SQL 스크립트를 작업 중이며 일부 조건이 충족되지 않으면 스크립트를 계속 중지해야합니다.
내가 그것을 구글 할 때, 나는 심각도가 20 인 RaisError가 그것을 끝내는 것을 알았습니다. 그러나 어떤 이유로 나는 그 옵션을 사용할 수 없습니다.
SQL 스크립트 실행을 중지하는 가능한 대안이 무엇인지 알려주십시오.
SQL 스크립트를 작업 중이며 일부 조건이 충족되지 않으면 스크립트를 계속 중지해야합니다.
내가 그것을 구글 할 때, 나는 심각도가 20 인 RaisError가 그것을 끝내는 것을 알았습니다. 그러나 어떤 이유로 나는 그 옵션을 사용할 수 없습니다.
SQL 스크립트 실행을 중지하는 가능한 대안이 무엇인지 알려주십시오.
답변:
로부터 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
방법을 사용할 수도 있습니다 .
이 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
)로 바로 이동했습니다 .
가장 좋은 방법은 SET NOEXEC ON을 사용하는 것입니다
자세한 내용은 여기를 참조하십시오. 현재 배치 및 후속 배치에서 명령문의 실행을 중지 또는 ABORT 또는 BREAK하는 방법 SQL SERVER의 일부 조건에 따라 GO 문으로 구분