Конференция "Базы" » ADO и MS SQL - посоветуйте хорошую ссылку [MSSQL]
 
  • kaif © (08.09.08 21:03) [0]
    Пишу приложение для базы 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.

    Буду благодарен за любую информацию.
    С уважением.
  • stas © (08.09.08 21:08) [1]
    INSERT INTO GOODS(GOODS_NAME) VALUES(:NAME)
    SET :ID = @@IDENTITY


    ADOQuery.ExecSQL
  • sniknik © (08.09.08 22:04) [2]
    > после ExecSQL у меня в выходном параметре присутствует NULL.
    либо врешь либо ошибка в 17й строке.

    stas ©   (08.09.08 21:08) [1]
    > SET :ID = @@IDENTITY
    SELECT :ID = @@IDENTITY то же самое по сути, только стиль новее.
  • sniknik © (08.09.08 22:06) [3]
    > ADOQuery
    кстати заменил бы ты его на ADOCommand
  • Медвежонок Пятачок © (08.09.08 22:08) [4]
    у меня в ADOQuery.ExecSQL не сработала.

    ADODataSet и ADOCommand. Все остальное не использовать.
  • Медвежонок Пятачок © (08.09.08 22:18) [5]
    TAdoCommand + 'insert into TABLENAME values(.........)'
    +
    TAdoDataSet + select IDENT_CURRENT('TABLENAME')
  • sniknik © (08.09.08 22:27) [6]
    Медвежонок Пятачок ©   (08.09.08 22:18) [5]
    нет смысла разделять команды. опасно. а если возвращать значение через рекордсет, то тогда и инсерт тоже в TAdoDataSet  перенести.
  • Anatoly Podgoretsky © (08.09.08 22:34) [7]
    > sniknik  (08.09.2008 22:27:06)  [6]

    О чем речь, о получение идентити?
    Тогда просто insert + select в одной команде.
  • Медвежонок Пятачок © (08.09.08 22:37) [8]
    можно и в одном. еще лучше пересесть на 2005 и заюзать output для инсерта
  • kaif © (08.09.08 22:52) [9]
    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. Разницы никакой.
  • stas © (08.09.08 22:56) [10]
    странно, поставь дирекшин InputOutput
  • kaif © (08.09.08 23:17) [11]
    stas ©   (08.09.08 22:56) [10]
    странно, поставь дирекшин InputOutput

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

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

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

    Вроде бы не стоит.
    Даже не знаю, с чем это все может быть связано.
  • kaif © (08.09.08 23:35) [12]
    В принципе мне нравится решение Медвежонок Пятачок ©   (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;



    Буду благодарен за комментарии к этому месту. Что произошло?
    И подскажите, пожалуйста, как написать так, чтобы транзакция не повисла в случае, например нарушения уникального ключа при вставке.
  • sniknik © (08.09.08 23:42) [13]
    > Однако все равно не работает.
    в коде нет указания типа параметра, а говоришь что он pdOutput.
    как знал, что врешь.
  • Медвежонок Пятачок © (08.09.08 23:44) [14]
    у меня аналогично.
    set устанавливает значение, select не устанавливает

    insert into test_table(name) values('test')
    set :id = @@identity
  • sniknik © (08.09.08 23:47) [15]
    > О чем речь, о получение идентити?
    да
    > Тогда просто insert + select в одной команде.
    это вариант от "пятачка", а изначально попытка вернуть через параметр. оба варианта работают. если бы не 17я строка...
  • sniknik © (08.09.08 23:48) [16]
    > set устанавливает значение, select не устанавливает
    не может быть... это разные формы одного и того же.
    счас проверю.
  • Медвежонок Пятачок © (08.09.08 23:50) [17]
    я уже раза четыре проверил.
  • Медвежонок Пятачок © (08.09.08 23:52) [18]
    ой нет. все работает
  • Медвежонок Пятачок © (08.09.08 23:56) [19]
    запрос был в дизайнтайме и после смены текста commandtext тип параметра сбрасывался в инпут
 
Конференция "Базы" » ADO и MS SQL - посоветуйте хорошую ссылку [MSSQL]
Есть новые Нет новых   [134435   +36][b:0.001][p:0.002]