SQL 스크립트 실행을 중단하는 방법


16

SQL 스크립트를 작업 중이며 일부 조건이 충족되지 않으면 스크립트를 계속 중지해야합니다.

내가 그것을 구글 할 때, 나는 심각도가 20 인 RaisError가 그것을 끝내는 것을 알았습니다. 그러나 어떤 이유로 나는 그 옵션을 사용할 수 없습니다.

SQL 스크립트 실행을 중지하는 가능한 대안이 무엇인지 알려주십시오.


1
오류를 발생시킬 수없는 이유는 무엇입니까? 이 스크립트는 저장 프로 시저입니까?
Namphibian

나는 당신의 주먹 질문을 명확하게 이해하지 못했습니다. 두 번째 질문; 아니오 이것은 SP가 아닙니다
새로운 개발자

1
스크립트는 무엇입니까? 여러 배치로 구성되어 있습니까? 여기서 답을 보셨습니까?
Martin Smith

답변:


8

로부터 RAISERROR 문서 (강조 광산) :

0에서 18까지의 심각도 수준은 모든 사용자가 지정할 수 있습니다. 19에서 25까지의 심각도 수준은 sysadmin 고정 서버 역할의 멤버 또는 ALTER TRACE 권한이있는 사용자 만 지정할 수 있습니다. 심각도가 19에서 25 사이 인 경우 WITH LOG 옵션이 필요합니다.

이러한 기준을 충족하지 않으므로 스크립트를 실행하는 주체 일 가능성이 높습니다.

RAISERROR; 를 사용하는 데 아무런 문제가 없습니다 . 과도한 심각도 수준을 사용하고 있습니다. 레벨 16을 기본값으로 사용하여 오류가 발생하고 시퀀스가 ​​종료됩니다. 보다 정확하게하려면 Microsoft 자체에서 제공하는 수준을 따르십시오.

여기에 이미지 설명을 입력하십시오

이제 스크립트의 컨텍스트에 따라 스크립트 RAISERROR자체를 "종료"하지 않기 때문에 사용하는 것만으로는 충분하지 않을 수 있습니다 (일반 심각도 수준 사용).

예를 들면 다음과 같습니다.

RAISERROR(N'Test', 16, 1);

SELECT 1;   /* Executed! */

이 것 모두 에서 오류가 발생 하고 결과 집합을 반환합니다.

스크립트를 즉시 종료하려면 사용하는 것이 좋습니다 RETURN( GOTO-type 구문 을 사용하는 것은 대체 방법이있는 대부분의 프로그래밍 서클에서 권장하지 않습니다).

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */

또는를 사용하여 오류를 처리하십시오 . 심각도가 11 이상인 경우 TRY/CATCH실행이 CATCH블록으로 이동합니다.

BEGIN TRY
    RAISERROR(N'Test', 16, 1);
    SELECT 1;   /* Not executed */
END TRY
BEGIN CATCH
    SELECT 2;   /* Executed */
END CATCH

BEGIN TRY
    RAISERROR(N'Test', 10, 1);
    SELECT 1;   /* Executed */
END TRY
BEGIN CATCH
    SELECT 2;   /* Not executed */
END CATCH

별도의 문제는 스크립트는 여러 배치에 걸쳐있는 경우 - RETURN에만 종료됩니다 배치 :

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */
GO

SELECT 2;   /* Executed! */

이 문제를 해결하기 위해 @@ERROR모든 배치가 시작될 때 확인할 수 있습니다 .

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */
GO

IF (@@ERROR != 0)
    RETURN;

SELECT 2;   /* Not executed */

편집 : Martin Smith는 주석에서 올바르게 지적 했으므로 2 개의 배치에서만 작동합니다. 3 개 이상의 배치로 확장하려면 다음과 같이 계단식으로 발생하는 오류를 캐스케이드 할 수 있습니다 GOTO.

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */
GO

IF (@@ERROR != 0)
BEGIN
    RAISERROR(N'Error already raised. See previous errors.', 16, 1);
    RETURN;
END

SELECT 2;   /* Not executed */
GO

IF (@@ERROR != 0)
BEGIN
    RAISERROR(N'Error already raised. See previous errors.', 16, 1);
    RETURN;
END

SELECT 3;   /* Not executed */

또는 그가 지적했듯이 환경에 적합한 SQLCMD방법을 사용할 수도 있습니다 .


그 마지막 제안은 효과가 없습니다. pastebin을 참조하십시오 . 나는 sqlcmd 방법을
Martin Smith

6

GOTO문장을 사용하여 원하는 곳을 건너 뛸 수 있습니다 . 다시 말해, 오류나 다른 조건이 발생하면 스크립트 하단에 레이블 (예 TheEndOfTheScript::)이 있고 goto TheEndOfTheScript;명령문을 발행 할 수 있습니다.

다음은 간단한 샘플입니다.

print 'here is the first statement...';

print 'here is the second statement...';

-- substitute whatever conditional flow determining factor
-- you'd like here. I have chosen a dummy statement that will
-- always return true
--
if (1 = 1)
    goto TheEndOfTheScript;

print 'here is the third statement...';

print 'here is the fourth statement...';


TheEndOfTheScript:
print 'here is the end of the script...';

이 실행 결과는 다음과 같습니다.

here is the first statement...
here is the second statement...
here is the end of the script...

보다시피 GOTO, 세번째와 네번째 문장의 인쇄를 건너 뛰고 레이블 ( TheEndOfTheScript)로 바로 이동했습니다 .


7
단일 배치가있을 때만 작동하며 GO 문을 실행하자마자 중단됩니다.
Gabriel


0

에 동의 SET NOEXEC ON/OFF단순히 사용 (단일 블록을 포함하는) 그러나 procs 저장에 RETURN문을.

주의 사항 : 스크립트 파일에서 여러 GO명령문 RETURN이있는 경우 현재 블록에서만 나오고 다음 블록 / 일괄 처리를 계속합니다.

참고 : GOTO잘못된 코딩 방법으로, " TRY..CATCH"를 사용하는 것이 좋습니다. SQL Server 2008 이후에 소개 THROW되었으며 2012 년에 도입되었습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.