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

时间:2009-12-07 21:03:02

标签: sql-server tsql stored-procedures sql-server-2000 flow-control

如何在存储过程中退出?

我有一个存储过程,我希望尽早解救(尝试调试时)。我试过调用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中的存储过程?

7 个答案:

答案 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)

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