SQL代理作业失败时在电子邮件中生成错误完整消息

SQL代理作业失败时在电子邮件中生成错误完整消息,sql,sql-server-2012,sql-agent-job,Sql,Sql Server 2012,Sql Agent Job,我有3个执行SSIS包的SQL代理作业。当作业出错时,它会生成一封主题为“作业失败-”的电子邮件,并在电子邮件中显示一条消息“作业失败”。该作业由schedule schename调用,要运行的最后一个步骤是运行 它没有在我查看作业历史记录时可见的完整错误消息。有没有办法将作业配置为在电子邮件中包含完整的错误消息?或者,是否有一种方法可以构建一个存储过程,该存储过程将在特定作业失败时执行,并查询其中一个系统表(sysjobs) 我以前从未这样做过,但我想我可以在sysjobs表中构建一个触发器,

我有3个执行SSIS包的SQL代理作业。当作业出错时,它会生成一封主题为“作业失败-”的电子邮件,并在电子邮件中显示一条消息“作业失败”。该作业由schedule schename调用,要运行的最后一个步骤是运行

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


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

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

Step1: Execute Package
如果步骤1失败:

Step2: use T-SQL with sp_db_sendmail
步骤2可以通过多种方式进行定制,就像您可以附加上一步ssis包生成的日志一样

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


如果您使用的是Project deployment model,那么您可以使用catalog做很多事情,比如使用SP执行ssis包,从日志表中获取错误详细信息。

下面是一个可以在作业中使用的脚本。它查找当天失败的任何作业。您可以每天运行一次,查看当天哪些作业失败。如果希望每30分钟左右运行一次,并且只查看在最后一小时内失败的作业,则可以添加时间变量。您必须能够使用
xp\u cmdshell
,因为您想使用
sp\u send\u 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

下面是一个示例查询,用于从SSIDB目录中提取消息。它们提供的信息比任何作业日志中都要多得多。您(或我)可以对此进行扩展,只返回给定包名的最新错误@Nice.McDermaid-我有一些类似的东西,但我需要在作业失败时立即生成的东西-而不是在设定时间运行并获取失败作业的所有信息的计划作业。换句话说,一旦作业失败,并且通知电子邮件被发送,我需要该电子邮件中的所有错误消息信息,或者,我可以创建另一封电子邮件来捕获整个消息。好的,你已经有了发送电子邮件的内容-只需将其添加到其中即可。如果你描述你发送电子邮件的过程,我们可以看看我们是否能解决一些问题。这只是SQL Agent作业失败时的一个步骤,还是在SSIS包中?@Nick.McDermaid-作业失败时,在“通知”中设置当前电子邮件。这是在作业中设置的,ssis包中没有设置任何内容。作业只是执行ssis包。关于仅在失败后发送(而不是轮询),请遵循@Pinwar13的建议。但您需要查询SSIS目录,而不是SQL代理表。正如您所猜测的,由于许多原因,代理表没有用处。只需查询SSIS目录表即可。唯一的诀窍是您只需要搜索正确的包标识符就可以获得包的正确日志。这是一个计划作业,我需要的是在作业失败时立即生成的内容。一旦作业失败,整个错误消息都需要通过电子邮件发送。因此,请每分钟运行一次。这并不费劲,我被要求想出一个最佳的解决方案——设置1分钟的时间表不是一个好办法。如果这项工作很重要,那么当它失败时,你将启动SSM进行调查并重新运行它,因此从一开始就没有任何意义。这将在n个作业上运行吗?如果是这样,您可以在日志上使用触发器table@DamonMatt这是因为只有在作业报告失败后才会将其写入表中,而失败发生在作业结束后,因此在作业的附加步骤中放置某些内容不会向您显示错误消息,因为它还没有出现。使用您的方法,如果我有一个查询sysjobs和sysjobhistory的步骤2,那么刚才发生的错误信息是否已经记录在其中?或者,在整个作业(包括步骤2)完成后,是否将错误信息记录到这些表中?如果是这样,这对我的目的没有帮助,因为在步骤1中不会出现错误信息。我错了吗?