SQL Server try-catch内部异常消息难题

Jam*_*mes 7 t-sql sql-server exception-handling try-catch

下面的SQL语句是一些使用嵌套详细信息抛出异常的SQL的一个很好的示例.似乎在语句的catch部分我只能得到外部异常细节Could not create constraint. See previous errors(不是很有用!).我想得到的是内部异常消息:

在表'TABLE2'上引入FOREIGN KEY约束'FK_TWO'可能会导致循环或多个级联路径.指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束(您可以通过运行不带try-catch的代码来获取此消息).

在Catch块中,如何在T-SQL中实现?

BEGIN TRY
      BEGIN TRAN;

        CREATE TABLE TABLE1 (USER_ID INTEGER NOT NULL PRIMARY KEY, USER_NAME
            CHAR(50) NOT NULL);

        CREATE TABLE TABLE2 (AUTHOR_ID INTEGER NOT NULL PRIMARY KEY, AUTHOR_NAME
            CHAR(50) NOT NULL, LASTMODIFIEDBY INTEGER NOT NULL, ADDEDBY INTEGER NOT
            NULL);

        ALTER TABLE TABLE2 ADD CONSTRAINT FK_ONE FOREIGN KEY (LASTMODIFIEDBY)
            REFERENCES TABLE1 (USER_ID) ON DELETE CASCADE ON UPDATE CASCADE;

        ALTER TABLE TABLE2 ADD CONSTRAINT FK_TWO FOREIGN KEY (ADDEDBY)
            REFERENCES TABLE1(USER_ID) ON DELETE NO ACTION ON UPDATE CASCADE;   

        COMMIT TRAN;
END TRY
BEGIN CATCH

      DECLARE @ERROR_MSG NVARCHAR(MAX), @SEVERITY INT, @STATE INT
      SELECT @SEVERITY = ERROR_SEVERITY(), @STATE = ERROR_STATE()
            , @ERROR_MSG = ERROR_MESSAGE() + ' err src line: ' + CAST( ERROR_LINE() AS NVARCHAR(20)) + ' ' + ISNULL(ERROR_PROCEDURE(), ''); 

      ROLLBACK;
      -- RE-THROW EXCEPTION FOR DIAGNOSTIC VISIBILITY
      RAISERROR (@ERROR_MSG ,@SEVERITY, @STATE); 
END CATCH;
Run Code Online (Sandbox Code Playgroud)

[编辑]

因此,经过多次搜索后似乎没有解决这个问题的办法.希望他们能在未来的版本中解决这个问题.

Rem*_*anu 9

你无法重新抛出原始错误.您必须抛出一个错误号超过50000 的错误,其中包含捕获的错误消息.有关示例,请参阅异常处理和嵌套事务:

begin catch
    declare @error int, @message varchar(4000), @xstate int;
    select @error = ERROR_NUMBER()
        , @message = ERROR_MESSAGE();
raiserror ('Caught exception: %d: %s', 16, 1, @error, @message) ;
return;
end catch   
Run Code Online (Sandbox Code Playgroud)

我链接的文章有一个更全面的例子,还包括强制XACT_STATE()检查和混合带事务语义的try/catch块.

使用下一个版本("Denali"),这个问题得到解决,因为你有能力发出throw;没有任何参数,这将引发原始异常,就像在其他try/catch语言中一样.请参阅TRY CATCH THROW:错误处理T-SQL中的更改

更新

噢,我有点读对角线的帖子.如果引发更多异常,则只能捕获一个异常.德纳利也是如此.但大多数情况下,引发的异常是严重性0(意味着它们确实是打印,而不是例外),并且仍然将它作为信息性消息(SqlConnection.InfoMessage事件)传递给客户端.


Jam*_*mes 1

现在这个问题还没有解决办法。据此,下一版本的 SQL Server 的解决方案将是使用新的 throw 关键字,这将重新引发这两个错误。