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
не остановит выполнение. Смотрите Примечание.обычный обходной путь должен включать
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
не является безусловным возвратом из хранимой процедуры. Ошибка, которую я вижу, заключается в том, что хранимая процедура compiled - не тогда, когда она выполняется.рассмотрим воображаемую хранимую процедуру:
CREATE PROCEDURE dbo.foo AS INSERT INTO ExistingTable EXECUTE LinkedServer.Database.dbo.SomeProcedure
несмотря на то, что этот stord proedure содержит ошибку (возможно, это связано с тем, что объекты имеют разное количество столбцов, возможно, в таблице есть столбец timestamp, возможно, хранимая процедура не имеет существуют), вы все еще можете сохранить его. Вы можете сохранить его, потому что вы ссылаетесь на связанном сервере.
но когда вы на самом деле выполнить хранимая процедура, SQL Server затем составляет он и генерирует план запроса.
моя ошибка не происходит на линии 114, это on строка 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
возвращает
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