2015-04-23 85 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.

相关问题