无法使用 THROW SQL Server 2008 R2

25

SQL Server 2008 R2管理工具在下面的示例中无法识别我的throw关键字,它会显示 "incorrect syntax near Throw" 的错误提示。

我在这里尝试抛出一个错误,这样当有人尝试插入相同的值时,我可以在我的网站上处理它。

Begin Try
 insert into BusinessID (BusinessID) values (@ID)
 insert into BusinessID (BusinessID) values (@ID)

End Try

Begin Catch

Print 'PK already exist'
THROW
End Catch

1
THROW是SQL Server 2012中的新功能,因此在2008 R2中尚不可用..... - marc_s
此外,看起来您需要在 THROW 前的语句中加上分号以终止它,否则会出现语法错误! - joedotnot
2个回答

47

THROW语句是在SQL Server 2012中引入的。

http://msdn.microsoft.com/en-us/library/ee677615.aspx

你可以使用RAISERROR代替。

http://msdn.microsoft.com/en-us/library/483588bd-021b-4eae-b4ee-216268003e79(v=sql.105)

BEGIN CATCH
    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    SELECT 
        @ErrorMessage = ERROR_MESSAGE(),
        @ErrorSeverity = ERROR_SEVERITY(),
        @ErrorState = ERROR_STATE();

    RAISERROR (@ErrorMessage, -- Message text.
               @ErrorSeverity, -- Severity.
               @ErrorState -- State.
               );
END CATCH;

有一点不同。RAISERROR 不会停止执行,而 THROW 会停止。 - Mehmet AVŞAR
1
@MehmetAVŞAR 这并不完全正确。执行是否停止并不取决于RAISERROR或THROW,而是取决于严重性级别。使用RAISERROR,您可以自己设置严重性,并选择是否停止执行。使用THROW时,您不能设置严重性,缺省值为16,它确实会停止执行,但是当在CATCH块中使用时,它只会转发上一个已知异常,这可能是16也可能不是。 - Nenad Zivkovic
@NenadZivkovic 我刚刚再次尝试了一下,错误级别17不会停止执行。它只需要用户是sysadmin的成员才能引发高于18级别的错误。 CREATE PROCEDURE RaiseMeAnError AS PRINT '步骤1' RAISERROR('这里是低级别错误', 1, 1) PRINT '步骤2' RAISERROR('这里是低级别错误', 17, 1) PRINT '步骤3' - Mehmet AVŞAR
1
@MehmetAVŞAR PRINT 是一个在执行计划方面比较特殊的命令,SQL 在引发错误之前就已经运行了它,请尝试在演示代码中将其替换为 SELECT,您会发现第三个选择不会发生。 - Nenad Zivkovic
明白了 @NenadZivkovic,但仍然感到困惑。在这里,SQL Server 引擎团队的一位成员表示 raiserror 的这种行为是设计上的。链接 - Mehmet AVŞAR
显示剩余2条评论

4

在你的SQL块中使用 RAISERROR 代替 Throw。

Begin Try
 insert into BusinessID (BusinessID) values (@ID)
 insert into BusinessID (BusinessID) values (@ID)

End Try

Begin Catch

Print 'PK already exist'
  DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

SELECT 
    @ErrorMessage = ERROR_MESSAGE(),
    @ErrorSeverity = ERROR_SEVERITY(),
    @ErrorState = ERROR_STATE();

-- Use RAISERROR inside the CATCH block to return error
-- information about the original error that caused
-- execution to jump to the CATCH block.
RAISERROR (@ErrorMessage, -- Message text.
           @ErrorSeverity, -- Severity.
           @ErrorState -- State.
           );
End Catch

感谢您的建议,并对我的具体示例应用了您的建议 :) - user2405574
如果 ERROR_MESSAGE() LIKE '%[%]s%' 或者其他什么呢? - binki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接