Конференция "Базы" » Добавление ADO-параметров в ран-тайм [D7, MSSQL]
 
  • sniknik © (04.10.08 12:34) [20]
    > О как...
    а ты как думал? :)
    раз уж не пользуешься тем что дядя борланд написал, читай справку "оригинала".

    > Если кто-нибудь приведет конкретное решение с Unique Table с примером работающего кода
    я тут проверил... даже Unique Table не нужно (вернее нужно но не для этого), заявленная проблема "вставки куда не просят" -
    > он пытается все эти запросы сам как-то сгенерировать, в результате он, естественно, пытается вставлять данные не только в таблицу накладных,
    > но и наименования товаров в справочник товаров
    вовсе и не проблема (вернее ADO/обертка к ней не причастны)... т.к. вставки не происходит если не редактировать значения второй связанной таблицы
    т.е. пробовал запрос (отдаваемые на редактирование в грид поля выделены)
    SELECT m.ID,m.mInt,m.mName,d.ID,d.mID,d.dInt,d.dName FROM Main m LEFT JOIN Detail d ON m.ID=d.mID


    так вот если ввести значения всем полям, действительно идет вставка в обе таблицы (что естественно, раз ввели, или эти данные потеряются),
    если же вводить только в поля первой таблицы т.е. - m.mInt,m.mName, вставки во вторую нет, даже без Unique Table.
    т.е. получается что ты там где то задаешь значения второй таблице ("просишь о вставке данных"), а после удивляешься попытке сохранить эти данные...
    > хотя они там уже присутствуют и защищены у меня уникальным ключом.
    а вот тут уже нужна Unique Table, т.к. эти уже присутствующие данные необходимо отображать (?), типа ввели код товара в накладную и по нему "подтянулось" его значение из справочника, вот для такой "подтяжки" есть Resync Command, а она работает в паре с Unique Table (вот и ее необходимость, и потом без нее удаление будет происходить тоже обоих связанных записей).
    но вообще это все есть в статьях на королевстве (блин вот почему их не было когда я это изучал?), ссылки куда тебе вроде давали (да и так найти не проблема).
  • sniknik © (04.10.08 12:35) [21]
    > Parameters[0], Parameters[1], можно присвоить имена параметрам.
    после того как создашь пожалуйста, а пока их нет... ошибка будет (вне списка).
  • kaif © (04.10.08 13:45) [22]
    2 sniknik ©   (04.10.08 12:34) [20]

    То, что при update полей одной таблицы update вставки во вторую не происходит, это я и тогда обнаружил. Странно было бы, если бы это было не так. Собственно, а что вставлять?

    Проблема совершенно в другом.

    При вставке новой строки в набор,  а именно: строки, содержащей суррогатный id товара, наименование товара (исключительно лишь для того чтобы отобразить его в сетке) и его количество, то вставка произойдет в обе таблицы.

    Мне неохота возвращаться к тем исследованиям. Вот куски кода, которые я закомментировал, пытался чего-то добиться. Результат был нулевым:

    //  qryDetail.Properties['Unique Table'].Value := 'ORDER_ITEMS';
    //  qryDetail.Properties['Update Criteria'].Value := adCriteriaUpdCols;
    //  adCriteriaKey, adCriteriaAllCols, adCriteriaUpdCols

    Сделаем проще. Вот примерно то, как я решаю подобную задачу в IBX (опустим лишнее, будем считать, что у нас всего одна накладная):

    IBDataSet1.SelectSQL.Text = 'select n.id, g.good_id, g.name, n.quantity from goods g, nakl n where n.good_id = g.id';
    IBDataSet1.ModifySQL.Text = 'update nakl set good_id = :good_id, quantity = :quantity where n.id = :old_id';
    IBDataSet1.DeleteSQL.Text = 'delete from nakl where id = :old_id';
    IBDataSet1.RefreshSQL.Text = 'select n.id, g.good_id, g.name, n.quantity from goods g, nakl n where n.good_id = g.id and n.id = :id';

    То есть у меня имеется 4 команды. И полная свобода сделать именно то, что мне нужно, без недоразумений и гаданий. Единственное, чего мне не дает IBX - мультитабличной вставки. Ну и слава богу. К чему мне этот страшный сон?

    И так вариантов поведения, которое разработчику может понадобиться  слишком много: и апдейты с использованием всех полей в WHERE, и апдейты с использованием только измененных, и апдейты с опорой на ключевые поля. И апдейты не всех измененных юзером в сетке полей, а лишь полей, указанных в SET ... = ..., не трогая иные поля. Да мало ли что захочет разработчик? Например в ModifySQL я вообще часто вписываю вызов хранимой процедуры.
    Вот дали разработчику 4 команды и известно, что это именно те команды и только те команды, что отправятся на сервер. И ничего такого за кулисами, что бы за него додумывали.

    И не только IBX Так устроены.

    Впрочем, если Вам нравится то, как "ADO думает за нас", то, как говорится, на вкус и цвет... Тогда спор просто бессмысленен.
  • sniknik © (04.10.08 14:45) [23]
    > исключительно лишь для того чтобы отобразить его в сетке
    а ADO про это знает? что ты вставил в привязанную таблицу значения исключительно "на посмотреть".
    про то и говорил ([20]), не надо туда писать, надо прописать код товара только основной таблице, и при записи сработает (если прописаны Resync Command, Unique Table) "подтяжка" значений ("суррогатный id товара, наименование товара") из дополнительной, для этой записи.
    и все, только чуть чуть другая логика.  

    > Впрочем, если Вам нравится то, как "ADO думает за нас", то, как говорится, на вкус и цвет...
    какая разница нравится или нет? оно так есть, и все. хочешь пользоваться - изучай "механизм", как он работает. и следуй его логике. или пиши свою, но на основании этой уже существующей.
    нравится логика с 4 отдельными запросами, что мешает добавить в ADO 4-ре ADOCommand и прописать в них такие же?
    хочешь "все одном"? - сделай это компонентом.

    > Тогда спор просто бессмысленен.
    а кто спорит то?
  • kaif © (04.10.08 21:01) [24]
    sniknik ©   (04.10.08 14:45) [23]
    нравится логика с 4 отдельными запросами, что мешает добавить в ADO 4-ре ADOCommand и прописать в них такие же?


    А вообще это неплохая идея. Может и стоит реализовать как-нибудь свой TKaifADODataSet, прямого наследника TDataSet с 4-мя командами и парсером параметров, который не вызывается вторично, если коллекция параметров была создана дизайн-тайм.

    И больше не иметь никаких проблем.

    Дело все же я думаю не в иной логике. Я готов привыкнуть к иной логике. Например, логика работы самого MSSQL (например, триггеров и взаимодействия с ними внешних каскадных ключей) сильно отличается от логики IB Или ORACLE.
    Но я заценил MSSQL, поработав с ним.
    Это действительно весьма хороший и производительный сервер, и с ним приятно работать. И он мне быстро понравился, несмотря на иную логику почти во всем.
    А вот реализация работы с ним через ADO-компоненнты в Delphi  нравилась мне все меньше и меньше, пока не разонравилась вовсе.

    С уважением.
  • sniknik © (04.10.08 21:38) [25]
    > Может и стоит реализовать как-нибудь свой TKaifADODataSet
    наверняка уже такой есть, фанатов Fib-ов/пересаживающихся с IB, хватает, неужели мне первому это в голову пришло? вряд ли.

    > А вот реализация работы с ним через ADO-компоненнты в Delphi
    думаешь вот эта вот запись "не туда" реализована на уровне дельфевской обертки? ;) ... нет, это чисто ADO-шная вещь, сделай все на обьектах ADO, помучится тоже самое.
  • MsGuns © (04.10.08 22:15) [26]
    >kaif ©   (04.10.08 21:01) [24]
    >А вообще это неплохая идея.

    Это правильная идея - явно писать запросы на изменения в несколько таблиц, не полагаясь на "ителлект" оберток. А если уж полагаешься, то подстраивайся под них, а не пытайся бороться с ними. И не возмущайся на их "кривость", если они ведут себя "не так".

    >И больше не иметь никаких проблем.

    ИМХО, у тебя проблемы только потому, что ты сам их настойчиво выискиваешь

    >Например, логика работы самого MSSQL (например, триггеров и >взаимодействия с ними внешних каскадных ключей) сильно отличается от >логики IB Или ORACLE.

    В чем "сильность" ?

    >Но я заценил MSSQL, поработав с ним.

    Не ты один. Однако он весьма сложен в администрировании. В частности весьма трудно управлять логом (и вообще он, ИМХО, сделан совершенно идиотически, в связи с чем больше напоминает мусорную свалку, чем "журнал". Особенно когда надо в нем что-то найти).
    Также неудобно реализованы копирования и восстановления. Нет возможности хранения скриптов и расширенных комментариев как в ИБ. Еще одна дурость - невозможность селекта из хранимок, а таже существенные ограничения при написания функций.
    Еще мне не понравилось отсутствие такого удобного средства, как suspend, что приводит к тому, что сервер не начинает отсылку пока не выберет все. Иногда это приводит к излишней загрузке сети и ненужному ожиданию на клиенте.

    Единственное СУЩЕСТВЕННОЕ отличие мсскл от ИБ - это абсолютно иной механизм транзакций. Вот к этому, действительно, надо приспособиться и привыкнуть.

    >А вот реализация работы с ним через ADO-компоненнты в Delphi  нравилась мне все меньше и меньше, пока не разонравилась вовсе.

    Что же касается ADO - то я не знаю другого такого же по гибкости и "комфортности" набора компонент. Во всяком случае по сравнению с IBX.

    И последнее. Мне кажется, что многие из твоих проблем в связке ADO+MsSQL от "гридного" редактирования. Если ты сможешь заставить себя навсегда от него отказаться (имеется в виду не вообще от правки в сетках с т.зр.пользователя, а именно от редктирования самого датасета, "напрямую" связанного с таблицами БД), то проблем у тебя существенно поубавится.
  • kaif © (05.10.08 02:25) [27]
    MsGuns ©   (04.10.08 22:15) [26]
    >Например, логика работы самого MSSQL (например, триггеров и >взаимодействия с ними внешних каскадных ключей) сильно отличается от >логики IB Или ORACLE.

    В чем "сильность" ?


    В том, что триггеры срабатывают после проверок на ссылочную целостность. И в том, что они все BEFORE. Плюс они срабатывают не на каждую запись, а на всю команду в целом. Например, IB при множественной вставке insert into ... select ... from ... сработает столько раз, сколько вставляется строк. А триггер MSSQL - единожды. На самом деле для задач, орудующих большими массивами это удобно.
    Разумеется, отсутствие suspend меня сразу смутило. Но зато MSSQL позволяет очень лихо (и главное быстро, и это принятый прием) создавать временные таблицы внутри хранимых процедур и возвращать их набор.

    Недостаток suspend восполняет функция, возвращающая тип данных TABLE. По крайней мере в MSSQL 2005 (а возможно и в 2000) это работает отменно, я попробовал.

    Неприятным открытием для меня стало то, что если удаление строк делается в триггере, то каскадный внешний ключ просто не сработает. Здесь я вижу кривизну самой архитектуры - естественную плату за то, что триггер срабатывает единожды и срабатывает BEFORE.

    Мне кажется, что многие из твоих проблем в связке ADO+MsSQL от "гридного" редактирования

    Я не злоупотребляю гридным редактированием. Но считаю полный отказ от DATA AWARE компонентов другой крайностью. Нафиг тогда вообще это все было придумано? В IB у меня с этим проблем нет. Я же не вытягиваю таблицы на клиент в IBTable и не редактирую их там наивно в сетках.
    Мне просто кажется естественным, когда юзер может в сетке подправить количества в нескольких строках накладной, содержащей в среднем 20 строк, не прибегая каждый раз к вызову диалогового окна для этой цели. Если есть проблемы с медленной отправкой строк на сервер в процессе такого редактирования (если честно, в IB таких проблем обычно просто нет), то можно использовать CachedUpdate := True и дело с концом - в ApplyUpdates я полностью управляю отсылкой данных так, как пожелаю.

    Это ведь архитектура самого Delphi - работа с данными в Data Aware Controls. Я знаю людей, которые все запихивают в StringGrid только ради того чтобы не держать запрос открытым. Ну и зачем это? А если серверу все же нужно знать о необходимости блокировки? Я вижу, что в MSSQL Это весьма может быть актуальным.

    sniknik ©   (04.10.08 21:38) [25]
    > А вот реализация работы с ним через ADO-компоненнты в Delphi
    думаешь вот эта вот запись "не туда" реализована на уровне дельфевской обертки? ;) ... нет, это чисто ADO-шная вещь, сделай все на обьектах ADO, помучится тоже самое.


    Это я уже понял. Я сегодня внимательно рассмотрел модуль ADODB.PAS. :(
    Но мне все же видится, что встроить 4 команды, как ты предложил, вполне реально. Наверняка можно заставить ADO не делать запрос "живым".

    К сожалению в сети не так уж много литературы по ADO Delphi. И написано везде одно и то же. Ты говоришь о ссылках на статьи на Королевстве. Я тогда посмотрел все, что мне давали. Unique Table я так и не смог задействовать. Может быть времени не хватило. Но времени у меня и не было совершенно. И меня очень разражали проблемы на каждом шагу. Впрочем, это мои проблемы.

    В пользу ADO (я работал через него с dBase и Access) могу сказать, что мне нравится его скорость Fetch-а, "гладкость" работы, экономность (как мне показалось) в отношении ресурсов и довольно развитая поддержка SQL в локальных вариантах (выборки из dBase). Например если бы не ADO, я бы вообще не знал как мне (иначе, чем разбирая dBase файл руками) считать двоичные данные из строковых полей (был такой раньше способ оптимального запихивания чисел в DBF). ADO позволил мне тогда получить эти данные в SELECT-е как cast(... as VarBinary()) или что-то в этом духе, может неверно помню, но работал такой typecast отлично. Никакие иные средства не позволяли (BDE, например) получить в строках символы после символа 0, так как они понимали 0 как конец строки (как и принято в Windows). А запиханные двоично числа в строки могли, разумеется, содержать нулевые байты. Поэтому я и говорю, что к OLEDB как таковому у меня особых нареканий нет.

    А что, MSSQL не имеет разве своей клиентской dll ? А с чем же тогда BDE драйвер работает? Или он напрямую через TCP/IP  с сервером общается?
  • sniknik © (05.10.08 14:26) [28]
    > А что, MSSQL не имеет разве своей клиентской dll
    имеет конечно, прямо в виндовс встроенную (MDAC), но не в том виде что у IB/Firebird, не отдельная распространяемая вместе с программой, а устанавливаемый в винду пакет COM обьектов.

    > А с чем же тогда BDE драйвер работает?
    х.з. может с dblib, может что то своё, но строго говоря он уже давно не работает ... поддержка с версии MSSQL 6,5 прекращена.
    только вариант с BDE + ODBC ещё "дышит", а  драйвера ODBC сейчас тоже входят в MDAC и не поймешь, кто там кого использует. вот для dbase/paradox очевидно, их драйвера ODBC используют jet (т.е. OLEDB провайдер.).
  • kaif © (06.10.08 01:36) [29]
    2 sniknik ©   (05.10.08 14:26) [28]
    Спасибо за ответ.
    Таким образом все "нативные" компоненты Delphi для MSSQL работают через COM-объекты MDAC, если я правильно понял.
    Я бы предпочел, если честно использовать "нативные" компоненты (компоненты "прямого доступа"), а не ADO.
    Какие конкретно (платные и бесплатные) существуют и какие из них кажутся Вам наиболее удачными?
  • Германн © (06.10.08 02:01) [30]
    <offtop>
    Вот после таких веток и думаешь, почему все, кому не лень,  "столь грязно" ругают Парадокс?
    </offtop>
    :)
  • sniknik © (06.10.08 08:48) [31]
    > и какие из них кажутся Вам наиболее удачными?
    ни одни.
    самые удачные, гибкие, и с максимумом возможностей (и потому самые сложные) это ADO.
    было время тестировал парочку "прямого доступа", и ничего особого, кроме ограниченного функционала того же ADO в них не нашёл. другое дело работать с ними было попроще, реализована всего одна схема работы. но изучать/использовать их не рекомендовал бы, зачем изучать сурогат, когда есть оригинал? и нафига потом переучиваться, когда понадобится возможность которая есть в ADO, но которая проигнорирована в этих "найтивных"?
  • MsGuns © (06.10.08 09:10) [32]
    >Я бы предпочел, если честно использовать "нативные" компоненты (компоненты "прямого >доступа"), а не ADO.

    Толкать грузовик вручную вместо того, чтобы просто запустить мотор и поехать ?
  • Vlad Oshin © (06.10.08 09:24) [33]

    > > Непонятно зачем ты вообще устраиваешь пляски с бубном
    > вокруг
    > > параметров - чем не устроила стандартная схема ?
    >
    >
    > Тем, что у меня вообще не оконное приложение. И в дизайн-
    > тайме я ничего выставить не могу.

    а добавить   Unit1 in 'Unit1.pas' {DataModule1: TDataModule};
    и накидать чего хочешь?
  • Ega23 © (06.10.08 12:04) [34]
    Да, с ? вместо :param проблема решилась.
    Всем спасибо, отдельно - sniknik ©
  • Вариант (06.10.08 12:09) [35]

    > kaif ©   (06.10.08 01:36) [29]


    > Какие конкретно (платные и бесплатные) существуют и какие
    > из них кажутся Вам наиболее удачными?


    MSDAC
  • ANB (06.10.08 12:32) [36]

    > kaif ©   (05.10.08 02:25) [27]

    Я как то уже поднимал вопрос в форуме о некой урезанности функционала ADO по сравнению с тем же QA.
    Получил ответ, что я не умею его готовить :)
    Несмотря на применение всех советов, которые мне тут надавали, решить мою задачу удалось только прямым вызовом DBLib. И действительно, в ADO.Net таких проблем нету.

    Короче, решений 3 :
    1. Пользвать ADO с учетом граблей
    2. Написать свои компоненты с использованием DBLib (я бы сказал - не простой способ)
    3. Способ который выбрал я - перейти на оракл, для него есть весьма толковые нативные компоненты.
  • Вариант (06.10.08 12:49) [37]

    >  Вариант   (06.10.08 12:09) [35]

    Дополню - http://devart.com/sdac/. есть и для других СУБД
 
Конференция "Базы" » Добавление ADO-параметров в ран-тайм [D7, MSSQL]
Есть новые Нет новых   [134473   +33][b:0][p:0.001]