[sql] SQL Server-SQL 스크립트 실행 중지 또는 중단

“break”또는 “exit”명령과 같이 SQL 서버에서 SQL 스크립트의 실행을 즉시 중지 할 수있는 방법이 있습니까?

삽입을 시작하기 전에 유효성 검사 및 조회를 수행하는 스크립트가 있으며 유효성 검사 또는 조회가 실패하면 중지하고 싶습니다.



답변

RAISERROR의 방법

raiserror('Oh no a fatal error', 20, -1) with log

연결이 종료되어 나머지 스크립트 실행이 중지됩니다.

WITH LOG이 방법으로 작동 하려면 심각도 레벨 20 이상과 옵션이 모두 필요합니다.

이것은 심지어 GO 문장에서도 작동합니다.

print 'hi'
go
raiserror('Oh no a fatal error', 20, -1) with log
go
print 'ho'

당신에게 출력을 줄 것입니다 :

hi
Msg 2745, Level 16, State 2, Line 1
Process ID 51 has raised user error 50000, severity 20. SQL Server is terminating this process.
Msg 50000, Level 20, State 1, Line 1
Oh no a fatal error
Msg 0, Level 20, State 0, Line 0
A severe error occurred on the current command.  The results, if any, should be discarded.

‘ho’는 인쇄되지 않습니다.

주의 사항 :

  • 이것은 관리자 ( ‘sysadmin’역할)로 로그인 한 경우에만 작동하며 데이터베이스 연결이없는 상태로 유지됩니다.
  • admin으로 로그인하지 않으면 RAISEERROR () 호출 자체가 실패 하고 스크립트는 계속 실행 됩니다.
  • sqlcmd.exe로 호출하면 종료 코드 2745가보고됩니다.

참조 : http://www.mydatabasesupport.com/forums/ms-sqlserver/174037-sql-server-2000-abort-whole-script.html#post761334

noexec 방법

GO 문과 함께 작동하는 다른 방법은 set noexec on입니다. 이로 인해 나머지 스크립트는 건너 뜁니다. 연결을 종료하지는 않지만 설정해야합니다.noexec 명령을 실행하기 전에 다시 꺼야합니다.

예:

print 'hi'
go

print 'Fatal error, script will not continue!'
set noexec on

print 'ho'
go

-- last line of the script
set noexec off -- Turn execution back on; only needed in SSMS, so as to be able 
               -- to run this script again in the same session.


답변

RETURN을 사용하십시오 (저장 프로 시저 내부 및 외부에서 모두 작동 함).


답변

SQLCMD 모드를 사용할 수있는 경우 주문

:on error exit

(콜론을 포함하여) RAISERROR가 실제로 스크립트를 중지시킵니다. 예 :

:on error exit

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SOMETABLE]') AND type in (N'U'))
    RaisError ('This is not a Valid Instance Database', 15, 10)
GO

print 'Keep Working'

출력합니다 :

Msg 50000, Level 15, State 10, Line 3
This is not a Valid Instance Database
** An error was encountered during execution of batch. Exiting.

배치가 중지됩니다. SQLCMD 모드가 켜져 있지 않으면 콜론에 대한 구문 분석 오류가 발생합니다. 불행히도, 스크립트가 SQLCMD 모드에 있지 않고 실행되는 것처럼 완전히 방탄하지는 않습니다. 여전히 명령 행에서 실행하고 있다면 괜찮습니다.


답변

RAISERROR- SQL을 사용하지 않습니다. SQL에는이 목적으로 사용할 수있는 IF 문이 있습니다. 유효성 검사 및 조회를 수행하고 로컬 변수를 설정 한 다음 IF 문에서 변수 값을 사용하여 삽입을 조건부로 만듭니다.

모든 유효성 검사 테스트의 변수 결과를 확인할 필요는 없습니다. 일반적으로 하나의 플래그 변수 만 사용하여 전달 된 모든 조건을 확인할 수 있습니다.

declare @valid bit

set @valid = 1

if -- Condition(s)
begin
  print 'Condition(s) failed.'
  set @valid = 0
end

-- Additional validation with similar structure

-- Final check that validation passed
if @valid = 1
begin
  print 'Validation succeeded.'

  -- Do work
end

유효성 검사가 더 복잡하더라도 최종 검사에 포함 할 플래그 변수는 몇 개만 있으면됩니다.


답변

SQL 2012+에서는 THROW 를 사용할 수 있습니다 .

THROW 51000, 'Stopping execution because validation failed.', 0;
PRINT 'Still Executing'; -- This doesn't execute with THROW

MSDN에서 :

예외를 발생시키고 실행을 TRY… CATCH 구문의 CATCH 블록으로 전송합니다. TRY… CATCH 구문을 사용할 수 없으면 세션이 종료됩니다. 예외가 발생한 행 번호와 절차가 설정됩니다. 심각도는 16으로 설정되어 있습니다.


답변

트랜잭션을 사용하여 noexec on / off 솔루션을 성공적으로 확장하여 스크립트를 전혀 또는 전혀 실행하지 않았습니다.

set noexec off

begin transaction
go

<First batch, do something here>
go
if @@error != 0 set noexec on;

<Second batch, do something here>
go
if @@error != 0 set noexec on;

<... etc>

declare @finished bit;
set @finished = 1;

SET noexec off;

IF @finished = 1
BEGIN
    PRINT 'Committing changes'
    COMMIT TRANSACTION
END
ELSE
BEGIN
    PRINT 'Errors occured. Rolling back changes'
    ROLLBACK TRANSACTION
END

분명히 오류가 있고 실행이 비활성화 된 경우에도 컴파일러는 IF에서 @finished 변수를 “이해합니다”. 그러나 실행이 비활성화되지 않은 경우에만 값이 1로 설정됩니다. 따라서 트랜잭션을 적절하게 커밋하거나 롤백 할 수 있습니다.


답변

SQL 문을 WHILE 루프로 감싸고 필요한 경우 BREAK를 사용할 수 있습니다.

WHILE 1 = 1
BEGIN
   -- Do work here
   -- If you need to stop execution then use a BREAK


    BREAK; --Make sure to have this break at the end to prevent infinite loop
END