Конференция "Базы" » Обработка исключений ADO + MSSQL [D6, MSSQL]
 
  • kaif © (10.09.08 09:42) [0]
    У меня в триггере поднимается исключение:

    CREATE TRIGGER TRI_RESTS_UPDATE
    ON RESTS FOR UPDATE
    AS
     declare @Good_name varchar(255)
     select @Good_name = g.good_name
      from inserted i, goods g
      where i.good_id = g.id and
      i.quantity < 0
     if (@Good_name is not null)
     begin
       RAISERROR ('недостаточно товара на складе: %s', 16, 1, @Good_name)
       ROLLBACK TRANSACTION
     end
    GO



    Однако это исключение до моего дельфийского приложения не добирается. А при выполнении тех же действий, что делает мое приложение, в Studio Express сообщение об ошибке нормально отображается.

    Как заставить дельфийское приложение, работающее через ADO увидеть эту исключительную ситуацию?

    Если вызвать не в триггере, а явно, то Delphi поднимает исключение и все нормально, вплоть до текста совпадает с моим сообщением. Скажем, через ADOCommand:

           CommandText :=
             'declare @Good_name varchar(255)'#13+
             'set @Good_name = ''вася'''#13+
             'RAISERROR (''недостаточно товара на складе: %s'', 16, 1, @Good_name)';
           Execute;



    В чем засада получить то же самое из-под триггера?
  • Ega23 © (10.09.08 10:15) [1]

    > В чем засада получить то же самое из-под триггера?


    А тебе на проверку вводимого значения непременно триггер нужен?
  • Василий Жогарев © (10.09.08 10:22) [2]
    EOleException, хотя возможно ошибаюсь.
  • Anatoly Podgoretsky © (10.09.08 10:29) [3]
    RAISERROR в триггере для прерывания триггера и отката транзакции, а не для клиента.
    По крайней мере надо скатываться на более низкий уровень на АДО. В компонентах свойство TADOConnection.Errors и возможно к RecordSet
  • Anatoly Podgoretsky © (10.09.08 10:30) [4]

    > EOleException, хотя возможно ошибаюсь.

    У него не возникает исключение!
  • kaif © (10.09.08 10:43) [5]
    Ega23 ©   (10.09.08 10:15) [1]
    А тебе на проверку вводимого значения непременно триггер нужен?


    Нет, у меня просто система поддержки остатков на триггерах.
  • stas © (10.09.08 13:05) [6]
    У меня вот такое работает и выдается в программе.
    RAISERROR(@T,16, 1, 1, 1)
    где @T - nvarchar(50)
  • kaif © (10.09.08 13:25) [7]
    2 stas ©   (10.09.08 13:05) [6]

    в триггере работает?
  • stas © (10.09.08 13:37) [8]
    да
  • stas © (10.09.08 13:57) [9]
    Может у тебя условие не выполняется  if (@Good_name is not null) ?
    И триггер неправильно построен, если у тебя в таблице инсертед будет не одна запись?
  • kaif © (10.09.08 20:32) [10]
    2 stas ©   (10.09.08 13:57) [9]
    Нет, у меня все правильно.
    Предствавь, ты вставляешь расходную накладную. Есть триггер на позиции этой накладной, который апдейтит таблицу остатков. На таблице остатков еще триггер, он смотрит, чтобы остаток не стал отрицательным. Если такое произошло, он откатывает транзакцию и выдает исключение.

    Так вот в дельфийской программе после вставки такой накладной и переоткрытия ее позиций оказывается, что она не проапдейтилась, то есть транзакция была реально отменена в триггере. Но исключение до программы не добирается. А если я то же действие (вставка накладной, приводящей к отрицательному остатку) делаю из среды Microsoft SQL Nanagement Studio Express, в окне запроса выдается сообщение об ошибке, причем с моим текстом. Красным цветом. То есть Studio видит эту ситуацию, а ADO - не видит. Или же видит, но молчит. :)
  • stas © (10.09.08 20:45) [11]
    У тебя Delphi 6, может из-за этого все проблемы?
    у меня D7 и работают собщения из тригеров (только что проверил все настройки по умолчанию), и OUT параметры тоже.
    При этом использовал OLEDB подключение и Native client.
    MSSQL у меня 2005, но это все работало и на 2000
  • kaif © (10.09.08 22:34) [12]
    2 stas.

    Спасибо за твою настойчивость.

    Я расскажу все, что я проделал, а уж какие из этого можно сделать выводы, я не знаю.

    Итак, у меня есть приложени, которое при попытке выставить некий флаг в заказе сталкивается с тем, что происходит исключение в базе, откат транзакции и флаг не выставляется. Это факт. Виден после переоткрытия запроса. Исключение в приложении не возникает.

    Я проверил по цепочке. Так как у меня срабатывает сначала первый триггер, затем 2-й, а затем уже 3-й и только в нем вызывается исключение, я подумал, что может быть здесь играет роль "вложенность триггеров". Я вставил простое исключение в 1-й триггер (в начало текста). Все заработало, затем - во второй, затем в третий. Исключение всякий раз добиралось до приложения.

    Тогда я вставил такое же простое исключение в мою проверку. И вдруг я его увидел. Я заменил конструкцию:

       RAISERROR ('недостаточно товара на складе: %s', 16, 1, @Good_name)

    на более примитивную:

       set @Good_name = 'недостаточно товара на складе: ' + @Good_name;
     
      RAISERROR (@Good_name, 16, 1)

    и все заработало.

    Тогда я вернул старую конструкцию и еще раз убедился в том, что команда

    update orders set is_fact = 1 where id = 1102

    в Studio Express показывает текст ошибки, содержащий мое сообщение:

    Сообщение 50000, уровень 16, состояние 1, процедура TRI_RESTS_UPDATE, строка 19
    недостаточно товара на складе: Товар 1
    Сообщение 3609, уровень 16, состояние 1, процедура TRI_NAKL_ITEMS_UPDATE, строка 33
    The transaction ended in the trigger. The batch has been aborted


    Теперь я вызвал опять эту ситуацию в приложении.
    И теперь в приложении тоже исключение стало видно.

    Я ничего не понимаю...

    Я заново создал всю базу заново согласно тому же старому сценарию. Все продолжает работать.

    Чудо какое-то.
 
Конференция "Базы" » Обработка исключений ADO + MSSQL [D6, MSSQL]
Есть новые Нет новых   [134435   +35][b:0][p:0.001]