Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

ADO и MS SQL - посоветуйте хорошую ссылку [MSSQL]


Страницы:   1 2 3 4 5

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.

Буду благодарен за любую информацию.
С уважением.


Медвежонок Пятачок   (2008-09-08 23:56:00) [81]

запрос был в дизайнтайме и после смены текста commandtext тип параметра сбрасывался в инпут


Медвежонок Пятачок   (2008-09-08 23:52:00) [82]

ой нет. все работает


Медвежонок Пятачок   (2008-09-08 23:50:00) [83]

я уже раза четыре проверил.


sniknik   (2008-09-08 23:48:00) [84]

> set устанавливает значение, select не устанавливает
не может быть... это разные формы одного и того же.
счас проверю.


sniknik   (2008-09-08 23:47:00) [85]

> О чем речь, о получение идентити?
да
> Тогда просто insert + select в одной команде.
это вариант от "пятачка", а изначально попытка вернуть через параметр. оба варианта работают. если бы не 17я строка...


Медвежонок Пятачок   (2008-09-08 23:44:00) [86]

у меня аналогично.
set устанавливает значение, select не устанавливает

insert into test_table(name) values('test')
set :id = @@identity


sniknik   (2008-09-08 23:42:00) [87]

> Однако все равно не работает.
в коде нет указания типа параметра, а говоришь что он pdOutput.
как знал, что врешь.


kaif   (2008-09-08 23:35:00) [88]

В принципе мне нравится решение Медвежонок Пятачок ©   (08.09.08 22:18) [5], если перевести в TAdoDataSet. Мне не очень нравится запрашивать @@IDENTITY по честному. Но это похоже на мое решение с хранимой процедурой. Неприятно то, что для того чтобы сделать инсерт я в программе вынужден делать Open. Как-то неаккуратненько.
К тому же я не люблю не разобравшись в причине брать альтернативное решение. А вдруг мне еще где-нибудь понадобится вернуть параметр?
Что я буду делать?

Вот я сделал такой запрос для исследования:

 with ADOCommand1 do
 begin
   CommandText := 'SELECT :ID = @@Error';
   Execute;
   ShowMessage(IntToStr(Parameters.ParamByName('ID').Value));
 end;


Все отлично. Выходной параметр установлен, значение равно 0.
Значит дело в том, что у меня пакет.
Вот такой текст уже не сработал:

 with ADOCommand1 do
 begin
   CommandText := 'INSERT INTO GOODS(GOOD_NAME) VALUES (:NAME)'#13+
                  'SELECT :ID = @@Error';
   Parameters.ParamByName('NAME').Value := AName;
   Execute;
   ShowMessage(IntToStr(Parameters.ParamByName('ID').Value));
 end;


Причем запись вставилась, а вот второй запрос, похоже, то ли не отработал вообще, то ли не сумел донести выходной параметр до места назначения.

А вот так сработало:

 with ADOCommand1 do
 begin
   CommandText :=
                  ' BEGIN TRAN'#13+
                  'INSERT INTO GOODS(GOOD_NAME) VALUES (:NAME)'#13+
                  'SELECT :ID = @@IDENTITY'#13+
                  ' COMMIT TRAN';
   Parameters.ParamByName('NAME').Value := AName;
   Execute;
   ShowMessage(IntToStr(Parameters.ParamByName('ID').Value));
 end;


Буду благодарен за комментарии к этому месту. Что произошло?
И подскажите, пожалуйста, как написать так, чтобы транзакция не повисла в случае, например нарушения уникального ключа при вставке.


kaif   (2008-09-08 23:17:00) [89]

stas ©   (08.09.08 22:56) [10]
странно, поставь дирекшин InputOutput

Давно стоит.
Если у всех это работает, буду биться с настройками, транзакциями и т.п.

я проверил, не стоит ли режим IMPLICIT_TRANSACTIONS на сервере.

select case when (@@options & 2) = 2 then 'IMPLICIT' else 'NOT IMPLICIT' end

Вроде бы не стоит.
Даже не знаю, с чем это все может быть связано.


stas   (2008-09-08 22:56:00) [90]

странно, поставь дирекшин InputOutput


kaif   (2008-09-08 22:52:00) [91]

2 sniknik ©   (08.09.08 22:06) [3]
Ух ты, спасибо, я вообще не разглядел ADOCommand на палитре...

Однако все равно не работает.

 with ADOCommand1 do
 begin
   CommandText := 'INSERT INTO GOODS(GOOD_NAME) VALUES (:NAME)'#13+
                           'SET :ID = @@IDENTITY';
   Parameters.ParamByName('NAME').Value := AName;
   Execute;
   ShowMessage(IntToStr(Parameters.ParamByName('ID').Value));
 end;


Ошибка та же. Значение выходного параметра все равно имеет значение Null (в смысле variant).

Пробовал оба синтаксиса, и SELECT и SET. Разницы никакой.


Медвежонок Пятачок   (2008-09-08 22:37:00) [92]

можно и в одном. еще лучше пересесть на 2005 и заюзать output для инсерта


Anatoly Podgoretsky   (2008-09-08 22:34:00) [93]

> sniknik  (08.09.2008 22:27:06)  [6]

О чем речь, о получение идентити?
Тогда просто insert + select в одной команде.


sniknik   (2008-09-08 22:27:00) [94]

Медвежонок Пятачок ©   (08.09.08 22:18) [5]
нет смысла разделять команды. опасно. а если возвращать значение через рекордсет, то тогда и инсерт тоже в TAdoDataSet  перенести.


Медвежонок Пятачок   (2008-09-08 22:18:00) [95]

TAdoCommand + 'insert into TABLENAME values(.........)'
+
TAdoDataSet + select IDENT_CURRENT('TABLENAME')


Медвежонок Пятачок   (2008-09-08 22:08:00) [96]

у меня в ADOQuery.ExecSQL не сработала.

ADODataSet и ADOCommand. Все остальное не использовать.


sniknik   (2008-09-08 22:06:00) [97]

> ADOQuery
кстати заменил бы ты его на ADOCommand


sniknik   (2008-09-08 22:04:00) [98]

> после ExecSQL у меня в выходном параметре присутствует NULL.
либо врешь либо ошибка в 17й строке.

stas ©   (08.09.08 21:08) [1]
> SET :ID = @@IDENTITY
SELECT :ID = @@IDENTITY то же самое по сути, только стиль новее.


stas   (2008-09-08 21:08:00) [99]

INSERT INTO GOODS(GOODS_NAME) VALUES(:NAME)
SET:ID = @@IDENTITY

ADOQuery.ExecSQL


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо