【问题标题】:Generating error full message in email when SQL agent job failSQL 代理作业失败时在电子邮件中生成错误完整消息
【发布时间】:2017-02-26 18:35:03
【问题描述】:

我有 3 个执行 SSIS 包的 SQL 代理作业。当作业出错时,它会生成一封主题为“作业失败 -”的电子邮件,并且电子邮件中包含“作业失败”的消息。该作业由调度方案调用,运行的最后一步是 Run_'

当我查看作业历史记录时,它没有可见的完整错误消息。有什么方法可以将作业配置为在电子邮件中包含 COMPLETE 错误消息?或者,有没有一种方法可以构建一个存储过程,该过程将在特定作业失败时执行,并查询其中一个系统表(sysjobs)?

我以前从未这样做过,但我想我可以在 sysjobs 表中构建一个触发器,该触发器在特定作业失败时触发,并执行 sp_db_sendmail。我试图避免走这条路。有完成我的任务的最佳方式吗?

【问题讨论】:

  • 这是从 ssisdb 目录中提取消息的示例查询。这些提供的信息比任何作业日志中都多得多。您(或我)可以扩展它以仅返回给定包名称的最新错误。 sqlblog.com/blogs/jamie_thomson/archive/2012/10/17/…
  • @Nice.McDermaid - 我有类似的东西,但我需要在作业失败时立即生成的东西 - 不是在设定时间运行并获取所有信息的预定作业失败的工作。换句话说,一旦作业失败并发送通知电子邮件,我就需要该电子邮件中的所有错误消息信息,或者,我可以构建另一封电子邮件来捕获整个消息。
  • 好吧,您已经有一些发送电子邮件的东西 - 只需将其添加到其中。如果您描述了您发送电子邮件的过程,我们可以看看我们是否可以解决问题。它只是一个失败的 SQL 代理作业步骤,还是在 SSIS 包中?
  • @Nick.McDermaid - 当前电子邮件在作业失败时设置在“通知”中。这是在 Job 中设置的,在 ssis 包中没有设置任何内容。该作业只是执行 ssis 包。
  • 关于只在失败后发送(而不是轮询),请遵循@Pinwar13 的建议。但是您需要查询 SSIS 目录,而不是 SQL 代理表。正如您所推测的那样,代理表没有用处有很多原因。只需查询 SSIS 目录表即可。唯一的技巧是您只需要搜索正确的包标识符即可获取包的正确日志

标签: sql sql-server-2012 sql-agent-job


【解决方案1】:

一种更好的方法是使用多个作业步骤。

Step1: Execute Package

如果 Step1 失败:

Step2: use T-SQL with sp_db_sendmail

Step2可以通过多种方式进行自定义,例如可以附加上一步ssis包生成的日志。

或者

从作业历史记录中获取错误消息并添加到 sp_db_sendmail Refer。

如果您使用项目部署模型,您可以使用目录做很多事情,例如使用 SP 执行 ssis 包,从日志表中获取错误详细信息。

【讨论】:

  • 使用您的方法,如果我有一个查询 sysjobs 和 sysjobhistory 的步骤 2 - 刚刚发生的错误信息是否已经记录在其中?还是在整个作业完成后,包括第 2 步在内的这些表中记录了错误信息?如果是这样,这对我的目的没有帮助,因为在第 1 步中不会出现刚刚发生的错误信息。我错了吗?
【解决方案2】:

这是您可以在作业中使用的脚本。它会查找当天失败的所有作业。您可以每天运行一次以查看当天失败的作业。如果您想每 30 分钟左右运行一次,并且只查看在过去一小时内失败的作业,您可以添加一个时间变量。你必须能够使用xp_cmdshell,因为你想使用sp_send_dbmail

declare @filepath nvarchar(100)     --file path where results are stored as csv
declare @filename nvarchar(100)     --file name where results are stored
declare @command nvarchar(4000)     --dynamic sql of bcp command
declare @count int                  --result count
declare @emailList varchar(4000)    --people to email
declare @dt int                     --current date in INT format



set @filepath = '"e:\somefolder\'
set @filename = 'Failures.csv"'
set @emailList = 'email@domain.com; someOtherEmail@domain.com'
set @dt = (select convert(int,replace(convert(date,substring(convert(varchar,getdate()),1,11)),'-','')))

--query to get the jobs that failed and why. Looks for jobs that were executed today.
select
    h.run_date,
    h.run_time,
    h.run_status,
    j.name,
    j.description,
    h.message
from 
    msdb.dbo.sysjobhistory  h
    inner join
    msdb.dbo.sysjobs j on j.job_id = h.job_id
where
    h.run_status = 0
    and h.run_date = @dt

--if there were failures then put them in a csv and email them.
set @count = @@ROWCOUNT

if (select @count) > 0
begin
    set @command = 'bcp "select h.run_date, h.run_status, j.name, j.description, h.message from msdb.dbo.sysjobhistory h inner join msdb.dbo.sysjobs j on j.job_id = h.job_id where h.run_status = 0 and h.run_date = convert(int,''' + convert(varchar,@dt) + ''') " queryout '
    set @command = @command + @filepath + @filename + ' -c -t, -T '----> character data, tab delimtted is default use  -t, for comma ... trusted conn,server instance to connect to
    exec master..xp_cmdshell @command

    exec msdb.dbo.sp_send_dbmail 
                    @profile_name = null,
                    @recipients  = @emailList,
                    @body = 'Attached is the job failure results',  
                    @body_format = 'TEXT',
                    @subject = 'Job Failures',
                    @file_attachments = 'e:\someFolder\Failures.csv'

end

【讨论】:

  • 再一次,这是一个预定的作业,我需要的是在作业失败时生成的东西。作业失败后,需要立即通过电子邮件发送整个错误消息。
  • 所以每分钟运行一次。它不征税
  • 我被要求提出一个最佳解决方案 - 设置 1 分钟的时间表不会是一个。
  • 好吧,如果这项工作很重要,那么当它失败时,您将启动 SSMS 以进行调查并重新运行它,因此这一点从一开始就被忽略了。这将在 n 个作业上运行吗?如果是这样,您可以在日志表上使用触发器
  • @DamonMatt 那是因为在作业报告失败之前它不会被写入表中,这发生在作业结束后,因此在作业中的额外步骤中放置一些东西不会给你错误消息,因为它还不存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多