2015-04-23 2 views
0

У нас есть старый продукт, который медленно двигался вперед с тех пор, как он был первоначально построен в SQL Server 2000, и проблема связана с тем, как SQL создает пузырьки ошибок из вызовов RaiseError.RaiseError, не отображающийся в Trigger in Calling Сохраненная процедура

Например у меня есть триггер на таблицу, которая вызывает ошибку, подобную этой:

ALTER TRIGGER [dbo].[Rotation_UTrig] 
ON [dbo].[Rotation] FOR UPDATE AS 
BEGIN 
    SET NOCOUNT ON 
. 
. 
. 
    /* * VALIDATION RULE FOR FIELD 'RotationYear' */ 
      RAISERROR ('Invalid value entered for RotationYear, must be >=0', 44444, 1) 
      goto fatalerror 
. 
. 
fatalerror: 
END 

Это имеет необходимый эффект в вызывающей процедуре, что если оператор имеет значение для @@Error:

update Rotation 
set OrderedQuantity = @OrderedQuantity, 
    DespatchedQuantity = @DespatchedQuantity 
where ID = @RotationNo 

if @@Error != 0 
begin 
    if @AlreadyInTrans = 0 begin rollback transaction end 
     raiserror ('Error on update of Rotation.', 16, 1) 
     goto fatalerror 
end 
. 
. 
. 
fatalerror: 

но ошибка видела вызывающее приложение родителя:

Error Severity levels greater than 18 can only be specified by members of the sysadmin role, using WITH LOG option

Это происходит потому, что уровень ошибки в триггере 44444, если добавить

With LOG 

в код триггера для Raiserror то это закрывает соединение (которое мы не хотим). Если я понизить уровень ошибки до 16 в триггере, то

if @@Error !=0 

линия не попал в @@Error устанавливается равным нулю.

Другой, чем при использовании

Try... Catch 

вокруг обновления заявления в родительском порядке, есть ли другой способ пузыриться значение @@Error в процедуру, которая делает обновление, так что процедура кода (обновление утверждение и следующее, если @@ Error! = 0) может оставаться неизменным? Если нет, то это огромное изменение для моего приложения, так как мне нужно будет изменить все места, где обновляются обновленные таблицы, а также все триггеры.

+2

Я знаю, что это устаревший код, но как только вы начинаете видеть инструкцию GOTO, пришло время свернуть рукава и вытащите свой код из темных веков и начните использовать TRY/Catch. Он был доступен в качестве более совершенной техники обработки ошибок уже более десяти лет. –

+1

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

+1

что делать, если вы вызываете еще одну ошибку после 'fatalerror:'? – ughai

ответ

0

Найденный! Проблема заключается в том, что когда запускается еще один триггер и без проблем, @@ Ошибка сбрасывается на 0.

Смежные вопросы