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

问题描述 投票:0回答:7

如何在存储过程中退出?

我有一个存储过程,我想尽早退出(同时尝试调试它)。我尝试拨打

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 中的存储过程?

sql-server t-sql stored-procedures sql-server-2000 control-flow
7个回答
111
投票

您可以使用

RETURN
立即停止存储过程的执行。引用自在线图书

无条件退出查询或 程序。立即退货 完整且可以随时使用 退出过程、批处理或 语句块。声明称 follow RETURN 不被执行。

出于偏执,我尝试了你的示例,它确实输出了 PRINT 并立即停止执行。


32
投票

除非您指定严重性为 20 或更高,否则

raiserror
将不会停止执行。 请参阅 MSDN 文档

正常的解决方法是在每个

return
之后添加
raiserror

if @whoops = 1
    begin
    raiserror('Whoops!', 18, 1)
    return -1
    end

12
投票

将其放入

TRY/CATCH

当 RAISERROR 以严重程度运行时 TRY 块中的 11 或更高,它 将控制权转移给关联的 捕获块

参考:MSDN

编辑: 这适用于 MSSQL 2005+,但我看到您现在已经澄清您正在使用 MSSQL 2000。我将把它留在这里供参考。


9
投票

我明白了为什么

RETURN
没有无条件地从存储过程返回。我看到的错误是在存储过程被编译时,而不是在执行时。 考虑一个假想的存储过程:

CREATE PROCEDURE dbo.foo AS INSERT INTO ExistingTable EXECUTE LinkedServer.Database.dbo.SomeProcedure

即使这个存储过程包含错误(也许是因为对象的列数不同,也许表中有时间戳列,也许存储过程不存在),您仍然可以
保存
它。您可以保存它,因为您正在引用链接服务器。

但是当您实际执行

存储过程时,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


5
投票

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

5
投票

这是因为你没有

BEGIN
END

1
投票
Statement Completed

(或类似的东西)。

    

© www.soinside.com 2019 - 2024. All rights reserved.