在Sybase ASE 15.0中处理从一个存储过程到另一个存储过程的错误

时间:2015-10-22 19:40:10

标签: stored-procedures error-handling sybase sybase-ase raiserror

我需要根据某些条件在Sybase ASE数据服务器上执行密码重置:

if validations_here
begin
    exec sp_password 'sso_passw', 'new_passw', @userid
end

sp_password可能会引发一些错误,例如 10316 - “提供的新密码与以前的密码相同”。虽然我找不到任何文档,但我认为它们不应该是致命错误,应该可以使用raiserror来模拟它们。

因为调用者以这种方式处理它会更容易,我想得到错误代码并将其作为结果集的一部分返回,所以我想到SELECTing @@ error。我的代码如下(我只转录了我认为与问题相关的那些部分):

create procedure sp_desbloc_blanqueo_usr    
    @userid sysname,        
    @sso_pass varchar(20),  
    @new_pass varchar(20)   
as
begin
    declare @ret_code int
    declare @ret_msg varchar(100)
    declare @myerror int

    select @ret_code = 0, @ret_msg = 'OK'

    exec sp_password @sso_pass, @new_pass, @userid
    set @myerror = @@error 
    if @myerror <> 0
    begin
        select @ret_code = @myerror, @ret_msg = 'Error occurred changing password' 
        -- It would be nice to have the actual error message as well
        goto fin
    end

    fin:
    select @ret_code as ret_code, @ret_msg as ret_msg
end

但是,每当我执行存储过程时,我得到0为ret_code而确定为ret_msg(即使sp_password的参数错误)。

如何从我的存储过程中“捕获”sp_password的错误代码?

1 个答案:

答案 0 :(得分:1)

许多“sp_”存储过程在出现错误时设置非零返回码。通常,处理此返回代码比尝试捕获存储过程中引发的错误更好。 IIRC,Transact-SQL无法实现这种捕获;需要使用第三代语言,如C语言。

要将myproc存储过程的返回码变为变量@myvar,语法为

exec @myvar = myproc [arguments] 

sp_password的一个简单示例:

declare @spreturn int  
exec @spreturn = sp_password 'notmyoldpw', 'notmynewpw'  
print "Return from sp_password is %1!", @spreturn  
go

Server Message:  Number  10315, Severity  14  
Server 'SDSTRHA01_SY01', Procedure 'sp_password', Line 148:  
Invalid caller's password specified, password left unchanged.  
Server Message:  Number  17720, Severity  16  
Server 'SDSTRHA01_SY01', Procedure 'sp_password', Line 158:  
Error:  Unable to set the Password.  
(1 row affected)  
Return from sp_password is 1  
(return status = 1)  

第一行中定义的int变量@spreturn得到了sp_password返回码,其值为1,如上一条消息行中的(return status = 1)所示。它不是零的原因很明显:sp_password,10315和17720中有两个错误。重点是这个非零返回码并忽略10315和17720.在你的存储过程中,应该对零检查@spreturn 。如果为零则运行正常,否则会出现故障。