codememo

SQL Server의 T-SQL STOP 또는 ABROT 명령

tipmemo 2023. 7. 7. 19:03
반응형

SQL Server의 T-SQL STOP 또는 ABROT 명령

Microsoft SQL Server T-SQL에 스크립트에 처리를 중지하라는 명령이 있습니까?보관 목적으로 보관할 스크립트가 있지만 다른 사용자가 실행하지 않았으면 합니다.

다른 해결책은 다음을 사용하여 스크립트 실행 흐름을 변경하는 것일 수 있습니다.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!

경고!위의 샘플은 제가 메릴 앨드리치로부터 받은 샘플에서 따온 것입니다.구현하기 전에GOTOT-SQL 스크립트의 흐름 제어에 대한 그의 튜토리얼을 맹목적으로 읽는 것을 추천합니다.

아니요, 없습니다. 몇 가지 옵션이 옵션은 다음과 같습니다.

  1. 전체 스크립트를 단순히 사실이 아닌 것으로 확인되는 큰 if/end 블록(예: "1=2 시작 시")으로 감습니다. 그러나 스크립트에 GO 문이 포함되지 않은 경우에만 작동합니다(새로운 배치를 나타냅니다).

  2. 맨 위에 있는 반환 문 사용(다시, 배치 구분 기호로 제한됨)

  3. 전체 스크립트(전체 연결이 더 정확하도록)에 대해 실행되지 않도록 보장하는 연결 기반 접근 방식을 사용합니다. 스크립트 상단에 'SET PARSEONLY ON' 또는 'SET NO EXECON'과 같은 것을 사용합니다.이렇게 하면 연결의 모든 문(또는 해당 set 문이 해제될 때까지)이 실행되지 않고 대신 구문 분석/컴파일만 수행됩니다.

  4. 주석 블록을 사용하여 전체 스크립트(예: /* 및 */)를 주석 처리합니다.

편집: '반품' 문이 배치별임을 시연합니다. 반환 후에도 결과 집합이 계속 표시됩니다.

select 1
return
go
select 2
return
select 3
go
select 4
return
select 5
select 6
go

스크립트의 시작 부분에 다음을 간단히 추가하는 것은 어떻습니까?

PRINT 'INACTIVE SCRIPT'
RETURN

RETURN/GO 문제를 해결하려면 다음과 같이 하십시오.RAISERROR ('Oi! Stop!', 20, 1) WITH LOG맨 위에

MSDN의 RAISERROR에 따라 클라이언트 연결이 닫힙니다.

가장 큰 단점은 심각도 20을 사용하려면 sysadmin이어야 한다는 것입니다.

편집:

저지 디드의 발언에 대응하기 위한 간단한 시연...

RAISERROR ('Oi! Stop!', 20, 1)  WITH LOG
SELECT 'Will not run'
GO
SELECT 'Will not run'
GO
SELECT 'Will not run'
GO

심각도가 20인 RAISERROR는 이벤트 뷰어에서 오류로 보고됩니다.

SET PARSEONLY ON;(또는 NOEXEC)을 사용할 수 있습니다.스크립트가 끝나면 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;

다음은 "글로벌" 변수를 사용하여 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

각 GO-Batch에 대해 트랜잭션 및 Try/Catch 블록에 사용된 것과 동일한 아이디어가 있습니다.다양한 조건을 변경하거나 오류(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

TSQL 스크립트로 실행해 보십시오.

SELECT 1
RETURN
SELECT 2
SELECT 3

반환이 실행을 종료합니다.

리턴(트랜잭션-SQL)

쿼리 또는 프로시저에서 무조건 종료합니다.RETURN은 즉시 완료되며, 프로시저, 배치 또는 문 블록을 종료하기 위해 언제든지 사용할 수 있습니다.RETURN 뒤에 오는 문은 실행되지 않습니다.

매우 명확하고 강력한 설명에도 불구하고 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

중복된 행을 찾은 결과 발견되었습니다.디버깅 인쇄에서 @idSess가 IF 검사에서 0보다 큰 값을 가지고 있음이 확인되었습니다. RETURN은 실행을 중단하지 않았습니다!

질문이 오래되었고 몇 가지 다른 방법으로 정답을 맞췄다는 것을 알지만 비슷한 상황에서 사용한 나의 답은 없습니다.첫 번째 접근 방식(매우 기본):

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'

예상대로 작동하는지 확인하기 위해 직접 쉽게 테스트할 수 있습니다.

실행을 중지하려면 SET NOEXEC ON을 사용하십시오.

 Go
 Select 'I want to kill the job after some error or based on some validation.
 Go
 Select 'Raiserror not working'
  Go
 Select 'I have to be admin to define severity 20'
 go
Select 'I got an error, come custom validation failed, I don't want to run the 
 rest  of the script'.
Go
 SET NOEXEC ON
 Select 'rest of the script should not run after NOEXEC on executed'.

언급URL : https://stackoverflow.com/questions/2028072/t-sql-stop-or-abort-command-in-sql-server

반응형