Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server存储过程返回代码异常_Sql Server_Tsql_Stored Procedures_Error Handling - Fatal编程技术网

Sql server SQL Server存储过程返回代码异常

Sql server SQL Server存储过程返回代码异常,sql-server,tsql,stored-procedures,error-handling,Sql Server,Tsql,Stored Procedures,Error Handling,调用此代码的客户端受到限制,只能处理存储过程中的返回代码。因此,我们修改了我们通常的合同,在出现错误时返回-1,如果没有错误,则默认为返回0 如果代码命中内部catch块,则返回代码默认值为-4,而不是0 有人知道这是从哪里来的吗?参考 干杯 gbn 如果对象_ID('dbo.foo')不是NULL,则删除表dbo.foo 去 创建表dbo.foo( KeyCol char(12)不为空, ValueCol xml不为空, 注释varchar(1000)NULL, 约束PK_foo主键群集(Ke

调用此代码的客户端受到限制,只能处理存储过程中的返回代码。因此,我们修改了我们通常的合同,在出现错误时返回-1,如果没有错误,则默认为返回0

如果代码命中内部catch块,则返回代码默认值为-4,而不是0

有人知道这是从哪里来的吗?参考

干杯 gbn

如果对象_ID('dbo.foo')不是NULL,则删除表dbo.foo
去
创建表dbo.foo(
KeyCol char(12)不为空,
ValueCol xml不为空,
注释varchar(1000)NULL,
约束PK_foo主键群集(KeyCol)
)
去
如果OBJECT_ID('dbo.bar')不是NULL,则删除过程dbo.bar
去
创建过程dbo.bar
@关键字符(12),
@值xml,
@评论varchar(1000)
作为
不计较
声明@StartTranCount tinyint;
开始尝试
选择@StartTranCount=@@TRANCOUNT;
如果@StartTranCount=0,则开始传输;
开始尝试
--选择@StartTranCount='fish'——生成一个错误并转到外部捕获
插入dbo.foo(KeyCol、ValueCol、Comment)值(@Key、@Value、@Comment);
结束尝试
开始捕捉
如果错误_NUMBER()=2627--主键冲突
更新
dbo.foo
设置
ValueCol=@Value,Comment=@Comment
哪里
KeyCol=@Key;
其他的
RAISERROR('Tits up',16,1);
端接
如果@StartTranCount=0提交传输;
结束尝试
开始捕捉
如果@StartTranCount=0且XACT_STATE()0回滚传输;
返回-1
端接
--如果没有这个,如果我们点击上面的更新捕获块,我们将发送-4
--返回0
去
--请分别运行这些****
--运行时返回0,鱼线被注释掉
声明@rtn int
EXEC@rtn=dbo.bar“abcdefghijkl”,“testing”
选择@rtn;从dbo.foo中选择*
去
声明@rtn int
EXEC@rtn=dbo.bar“abcdefghijkl”,“testing2”
--更新正常,但我们得到@rtn=-4
选择@rtn;从dbo.foo中选择*
去
--取消注释鱼线
声明@rtn int
EXEC@rtn=dbo.bar“abcdefghijkl”,“testing”
--按预期命中外部捕捉,@rtn=-1
选择@rtn;从dbo.foo中选择*

在处理该过程时,如果我在foo.KeyCol中插入null并删除内部catch中的RAISERROR,我可以得到一个返回值-6。这是SQL Server正在做的事情,这里有文档记录:。

为什么要将“fish”分配给tinyint?以强制异常来测试外部CATCH块。查看最后一位执行官…抱歉,在我看到您的回复之前,已经删除了我的评论。(无论如何,我的评论是假的:)Ken Henderson的guru指南列表,但显然不再正确,因为-4将是一个权限错误。@gbn,这是在这个问题中给出的,您也回答了:返回值是10减去错误的严重程度,但我看不到链接文章中提到的。
IF OBJECT_ID('dbo.foo') IS NOT NULL DROP TABLE dbo.foo
GO
CREATE TABLE dbo.foo (
    KeyCol  char(12) NOT NULL,
    ValueCol xml NOT NULL,
    Comment varchar(1000) NULL,
    CONSTRAINT PK_foo PRIMARY KEY CLUSTERED (KeyCol)
)
GO

IF OBJECT_ID('dbo.bar') IS NOT NULL DROP PROCEDURE dbo.bar
GO
CREATE PROCEDURE dbo.bar
    @Key char(12),
    @Value xml,
    @Comment varchar(1000)
AS
SET NOCOUNT ON
DECLARE @StartTranCount tinyint;
BEGIN TRY
    SELECT @StartTranCount = @@TRANCOUNT;

    IF @StartTranCount = 0 BEGIN TRAN;

    BEGIN TRY
        --SELECT @StartTranCount = 'fish' --generates an error and goes to outer CATCH
        INSERT dbo.foo (KeyCol, ValueCol, Comment) VALUES (@Key, @Value, @Comment);
    END TRY
    BEGIN CATCH
        IF ERROR_NUMBER() = 2627    --PK violation
            UPDATE
                dbo.foo
            SET
                ValueCol = @Value, Comment = @Comment
            WHERE
                KeyCol = @Key;
        ELSE
            RAISERROR ('Tits up', 16, 1);
    END CATCH

    IF @StartTranCount = 0 COMMIT TRAN;
END TRY
BEGIN CATCH
    IF @StartTranCount = 0 AND XACT_STATE() <> 0 ROLLBACK TRAN;
    RETURN -1
END CATCH
--Without this, we'll send -4 if we hit the UPDATE CATCH block above
--RETURN 0
GO

--please run these **separately**

--Run with RETURN 0 and fish line commented out
DECLARE @rtn int
EXEC @rtn = dbo.bar 'abcdefghijkl', '<foobar />', 'testing'
SELECT @rtn; SELECT * FROM dbo.foo
GO

DECLARE @rtn int
EXEC @rtn = dbo.bar 'abcdefghijkl', '<foobar2 />', 'testing2'
--updated OK but we get @rtn = -4
SELECT @rtn; SELECT * FROM dbo.foo
GO

--uncomment fish line
DECLARE @rtn int
EXEC @rtn = dbo.bar 'abcdefghijkl', '<foobar />', 'testing'
--Hit outer CATCH, @rtn = -1 as expected
SELECT @rtn; SELECT * FROM dbo.foo