Подтвердить что ты не робот

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?

4b9b3361

Ответ 1

Вы можете использовать RETURN, чтобы немедленно остановить выполнение хранимой процедуры. Цитата взята из Books Online:

Выходит безоговорочно из запроса или процедура. ВОЗВРАТ немедленно и полный и может использоваться в любой точке для выхода из процедуры, партии или. Заявления о том, что следовать за RETURN не выполняются.

Из паранойи я попробовал пример, и он выводит ПЕЧАТИ и немедленно прекращает выполнение.

Ответ 2

Если вы не укажете серьезность 20 или выше, raiserror не остановит выполнение. См. Документацию MSDN.

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

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

Ответ 3

Поместите его в TRY/CATCH.

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

Ссылка: MSDN.

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

Ответ 4

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

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

CREATE PROCEDURE dbo.foo AS

INSERT INTO ExistingTable
EXECUTE LinkedServer.Database.dbo.SomeProcedure

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

Но когда вы фактически выполняете хранимую процедуру, SQL Server затем компилирует ее и формирует план запроса.

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

И вот почему RETURN не возвращается, поскольку он еще не запустил .

Ответ 5

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

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

Ответ 6

Это похоже на много кода, но лучший способ, который я нашел для этого.

    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

Ответ 7

Потому что у вас нет операторов BEGIN и END. Вы не должны видеть отпечатки или ошибки, выполняющие этот оператор, только Statement Completed (или что-то в этом роде).