问题
The following SQL Server job always exits with return code 0 indicating success, when in fact it does not do its job, i.e. it does not delete "test.txt". How can I catch the actual exit code (something like %ERRORLEVEL%, or a 'permission denied'-like message, or any meaningful response indicating success or failure of @command at msdb.dbo.sp_add_jobstep)?
Remarks:
- {DBname} is the name of the database I am the owner of
- {proxyName} is the name of the SQL Server Agent Proxy (that is active to the 'Operating system (CmdExec)' subsystem) belonging to a credential that maps to a Windows domain login in SQL Server that has full control to {folderUNC}
- {folderUNC} is the full UNC path to the folder where "test.txt" is
A few details that might be useful:
- Server: Microsoft SQL Server Enterprise Edition (64-bit) version 9.00.4060.00
- OS: Microsoft Windows NT 5.2 (3790)
- I am not a sysadmin, but only the owner of database {DBname}
CODE:
USE {DBname}
GO
DECLARE @returnCode AS INT
DECLARE @jobName NVARCHAR(128)
DECLARE @jobStep1Name SYSNAME
SET @jobName = 'CMDEXEC Test Job'
SET @jobStep1Name = 'CMDEXEC Test Job Step 1'
EXEC @returnCode = msdb.dbo.sp_add_job
@job_name = @jobName,
@enabled = 1,
@start_step_id = 1,
@notify_level_eventlog = 2,
@delete_level = 0;
IF (@@ERROR <> 0 OR @returnCode <> 0)
PRINT N'Error @ sp_add_job. @@ERROR = ' + CONVERT(VARCHAR(10), @@ERROR) +
N' @returnCode = ' + CONVERT(VARCHAR(10), @returnCode
EXEC @returnCode = msdb.dbo.sp_add_jobstep
@job_name = @jobName,
@step_id = 1,
@step_name = @jobStep1Name,
@subsystem = 'CMDEXEC',
@command = 'DEL {folderUNC}\test.txt',
@cmdexec_success_code = 0,
@on_success_action = 1,
@on_fail_action = 2,
@proxy_name = '{proxyName}';
IF (@@ERROR <> 0 OR @returnCode <> 0)
PRINT N'Error @ sp_add_job. @@ERROR = ' + CONVERT(VARCHAR(10), @@ERROR) +
N' @returnCode = ' + CONVERT(VARCHAR(10), @returnCode
EXEC @returnCode = msdb.dbo.sp_add_jobserver
@job_name = @jobName;
IF (@@ERROR <> 0 OR @returnCode <> 0)
PRINT N'Error @ sp_add_job. @@ERROR = ' + CONVERT(VARCHAR(10), @@ERROR) +
N' @returnCode = ' + CONVERT(VARCHAR(10), @returnCode
EXEC @returnCode = msdb.dbo.sp_start_job
@job_name = @jobName,
@step_name = @jobStep1Name;
IF (@@ERROR <> 0 OR @returnCode <> 0)
PRINT N'Error @ sp_add_job. @@ERROR = ' + CONVERT(VARCHAR(10), @@ERROR) +
N' @returnCode = ' + CONVERT(VARCHAR(10), @returnCode
EXEC @returnCode = msdb.dbo.sp_delete_job
@job_name = @jobName;
IF (@@ERROR <> 0 OR @returnCode <> 0)
PRINT N'Error @ sp_add_job. @@ERROR = ' + CONVERT(VARCHAR(10), @@ERROR) +
N' @returnCode = ' + CONVERT(VARCHAR(10), @returnCode
回答1:
The trouble seems to be that del
does not set the errorlevel
when it fails. There are several ways to 'work around' this, but personally I'd go for either writing my own delete.exe, or via a .bat file.
Example : (delete.bat)
@echo off
del "%1"
if exist "%1" GOTO FAIL
EXIT /B 0
:FAIL
ECHO "File still there ! (%1)"
EXIT /B 1
And you can call it like this (@command
):
delete.bat c:\test.txt
it will return as failed when the file is still there after supposedly being deleted.
来源:https://stackoverflow.com/questions/12263337/how-to-catch-the-exit-code-of-a-cmdexec-sql-server-job