sql-server - 从存储过程返回错误消息

标签 sql-server stored-procedures sql-server-2012

问题应该很简单,但我不知道答案,也不知道为什么我的存储过程不起作用。

CREATE PROCEDURE spTest_Delete
@ID int
AS
    begin tran
        declare @err int
        declare @errMesage nvarchar(max)
        set @errMesage = ''
        set @err = 0

        delete from Test
        where ID = @ID

        set @err = @@ERROR
        set @errMesage = ERROR_MESSAGE()

        if @err = 0 
           commit tran
        else 
        begin
            RAISERROR(N'Could not delete !Error nr: %d. Message: %s', 1, 16, @err, @errMesage)
            rollback tran
        end

此过程运行正常,但在 delete 语句上存在 FK 约束的情况下,它会遇到错误(这很好),我想捕获该错误。

Msg 547, Level 16, State 0, Procedure spTest_Delete, Line 12
The DELETE statement conflicted with the REFERENCE constraint "FK_TEstFK_Test". The conflict occurred in database "Test", table "dbo.Test", column 'ID'. The statement has been terminated.

Could not delete!
Error nr: 547. Message: (null) Msg 50000, Level 1, State 16

即使 delete 语句抛出错误,我的消息变量始终为 null。

最佳答案

您可能想开始使用TRY..CATCH阻止您的程序

Implements error handling for Transact-SQL that is similar to the exception handling in the Microsoft Visual C# and Microsoft Visual C++ languages. A group of Transact-SQL statements can be enclosed in a TRY block. If an error occurs in the TRY block, control is passed to another group of statements that is enclosed in a CATCH block.

所以你的程序可以重写为:

CREATE PROCEDURE spTest_Delete @ID INT
AS
BEGIN
    SET NOCOUNT ON;
    BEGIN TRY
        BEGIN TRANSACTION
            DELETE
            FROM Test
            WHERE ID = @ID;
        COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0
            ROLLBACK TRANSACTION
        SELECT ERROR_NUMBER(), ERROR_MESSAGE();
    END CATCH
END

另外,请注意您正在作为单个删除语句运行。这意味着它不需要包含在事务中。 This问题解释了原因。

你的代码变成这样:

CREATE PROCEDURE spTest_Delete @ID INT
AS
BEGIN
    SET NOCOUNT ON;
    BEGIN TRY
        DELETE
        FROM Test
        WHERE ID = @ID;
    END TRY
    BEGIN CATCH
        SELECT ERROR_NUMBER(), ERROR_MESSAGE();
    END CATCH
END

现在为什么你的@errMessage总是NULL?因为 ERROR_MESSAGE() 仅在 CATCH BLOCK 中有效。写在 documentation :

Returns the message text of the error that caused the CATCH block of a TRY…CATCH construct to be run.

Using TRY..CATCH in Transact-SQL告诉我们:

Error information is retrieved by using these functions from anywhere in the scope of the CATCH block of a TRY…CATCH construct. The error functions will return NULL if called outside the scope of a CATCH block.

关于sql-server - 从存储过程返回错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33277548/

相关文章:

java - 使用带 REF_CURSOR 的存储过程的 Spring 存储库

sql-server - 如何在 SQL SERVER 中格式化日期时间

sql - 根据一列的值更新另一列的值

sql-server - 表 '...' 中的计算列 '...' 无法持久化,因为该列是不确定的?

sql - 移动数据库后存储过程卡住

sql-server-2005 - 存储过程中的 IF、RAISERROR 和 RETURN

ssis - 使用 PackageInfo.ExecutionValueParameterSet 类在 PowerShell 中设置 SSIS 2012 包的参数值

sql-server - 相当于 MySQL SOURCE 命令来加载 SQL 脚本吗?

sql-server - 元素隐式具有 'any' 类型,因为类型 'string' 的表达式不能用于索引类型 'Type'

sql-server - Reporting Services 配置管理器用户无权执行此操作