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