如何在存储过程中退出?
我有一个存储过程,我希望尽早解救(尝试调试时)。我试过调用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]
我知道它一直在运行,因为我遇到了进一步的错误。我没有看到任何打印。如果我注释掉大部分存储过程:
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]
*/
然后我没有得到我的错误,我看到了结果:
before raiserror
Server: Msg 50000, Level 18, State 1, Procedure Archive_Session, Line 5
this is a raised error
before return
所以问题是:如何摆脱SQL Server中的存储过程?
答案 0 :(得分:79)
您可以使用RETURN
立即停止执行存储过程。引自Books Online:
无条件退出查询或 程序。立即返回 完成,可以随时使用 退出过程,批处理或 声明块。声明 跟随RETURN未执行。
出于偏执,我试过你的例子,它确实输出了PRINT并立即停止执行。
答案 1 :(得分:28)
除非您指定严重性为20或更高,否则raiserror
将不会停止执行。请参阅MSDN documentation。
正常的解决方法是在return
之后添加raiserror
:
if @whoops = 1
begin
raiserror('Whoops!', 18, 1)
return -1
end
答案 2 :(得分:10)
将其放入TRY/CATCH
。
以严重性运行RAISERROR时 它在TRY块中为11或更高 将控制转移到相关联的 CATCH块
参考:MSDN。
编辑:这适用于MSSQL 2005+,但我看到您现在已经澄清您正在使用MSSQL 2000.我将在此留待此参考。
答案 3 :(得分:9)
我弄清楚为什么RETURN
无法无条件地从存储过程返回。我看到的错误是存储过程正在编译 - 而不是在它被执行时。
考虑一个虚构的存储过程:
CREATE PROCEDURE dbo.foo AS
INSERT INTO ExistingTable
EXECUTE LinkedServer.Database.dbo.SomeProcedure
即使这个stord proedure包含一个错误(可能是因为对象有不同的列数,也许表中有一个时间戳列,也许存储过程不存在),你仍然可以保存它。您可以保存它,因为您正在引用链接服务器。
但是当你实际执行存储过程时,SQL Server然后编译它,并生成一个查询计划。
我的错误不是发生在第114行,在第114行.SQL Server无法编译存储过程,这就是它失败的原因。
这就是RETURN
没有返回的原因,因为它还没有开始。
答案 4 :(得分:4)
这可以在这里工作。
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
返回
before raiserror
Msg 50000, Level 18, State 1, Procedure Archive_Session, Line 7
this is a raised error
答案 5 :(得分:4)
这似乎是很多代码,但我发现这是最好的方法。
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
答案 6 :(得分:1)
因为你没有BEGIN
和END
语句。您不应该只看到打印或运行此语句的错误Statement Completed
(或类似的东西)。