SQL Server 2000:如何退出存储过程?

我怎样才能在存储过程中退出?

我有一个存储过程,我想早日退出(而试图debugging它)。 我试着调用RETURNRAISERROR ,并且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 

因为你没有BEGINEND语句。 你不应该看到打印,或运行这个声明的错误,只有Statement Completed (或类似的东西)。