2016-12-20 12 views
2

SQLCMD 및 다른 명령의 호출을 포함하는 .bat (Windows 명령) 파일이 있습니다. (물론 SQLCMD가 T-SQL 코드를 SQL Server로 보냅니다.) SQL 코드에서 특정 조건을 감지하고 조건부로 전체 배치 파일을 종료하려고합니다. 나는 RAISERROR, THROW, 그리고 0 (내가 자랑스럽지 않다)과 SQLCMD의 다양한 명령 행 스위치 및 .bat 파일의 errorlevel 처리와 함께 심의 부서의 다양한 조합을 시도했다.조건부로 SQLCMD를 통해 실행되는 SQL 코드에서 .BAT 파일을 끝내는 방법

5789568에 대한 답변을 시도했지만 제 경우에는 작동하지 않습니다. 실패한 시도 하나를 보여주는 두 개의 파일이 있습니다. 3 개 이상의 테이블이 있으면 중단을 시도합니다. 그러나 마지막 명령 (에코)이 실행될 때 알 수 있듯이 박쥐 파일을 중단하지 않습니다. SQLCMD의 실행을 중단하지 않습니다. SQLCMD가 얼마나 많은 테이블이 있는지 알려주므로 볼 수 있습니다.

example.bat

set ERRORLEVEL=0 
sqlcmd -b -S dbread.vistaprint.net -E -d columbus -e -i example.sql 
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL% 
echo we got to the end of the BAT file 

example.sql

SET XACT_ABORT ON 
if ((SELECT COUNT(*) FROM sys.tables) > 3) 
    begin 
    RAISERROR ('There are more than 3 tables. We will try to stop', 18, -1) 
    end 
SELECT COUNT(*) FROM sys.tables 
+0

코드는 거의 OK입니다. 프로세스 출력을 숨기는 것에 대해 말하고 있습니다. 명령 출력을 없애려면 'NUL'으로 리디렉션하십시오. 그래서'sqlcmd -b -S bla.bla.net -E -d my_db -e -i example.sql'은'sqlcmd -b -S bla.bla.net -E -d my_db -e -i example.sql이 될 것입니다. > NUL이라고합니다. 명령 출력이 블랙홀로 보내지지만 'ERRORLEVEL'은 여전히 ​​접근 가능합니다. – elzooilogico

+0

또는 오류 출력 만 없애 버리십시오. * NUL *을 * 2로 변경하십시오. NUL * – elzooilogico

+0

@elzooilogico - 아니, OP 문제와 관련이 없습니다. – dbenham

답변

0

@ dbenson의 대답은 .bat 파일의 문제를 해결합니다. 그러나 .sql 파일에 문제가 있습니다. 증상은 오류가 발생하더라도 마지막 행이 실행된다는 것입니다. 다음은 완벽한 솔루션입니다. 즉,이 두 파일이 올바르게 작동합니다.

코드를 검사하는 "오류"는 'master'라는 데이터베이스가 존재한다는 것입니다. 'master'를 데이터베이스 이름이 아닌 것으로 바꾸면 오류없이 실행됩니다.

example.bat

REM Replace the server name with any SQL Server server to which you 
REM have at least read access. The contents of the server don't matter. 
sqlcmd -b -S dbread.vistaprint.net -E -i example.sql 
if %errorlevel% neq 0 exit /b %errorlevel% 
echo 'In the .bat file, we got past the error check, so run was successful.' 

example.sql

if exists (select * from master.sys.databases where name = 'master') 
    begin 
    RAISERROR ('Found an error condition', 18, 10) 
    return 
    end 
print 'In the SQL file, we got past the error check, so run was successful.' 

0

%ERRORLEVEL%는 통상 환경 변수 아니다. 현재 ERRORLEVEL을 리턴하는 동적 의사 변수입니다. 실제 환경 변수를 set ERRORLEVEL=0으로 명시 적으로 정의하면 동적 특성이 손상되고 %ERRORLEVEL%은 사용자 정의 환경 변수의 값을 영원히 반환합니다. 당신은 는 ERRORLEVEL, RANDOM, CD, 시간, 날짜에 대한 자신의 값을 정의하지한다 등

는 ERRORLEVEL을 취소하려는 경우, 당신은 내가 좋아하는 0으로 값을 설정하는 명령을 실행해야합니다 (call)을 사용하십시오. 코드에 다른 문제가 없는지 가정

, 그것은 다음과 같이 수정되어야합니다 : 항상 ERRORLEVEL을 설정 있도록

(call) 
sqlcmd -b -S dbread.vistaprint.net -E -d columbus -e -i example.sql 
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL% 
echo we got to the end of the BAT file 

sqlcmd는 외부 명령 (exe 인 프로그램)입니다. 따라서 ERRORLEVEL을 삭제할 필요가 없으며 (call)을 제거 할 수 있습니다. 성공시 ERRORLEVEL을 0으로 설정하지 않는 내부 명령을 실행하기 전에 ERRORLEVEL을 지우는 것에 대해서만 걱정할 필요가 있습니다. (Which cmd.exe internal commands clear the ERRORLEVEL to 0 upon success? 참조)