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

Команда T-SQL STOP или ABORT в SQL Server

Есть ли команда в Microsoft SQL Server T-SQL, чтобы сообщить script прекратить обработку? У меня есть script, который я хочу сохранить в архивных целях, но я не хочу, чтобы кто-нибудь запускал его.

4b9b3361

Ответ 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 (Transact-SQL)

Выходит безоговорочно из запроса или процедура. ВОЗВРАТ немедленно и полный и может использоваться в любой точке для выхода из процедуры, партии или. Заявления о том, что следовать за 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'

Вы можете легко протестировать его, чтобы убедиться, что он ведет себя так, как ожидалось.