![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ADO и MS SQL - посоветуйте хорошую ссылку [MSSQL]
kaif © (2008-09-08 21:03:00)Пишу приложение для базы MSSQL. Решил в приложении использовать ADO. Не могу найти хорошей статьи с примерами.
Например, у меня есть справочники.
Конструкция типа:
INSERT INTO GOODS(GOODS_NAME) VALUES(:NAME)
SELECT :ID = @@IDENTITY
у меня в ADOQuery.ExecSQL не сработала. То есть сработала, но несмотря на то, что я явно задал 2 параметра (NAME и ID), один как Dirction = pdInput, а другой - pdOutput, после ExecSQL у меня в выходном параметре присутствует NULL.
Я написал хранимую процедуру, возвращающую набор данных:
CREATE PROCEDURE SP_INSERT_GOOD(@NAME VARCHAR(60))
AS
BEGIN
INSERT INTO GOODS(GOOD_NAME) VALUES(@NAME)
SELECT :ID = @@IDENTITY
END
И, используя метод ADOQuery.Open, получил желаемое.
Однако мне это решение кажется каким-то кривым.
Хотелось бы увидеть что-нибудь традиционно принятое в этой связке Delphi6-ADO-MSSQL2000.
Буду благодарен за любую информацию.
С уважением.
sniknik (2008-09-09 15:58:00) [21]> Это баг ADO.
это НЕ баг ADO, это стандартное поведение, имхо, для многих компонент (ParamCheck в BDE по крайней мере видел, чего зря оно там чтоли? зачем переключатель если нечего переключать?)
sniknik (2008-09-09 15:54:00) [22]> Причем тут тип блокировки - речь идет о невозможности явного управления порциями изменений (репликами) -
> когда надо писать не по одной записи, а несколькими логически связанными.
ltBatchOptimistic?
kaif (2008-09-09 15:54:00) [23]Вместо таких фраз:
sniknik © (08.09.08 23:42) [13]
> Однако все равно не работает.
в коде нет указания типа параметра, а говоришь что он pdOutput.
как знал, что врешь.
нужно было сказать так:
Ашот, учти, что после рантайм присвоения свойству CommandText нового значения, несмотря на свойство ParamCheck=True, ADO (в случае с MSSQL как минимум) теряет Direction параметров (присвоенные до того) и их следует после такого присвоенияеще раз устанавливать ручками принудительно. Это баг ADO. Тебе не повезло, что ты сразу на него наткнулся, пытаясь сделать первое в своей жизни редактирование справочника сервера MSSQL при помощи компонентов ADO.
Это был бы правильный ответ. И я никто бы не мучился и не обижался.
Кстати, я тебе признателен за идею использовать TADOCommand.
sniknik (2008-09-09 15:52:00) [24]> Вот пусть мой оппонент мне внятно объяснит этот момент.
обьяснить как подозреваю ничего, никому нельзя... только если сам поймет.
для проверки, приведи запрос с транзакцией к виду "для тупых", в изначальном виде (без задания типа после), и проверь.
MsGuns (2008-09-09 15:52:00) [25]>Нормально оно себя ведёт, LockType надо правильно выставлять...
Причем тут тип блокировки - речь идет о невозможности явного управления порциями изменений (репликами) - когда надо писать не по одной записи, а несколькими логически связанными.
MsGuns (2008-09-09 15:49:00) [26]По поводу кода в [66]
Ты внимательно почитал разницу между @@identity vs Scope_identity ?
Ega23 (2008-09-09 15:49:00) [27]
> ADO в сеточной режиме ведет себя иногда весьма капризно
> (особенно в конкурентных соединениях)
Нормально оно себя ведёт, LockType надо правильно выставлять...
sniknik (2008-09-09 15:49:00) [28]> говоря, что я зря в дизайн-тайме что-то указывал?
было бы не зря, если бы ты там указывал все начиная с запроса. а раз уж ты переприсваиваеш запрос (переинициализируеш) то ... и не говори только, что в других компонентах это не так, в BDE например (не знаю BDE. ... ну почти.)
> Не якобы, а помогла.
> Почему - не знаю.
а ведь я объяснял... но видимо у тебя на меня игнор.
MsGuns (2008-09-09 15:47:00) [29][67]
+100
Я просто забыл отметить эту весьма существенную деталь
И еще вдовесок:
а) Тексты запросов лучше располагать в тексте константами. Если проект является очередным в серии приложений с одной и той же БД, стОит задуматься об унификации кода, вынеся все запросы в отдельный библиотечный модуль.
б) не следует "класть" много компонент - на форме (ДМ) должны быть только те, которые используется при дизайне решеток и не меняются в ран-тайме. Все "одноразовые" запросы на выборки-вставки-изменения-удаления строятся на динамически создаваемых и затем прибиваемых объектах
в) старайся максимально использовать возможности ADO, предоставляемые на клиенте (TCustomADODataSet) - это может существенно упростить логику и разгрузить сервер при поисках, сортировках, фильтрациях и т.д.
г) в особо критичных ситуациях "гридного" редактирования не ленись использовать TClientDataSet со всеми его вкусностями (в т.ч. "тонкой" технологией управления кэшированием-отсылкой изменений) - ADO в сеточной режиме ведет себя иногда весьма капризно (особенно в конкурентных соединениях)
kaif (2008-09-09 15:40:00) [30]sniknik © (09.09.08 15:25) [63]
> Хотя ты сейчас опять скажешь, что я вру.
а то. в чем то обязательно, вот например сейчас когда ты "все" знаеш объясни причем тут транзакция которая якобы помогла тебе вернуть параметр в [12].
Не якобы, а помогла.
Почему - не знаю.
И хочу как раз это обсудить.
Со вчерашнего дня, между прочим. Вместо этого вынужден доказывать тебе, что я не лжец. Надоело.
Ega23 © (09.09.08 15:32) [67]
2 kaif:
Ашот, я тебе порекомендую не писать клиента с подключенным в дизайн-тайм коннекшеном. Многое тогда станет понятным.
А я так и не делаю.
Я вообще не понимаю, о чем здесь спор идет.
app (2008-09-09 15:40:00) [31]Будете переругиваться - закрою тему.
kaif (2008-09-09 15:34:00) [32]
sniknik © (09.09.08 15:20) [60]
> без того чтобы об этом было предупреждение в документации у меня нет.
вот именно поэтому я думал, что ты не читал документации, раз не знаеш об этом "предупреждении".
Приведи текст из Help по ADO Delphi, где об этом сказано. Если ты не врун, конечно.
Ega23 (2008-09-09 15:32:00) [33]2 kaif:
Ашот, я тебе порекомендую не писать клиента с подключенным в дизайн-тайм коннекшеном. Многое тогда станет понятным.
kaif (2008-09-09 15:31:00) [34]MsGuns © (09.09.08 15:15) [58]
>kaif © (09.09.08 14:31) [44]
В глубоко научный спор не вмешиваюсь, а только спрошу - зачем, Ашот, ты упорно пытаешься закатить солнце вручную, т.е. пишешь код по созданию и инициализации параметров, ведь это требуется только в исключительных случаях и то, если ParamCheck := false, что, ИМХО, бывает нужным лишь в исключительных случаях ?
И еще вопрос - зачем эти спецсимволы в строке запроса ?
В том-то и проблема.
Вот взгляни на этот код.
Здесь я вообще ничего явно не задаю. Надеюсь на ParamCheck.
Получаю фигню.
procedure TSimpleReferenceForm.Button1Click(Sender: TObject);
begin
with TADOCommand.Create(nil) do
try
Connection := MainData.Connection;
ParamCheck:= TRue;
CommandText :=
'INSERT INTO GOODS(GOOD_NAME) VALUES (:NAME)'#13#10+
'SELECT :ID = SCOPE_IDENTITY()';
Parameters.ParamByName('NAME').Value := 'Дядя Вася 8';
Execute;
if Parameters.ParamByName('ID').Value = Null then
ShowMessage(Format('Значение выходного параметра Null]))
else
ShowMessage(Format('Значение выходного параметра ID = %s',
[IntToStr(Parameters.ParamByName('ID').Value)]));
finally
Free;
end;
end;
Если я обрамлю команды явными стартом и коммитом транзакции, выходной параметр получит нормальное значение.
Почему обрамление транзакцией заставляет ADO работать так, как видится мне, а без этого обрамления я оказываюсь НЕПРАВ, а мой оппонент прав, говоря, что я зря в дизайн-тайме что-то указывал?
Вот пусть мой оппонент мне внятно объяснит этот момент.
А не придирается все время к тому, что я весь текст приевл или не весь текст привел. А потом сам же, как только я указываю весь текст, выделяет в этом тексте одну строку (о которой можно и словми сказать) и говорит, что весь текст нафиг никому не нужен.
Мне надоел этот стиль беседы.
У меня много работы и нет желания здесь опять с кем-то собачиться только потому что у того с культурой проблемы.
За обвинения во вранье человек так и не извинился. Ну и я извиняться не собираюсь за свои обвинения в том, что он дурно воспитан.
MsGuns © (09.09.08 15:15) [58]
>kaif © (09.09.08 14:31) [44]
И еще, чисто из собственного опыта - старт транзакции и ее завершение на клиенте не рекомендуется вкладывать в текст запроса - лучше это делать, используя TADOConnection.BeginTrans/CommitTrans|RollbackTrans - во-первых "прозрачнее" с т.з. кода, во-вторых в МсСкл нет понятия "транзакция" как самостоятельная величина (как в ИБ) и все они интерпретируются сервером применительно к соединению в целом - поэтому чтобы не запутаться в "ручных" транзакциях (в смысле где внешняя, а где внутренняя), лучше разруливать их в контексте не запроса, а всего соединения в целом.
За эту рекомендацию я очень тебе благодарен. Всегда хорошо услышать что-то дельное. Особенно человеку без опыта.
Anatoly Podgoretsky (2008-09-09 15:30:00) [35]> sniknik (09.09.2008 14:42:45) [45]
Речь и полях и о параметрах. В данный момент я не могу сказать про что именно, я просто помню, что тип ранее был Integer (RW) а потом стал AutoInc (RO) как мне и надо.
TParameter.DataType = ftAutoInc
И это не ADO, а ADO.VCL, точнее DB.PAS
Использовать просто
WHERE ID =:id
Вот у :id тип ftAutoInc, ранее Integer
Пример в теме DataType, список типов в теме TFieldType type, он общий и для полей и для параметров.
Параметр должен быть того же типа, что и поле или совместимого.
Если же ftAutoInc меня не особо и волновал, то преобразование ftWideString в ftFixedChar поскольку это уже приводило к полной неработоспособности программы.
При это сначала они исправили только поля, а потом и параметры, но для этого им потребовалось более 4 лет.
sniknik (2008-09-09 15:27:00) [36]> хреновый стиль
ну, в дельфи в отличие от с "\n" нету ;(.
sniknik (2008-09-09 15:25:00) [37]> Хотя ты сейчас опять скажешь, что я вру.
а то. в чем то обязательно, вот например сейчас когда ты "все" знаеш объясни причем тут транзакция которая якобы помогла тебе вернуть параметр в [12].
MsGuns (2008-09-09 15:25:00) [38]>sniknik © (09.09.08 15:20) [60]
>в остальных случаях, когда этого не нужно, просто стиль.
хреновый стиль
sniknik (2008-09-09 15:22:00) [39]> я наверно знал, что делаю.
да? и просвети зачем ты это делаешь? создание параметров до запроса имею ввиду.
sniknik (2008-09-09 15:20:00) [40]> без того чтобы об этом было предупреждение в документации у меня нет.
вот именно поэтому я думал, что ты не читал документации, раз не знаеш об этом "предупреждении".
> И еще вопрос - зачем эти спецсимволы в строке запроса ?
нормально. если создавать например процедуру то после ее можно будет наблюдать в инспекторе в удобочитаемом виде.
в остальных случаях, когда этого не нужно, просто стиль.