Есть ли команда в Microsoft SQL Server T-SQL, чтобы сообщить script прекратить обработку? У меня есть script, который я хочу сохранить в архивных целях, но я не хочу, чтобы кто-нибудь запускал его.
Команда T-SQL STOP или ABORT в SQL Server
Ответ 1
Альтернативным решением может быть изменение потока выполнения вашего script с помощью инструкции GOTO
...
DECLARE @RunScript bit;
SET @RunScript = 0;
IF @RunScript != 1
BEGIN
RAISERROR ('Raise Error does not stop processing, so we will call GOTO to skip over the script', 1, 1);
GOTO Skipper -- This will skip over the script and go to Skipper
END
PRINT 'This is where your working script can go';
PRINT 'This is where your working script can go';
PRINT 'This is where your working script can go';
PRINT 'This is where your working script can go';
Skipper: -- Don't do nuttin!
Внимание! Вышеприведенный образец был получен из примера, который я получил от Merrill Aldrich. Прежде чем выполнять инструкцию GOTO
вслепую, я рекомендую вам прочитать его учебник по Управление потоком в сценариях T-SQL.
Ответ 2
Нет, нет никого - у вас есть несколько вариантов:
-
Оберните весь script в большом блоке if/end, который просто гарантирован, чтобы он не был истинным (т.е. "если 1 = 2 начать" - это будет работать, однако, если script не включают любые инструкции GO (поскольку они указывают новую партию)
-
Используйте оператор return вверху (опять же, ограниченный разделителями пакетов)
-
Используйте подход на основе соединения, который обеспечит неисполнение для всего script (все подключение будет более точным) - используйте что-то вроде "SET PARSEONLY ON" или "SET NOEXEC ON" в верхней части script. Это обеспечит выполнение всех операторов в соединении (или до тех пор, пока указанный оператор набора не будет выключен) не будет выполняться и вместо этого будет анализироваться/скомпилироваться.
-
Используйте блок комментариев, чтобы прокомментировать весь script (т.е./* и */)
РЕДАКТИРОВАТЬ: Демонстрация того, что оператор "return" является пакетным, - обратите внимание, что вы будете продолжать видеть результирующие наборы после возврата:
select 1
return
go
select 2
return
select 3
go
select 4
return
select 5
select 6
go
Ответ 3
Почему бы просто не добавить следующее в начало script
PRINT 'INACTIVE SCRIPT'
RETURN
Ответ 4
Чтобы обойти проблему RETURN/GO, вы можете поместить RAISERROR ('Oi! Stop!', 20, 1) WITH LOG
вверху.
Это закроет клиентское соединение в соответствии с RAISERROR на MSDN.
Самый большой недостаток - вы должны быть sysadmin для использования серьезности 20.
Edit:
Простая демонстрация, чтобы встретить комментарий Джерси-чувак...
RAISERROR ('Oi! Stop!', 20, 1) WITH LOG
SELECT 'Will not run'
GO
SELECT 'Will not run'
GO
SELECT 'Will not run'
GO
Ответ 5
RAISERROR с серьезностью 20 будет сообщаться как ошибка в средстве просмотра событий.
Вы можете использовать SET PARSEONLY ON; (или NOEXEC). В конце script используйте GO SET PARSEONLY OFF;
SET PARSEONLY ON;
-- statement between here will not run
SELECT 'THIS WILL NOT EXEC';
GO
-- statement below here will run
SET PARSEONLY OFF;
Ответ 6
Попробуйте запустить это как TSQL Script
SELECT 1
RETURN
SELECT 2
SELECT 3
Возврат завершает выполнение.
Выходит безоговорочно из запроса или процедура. ВОЗВРАТ немедленно и полный и может использоваться в любой точке для выхода из процедуры, партии или. Заявления о том, что следовать за RETURN не выполняются.
Ответ 7
Несмотря на очень ясное и сильное описание, RETURN не работал у меня внутри хранимой процедуры (чтобы пропустить дальнейшее выполнение). Мне пришлось изменить логику состояния. Случается на SQL 2008, 2008 R2:
create proc dbo.prSess_Ins
(
@sSessID varchar( 32 )
, @idSess int out
)
as
begin
set nocount on
select @id= idSess
from tbSess
where sSessID = @sSessID
if @idSess > 0 return -- exit sproc here
begin tran
insert tbSess ( sSessID ) values ( @sSessID )
select @idSess= scope_identity( )
commit
end
пришлось изменить на:
if @idSess is null
begin
begin tran
insert tbSess ( sSessID ) values ( @sSessID )
select @idSess= scope_identity( )
commit
end
Обнаружен в результате поиска дублированных строк. Отладка PRINT подтвердила, что @idSess имеет значение больше нуля в проверке IF - RETURN не нарушил выполнение!
Ответ 8
Вот несколько глупый способ сделать это, который работает с GO-пакетами, используя "глобальную" переменную.
if object_id('tempdb..#vars') is not null
begin
drop table #vars
end
create table #vars (continueScript bit)
set nocount on
insert #vars values (1)
set nocount off
-- Start of first batch
if ((select continueScript from #vars)=1) begin
print '1'
-- Conditionally terminate entire script
if (1=1) begin
set nocount on
update #vars set continueScript=0
set nocount off
return
end
end
go
-- Start of second batch
if ((select continueScript from #vars)=1) begin
print '2'
end
go
И вот та же идея, что и для транзакции и блока try/catch для каждой GO-партии. Вы можете попытаться изменить различные условия и/или дать ему сгенерировать ошибку (разделите на 0, см. Комментарии), чтобы проверить, как она себя ведет:
if object_id('tempdb..#vars') is not null
begin
drop table #vars
end
create table #vars (continueScript bit)
set nocount on
insert #vars values (1)
set nocount off
begin transaction;
-- Batch 1 starts here
if ((select continueScript from #vars)=1) begin
begin try
print 'batch 1 starts'
if (1=0) begin
print 'Script is terminating because of special condition 1.'
set nocount on
update #vars set continueScript=0
set nocount off
return
end
print 'batch 1 in the middle of its progress'
if (1=0) begin
print 'Script is terminating because of special condition 2.'
set nocount on
update #vars set continueScript=0
set nocount off
return
end
set nocount on
-- use 1/0 to generate an exception here
select 1/1 as test
set nocount off
end try
begin catch
set nocount on
select
error_number() as errornumber
,error_severity() as errorseverity
,error_state() as errorstate
,error_procedure() as errorprocedure
,error_line() as errorline
,error_message() as errormessage;
print 'Script is terminating because of error.'
update #vars set continueScript=0
set nocount off
return
end catch;
end
go
-- Batch 2 starts here
if ((select continueScript from #vars)=1) begin
begin try
print 'batch 2 starts'
if (1=0) begin
print 'Script is terminating because of special condition 1.'
set nocount on
update #vars set continueScript=0
set nocount off
return
end
print 'batch 2 in the middle of its progress'
if (1=0) begin
print 'Script is terminating because of special condition 2.'
set nocount on
update #vars set continueScript=0
set nocount off
return
end
set nocount on
-- use 1/0 to generate an exception here
select 1/1 as test
set nocount off
end try
begin catch
set nocount on
select
error_number() as errornumber
,error_severity() as errorseverity
,error_state() as errorstate
,error_procedure() as errorprocedure
,error_line() as errorline
,error_message() as errormessage;
print 'Script is terminating because of error.'
update #vars set continueScript=0
set nocount off
return
end catch;
end
go
if @@trancount > 0 begin
if ((select continueScript from #vars)=1) begin
commit transaction
print 'transaction committed'
end else begin
rollback transaction;
print 'transaction rolled back'
end
end
Ответ 9
Я знаю, что вопрос старый, и на него ответили правильно несколькими путями, но нет ответа, который я использовал в подобных ситуациях. Первый подход (очень простой):
IF (1=0)
BEGIN
PRINT 'it will not go there'
-- your script here
END
PRINT 'but it will here'
Второй подход:
PRINT 'stop here'
RETURN
-- your script here
PRINT 'it will not go there'
Вы можете легко протестировать его, чтобы убедиться, что он ведет себя так, как ожидалось.