SQL Server 2000:如何退出存储过程?
我怎样才能在存储过程中退出?
我有一个存储过程,我想早日退出(而试图debugging它)。 我试着调用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中的存储过程中退出?
您可以使用RETURN
立即停止执行存储过程。 从联机丛书引用:
从查询或过程无条件退出。 RETURN是即时且完整的,可以在任何时候使用退出过程,批处理或语句块。 后面的语句不会被执行。
出于偏执狂,我试过例子,它输出的印刷品,并立即停止执行。
除非您指定严重性为20或更高,否则raiserror
将不会停止执行。 请参阅MSDN文档 。
正常的解决方法是在每个raiserror
之后包含一个return
:
if @whoops = 1 begin raiserror('Whoops!', 18, 1) return -1 end
把它放在TRY/CATCH
。
当RAISERROR在TRY块中以11或更高的严重级别运行时,它将控制转移到关联的CATCH块
参考: MSDN 。
编辑:这适用于MSSQL 2005+,但我看到你现在已经澄清,你在MSSQL 2000上工作。我将留在这里作为参考。
我想出了为什么RETURN
并不是无条件地从存储过程返回。 我看到的错误是存储过程正在编译 – 而不是当它正在执行。
考虑一个虚构的存储过程:
CREATE PROCEDURE dbo.foo AS INSERT INTO ExistingTable EXECUTE LinkedServer.Database.dbo.SomeProcedure
即使这个stord程序包含一个错误(也许是因为对象有不同数量的列,也许在表中有时间戳列,也许存储过程不存在),你仍然可以保存它。 您可以保存它,因为您正在引用一个链接的服务器。
但是当你实际执行存储过程时,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
返回
before raiserror Msg 50000, Level 18, State 1, Procedure Archive_Session, Line 7 this is a raised error
这似乎是很多代码,但我发现这样做的最好方法。
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
因为你没有BEGIN
和END
语句。 你不应该看到打印,或运行这个声明的错误,只有Statement Completed
(或类似的东西)。