SQL Server 2000: Как выйти из хранимой процедуры?

как я могу выйти в середине хранимой процедуры?

у меня есть хранимая процедура, в которой я хочу выйти рано (при попытке отладить ее). Я пытался дозвониться 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?

7 ответов


можно использовать RETURN немедленно остановить выполнение хранимой процедуры. Цитата взята из Книги Онлайн:

безусловный выход из запроса или процедура. Возвращение немедленно и полный и может быть использовано в любой момент для выхода из процедуры, пакета или блок операторов. Заявления, которые последующие возвраты не выполняются.

из паранойи я попробовал пример yor, и он выводит отпечатки и останавливает выполнение немедленно.


если вы не укажете серьезность 20 или выше,raiserror не остановит выполнение. Вижу документация MSDN.

обычным обходным путем является включение return после raiserror:

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

положите его в TRY/CATCH.

когда RAISERROR выполняется с серьезностью 11 или выше в блоке TRY, это передает управление связанному Поймать блок

ссылки: MSDN.

EDIT: это работает для MSSQL 2005+, но я вижу, что теперь вы уточнили, что работаете над MSSQL 2000. Я оставлю это здесь для справки.


я понял, почему RETURN безоговорочно не возвращается из хранимой процедуры. Ошибка, которую я вижу, заключается в том, что хранимая процедура составлен - нет, когда он выполняется.

рассмотрим воображаемую хранимую процедуру:

CREATE PROCEDURE dbo.foo AS

INSERT INTO ExistingTable
EXECUTE LinkedServer.Database.dbo.SomeProcedure

несмотря на то, что этот stord proedure содержит ошибку (возможно, это потому, что объекты имеют различное количество столбцов, возможно, в таблице есть столбец timestamp, возможно, хранимая процедура не exist), вы все еще можете сохранить его. Вы можете сохранить его, потому что ссылаетесь на связанный сервер.

но когда вы на самом деле выполнить хранимая процедура, SQL Server тогда compiles it и генерирует план запроса.

моя ошибка не происходит на линии 114, это on строка 114. SQL Server не может скомпилировать хранимую процедуру, поэтому она не выполняется.

и поэтому RETURN не возвращается, потому что он даже не started еще.


это работает здесь.

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 (или что-то в этом роде).