2015-04-23 61 views
0

從最初構建於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)可以保持不變嗎?如果不是,那麼這對我的應用程序是一個巨大的改變,因爲我需要更改所有受影響表格更新的位置以及所有觸發器。

+2

我知道這是遺留代碼,但是一旦你開始看到GOTO語句,就該捲起袖子並將您的代碼從黑暗時代拉出來並開始使用TRY/Catch。十多年來,它已經成爲一種更好的錯誤處理技術。 –

+1

你發佈的一小段代碼中的其他巨大的代碼味道是你始終有標量變量。這是一個很好的跡象表明你的觸發器假設只有一行操作。他們需要重寫爲基於集合的方法來處理多行。 –

+1

如果在'fatalerror:'之後引發另一個錯誤,該怎麼辦? – ughai

回答

0

找到了!問題是,當另一個觸發器出現並且沒有任何問題的時候,@@ Error被重置爲0.

相關問題