從最初構建於SQL Server 2000中的這些年中,我們有一箇舊產品已經慢慢向前推進,問題是SQL如何從RaiseError調用中喚醒錯誤。在調用存儲過程中沒有從觸發器中顯示RaiseError
比如我有對提出類似這樣的錯誤表中的觸發器:
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
值到它執行更新程序,使得程序的代碼(更新聲明和以下if @@ Error!= 0)可以保持不變嗎?如果不是,那麼這對我的應用程序是一個巨大的改變,因爲我需要更改所有受影響表格更新的位置以及所有觸發器。
我知道這是遺留代碼,但是一旦你開始看到GOTO語句,就該捲起袖子並將您的代碼從黑暗時代拉出來並開始使用TRY/Catch。十多年來,它已經成爲一種更好的錯誤處理技術。 –
你發佈的一小段代碼中的其他巨大的代碼味道是你始終有標量變量。這是一個很好的跡象表明你的觸發器假設只有一行操作。他們需要重寫爲基於集合的方法來處理多行。 –
如果在'fatalerror:'之後引發另一個錯誤,該怎麼辦? – ughai