如何捕获CMDEXEC SQL Server作业的退出代码?

时间:2012-09-04 12:17:59

标签: sql-server exit-code sql-server-agent sql-server-job

以下SQL Server作业总是退出,返回代码0表示成功,实际上它不执行其工作,即它不会删除“test.txt”。 如何捕获实际的退出代码(类似于%ERRORLEVEL%,或类似'权限被拒绝'的消息,或者在msdb.dbo.sp_add_jobstep中指示@command成功或失败的任何有意义的响应)?

说明:

  • {DBname} 是我是
  • 所有者的数据库的名称
  • {proxyName} 是SQL Server代理代理(对于'操作系统(CmdExec)'子系统有效)的名称,属于在SQL中映射到Windows域登录的凭据对 {folderUNC}
  • 具有完全控制权的服务器
  • {folderUNC} 是指向“test.txt”
  • 的文件夹的完整UNC路径

一些可能有用的细节:

  • 服务器:Microsoft SQL Server企业版(64位)版本9.00.4060.00
  • 操作系统:Microsoft Windows NT 5.2(3790)
  • 我不是系统管理员,只是数据库 {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 个答案:

答案 0 :(得分:2)

问题似乎是del在失败时未设置errorlevel。有几种方法可以“解决”这个问题,但我个人会选择编写自己的delete.exe,或者通过.bat文件。

示例:(delete.bat)

@echo off

del "%1"
if exist "%1" GOTO FAIL
EXIT /B 0

:FAIL
ECHO "File still there ! (%1)"
EXIT /B 1

你可以这样称呼它(@command):

delete.bat c:\test.txt

如果文件在被删除后仍然存在,它将返回失败状态。