バッチファイルからsqlcmdを実行していますが、バックアップに問題が発生したときに0以外のERRORLEVELを返すようにするにはどうすればよいのでしょうか。
バッチファイルからsqlcmdを実行していますが、バックアップに問題が発生したときに0以外のERRORLEVELを返すようにするにはどうすればよいのでしょうか。
回答:
sqlcmdでオプション-bを使用する必要があります。
-bエラーの発生時にsqlcmdが終了し、DOS ERRORLEVEL値を返すことを指定します。SQL Serverエラーメッセージの重大度レベルが10より大きい場合、DOS ERRORLEVEL変数に返される値は1です。それ以外の場合、返される値は0です
次のMSDN SQLCMDユーティリティページから:http ://msdn.microsoft.com/en-us/library/ms162773.aspx
RAISERRORがsqlcmdスクリプト内で使用され、状態127が発生した場合、sqlcmdは終了し、メッセージIDをクライアントに返します。例えば:
RAISERROR(50001、10、127)
そのため、BACKUP DATABASE...
コマンドをTRY...CATCH
ブロックでラップし、適切なエラーメッセージsqlcmd
を生成して、バッチファイルに戻すことができます。
たとえば、次のerrorleveltest.sql
ファイルを検討します。
:ON ERROR EXIT
BEGIN TRY
/* creates error 3147 Backup and restore operations
are not allowed on database tempdb */
BACKUP DATABASE tempdb;
END TRY
BEGIN CATCH
DECLARE @msg NVARCHAR(255);
SET @msg = 'An error occurred: ' + ERROR_MESSAGE();
RAISERROR (50002, 10, 127);
END CATCH
そして、次の.batファイル:(最初の行は読みやすいように折り返されていますが、1行にする必要があります。)
@echo off
"C:\Program Files\Microsoft SQL Server\110\Tools\Binn\sqlcmd" -S "someinstance" -E
-i .\errorleveltest.sql
ECHO Errorlevel: %ERRORLEVEL%
これにより、cmd.exeプロンプトから次が返されます。
Msg 18054, Level 16, State 1, Server CP708-D377\MV, Line 9
Error 50002, severity 10, state 127 was raised, but no message with that error number
was found in sys.messages. If error is larger than 50000, make sure the user-defined
message is added using sp_addmessage.
Errorlevel: 1
ご覧のとおり、通常の戻り値0ではなくERRORLEVEL 1が返されます。実際のエラー番号(この場合は50002)を反映するERRORLEVELを取得できません。コードに問題があるか、環境に何らかの問題がある可能性があります。
ERRORLEVEL
までに、SQL Serverから報告されたエラー番号と同じ値を期待するべきではありません。ErrorNumberは、SQL Server固有の値であり、その理由(つまりSQL Server)が終了した理由を示します。一方、それERRORLEVEL
はSQLCMD固有の値であり、その理由(つまりSQLCMD)が終了した理由を示します。