Ian*_*oyd 60 t-sql sql-server stored-procedures sql-server-2000 flow-control
如何在存储过程中退出?
我有一个存储过程,我想尽早摆脱(尝试调试).我已经打过电话RETURN,并RAISERROR和SP在后台继续运行:
CREATE PROCEDURE dbo.Archive_Session @SessionGUID uniqueidentifier AS
print 'before raiserror'
raiserror('this is a raised error', 18, 1)
print 'before return'
return -1
print 'after return'
[snip]
Run Code Online (Sandbox Code Playgroud)
我知道它继续运行,因为我遇到了进一步的错误.我看不到任何印刷品.如果我注释掉大部分存储过程:
CREATE PROCEDURE dbo.Archive_Session @SessionGUID uniqueidentifier AS
print 'before raiserror'
raiserror('this is a raised error', 18, 1)
print 'before return'
return -1
print 'after return'
/*
[snip]
*/
Run Code Online (Sandbox Code Playgroud)
然后我没有得到我的错误,我看到结果:
before raiserror
Server: Msg 50000, Level 18, State 1, Procedure Archive_Session, Line 5
this is a raised error
before return
Run Code Online (Sandbox Code Playgroud)
所以问题是:如何摆脱SQL Server中的存储过程?
And*_*mar 28
除非您指定严重性为20或更高,raiserror否则不会停止执行.请参阅MSDN文档.
正常的解决方法是return在每个之后包括raiserror:
if @whoops = 1
begin
raiserror('Whoops!', 18, 1)
return -1
end
Run Code Online (Sandbox Code Playgroud)
我想出为什么RETURN不能无条件地从存储过程返回.我看到的错误是在编译存储过程时 - 而不是在执行时.
考虑一个虚构的存储过程:
CREATE PROCEDURE dbo.foo AS
INSERT INTO ExistingTable
EXECUTE LinkedServer.Database.dbo.SomeProcedure
Run Code Online (Sandbox Code Playgroud)
即使这个stord proedure包含一个错误(可能是因为对象有不同的列数,也许表中有一个时间戳列,也许存储过程不存在),你仍然可以保存它.您可以保存它,因为您正在引用链接服务器.
但是当您实际执行存储过程时,SQL Server会编译它,并生成查询计划.
我的错误没有发生在第114行,它在第114行.SQL Server无法编译存储过程,这就是它失败的原因.
这就是为什么RETURN不回归,因为它还没有开始.
这在这里有效。
ALTER PROCEDURE dbo.Archive_Session
@SessionGUID int
AS
BEGIN
SET NOCOUNT ON
PRINT 'before raiserror'
RAISERROR('this is a raised error', 18, 1)
IF @@Error != 0
RETURN
PRINT 'before return'
RETURN -1
PRINT 'after return'
END
go
EXECUTE dbo.Archive_Session @SessionGUID = 1
Run Code Online (Sandbox Code Playgroud)
退货
before raiserror
Msg 50000, Level 18, State 1, Procedure Archive_Session, Line 7
this is a raised error
Run Code Online (Sandbox Code Playgroud)
这看起来像是很多代码,但这是我发现的最好的方法。
ALTER PROCEDURE Procedure
AS
BEGIN TRY
EXEC AnotherProcedure
END TRY
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.
);
RETURN --this forces it out
END CATCH
--Stuff here that you do not want to execute if the above failed.
END --end procedure
Run Code Online (Sandbox Code Playgroud)