AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 18153
Accepted
JHFB
JHFB
Asked: 2012-05-19 06:36:04 +0800 CST2012-05-19 06:36:04 +0800 CST 2012-05-19 06:36:04 +0800 CST

作业类别中的任何作业失败时发出警报

  • 772

是否可以在 SQL Server 2008 中设置警报,以便在特定类别的作业失败时发送电子邮件?

我想知道,因为我想在 SSRS 订阅失败时设置电子邮件 - 所有这些订阅都是Report Server类别中的作业。

编辑- 事实证明,当 SSRS 订阅失败时,作业本身不会失败,所以我的问题不适用于 SSRS 订阅监控使用。但是我仍然想知道我们在我们的环境中运行的其他工作

sql-server sql-server-2008
  • 2 2 个回答
  • 2009 Views

2 个回答

  • Voted
  1. Best Answer
    Aaron Bertrand
    2012-05-19T06:56:09+08:002012-05-19T06:56:09+08:00

    您可以创建一个作业,每分钟检查一次 msdb.dbo.sysjobhistory 表(或者您想要的频率)。您可能希望实现一个队列表,以便您只为任何单个实例故障发送一次消息。

    USE msdb;
    GO
    
    CREATE TABLE dbo.ReportServerJob_FailQueue
    (
      job_id UNIQUEIDENTIFIER,
      run_date INT,
      run_time INT, -- horrible schema, just matching sysjobhistory
      sql_message_id INT,
      sent BIT NOT NULL DEFAULT 0,
      PRIMARY KEY (job_id, run_date, run_time)
    );
    

    因此,您可以在作业中安排的代码变为:

    INSERT dbo.ReportServerJob_FailQueue
      (job_id, run_date, run_time, sql_message_id)
    SELECT job_id, run_date, run_time, sql_message_id
    FROM msdb.dbo.sysjobhistory AS h
    WHERE step_id = 0 
    AND run_status = 0
    AND EXISTS 
    (
      SELECT 1 FROM msdb.dbo.sysjobs AS j
        INNER JOIN msdb.dbo.syscategories AS c
        ON j.category_id = c.category_id
        WHERE j.job_id = h.job_id
       AND c.name = 'Report Server'
    )
    AND NOT EXISTS 
    (
      SELECT 1 FROM dbo.ReportServerJob_FailQueue
        WHERE job_id = h.job_id
        AND run_date = h.run_date
        AND run_time = h.run_time
    );
    

    现在我假设您想为每次失败发送一封单独​​的电子邮件,因此这也可能是工作的一部分(或不同工作的一部分,尽管这不一定是明智的):

    DECLARE 
      @subject NVARCHAR(4000),
      @body NVARCHAR(4000),
      @name SYSNAME,
      @id UNIQUEIDENTIFIER,
      @date INT,
      @time INT,
      @msg INT;
    
    DECLARE c CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
    FOR SELECT q.job_id, q.run_date, q.run_time, q.sql_message_id, j.name
      FROM dbo.ReportServerJob_FailQueue AS q
      INNER JOIN msdb.dbo.sysjobs AS j
      ON q.job_id = j.job_id
      WHERE q.sent = 0;
    
    OPEN c;
    
    FETCH NEXT FROM c INTO @id, @date, @time, @msg, @name;
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
    
      SET @subject = 'Report Server job ' + @name + ' failed.';
      SET @body = 'Error number: ' + RTRIM(@msg);
    
      BEGIN TRY
        EXEC msdb.dbo.sp_send_dbmail 
          @profile_name = 'default',     -- you may need to change this
          @recipients   = '[email protected]', -- you will need to change this
          @subject      = @subject,
          @body         = @body;
    
        UPDATE dbo.ReportServerJob_FailQueue
          SET sent = 1 
          WHERE job_id = @id
          AND run_date = @date
          AND run_time = @time;
      END TRY
      BEGIN CATCH
        PRINT 'Will have to try that one again later.';
      END
    
      FETCH NEXT FROM c INTO @id, @date, @time, @msg, @name;
    END
    
    CLOSE c; DEALLOCATE c;
    

    还有一些其他的选择:

    • 拉入 sysjobhistory.message
    • 查看失败的各个步骤
    • 即使有多次失败,也只能在 n 分钟/小时内为任何作业发送一次消息
    • 发送一封包含所有失败作业列表的电子邮件,而不是每次失败的电子邮件
    • 您可能希望在消息中包含 run_date 和 run_time,因为电子邮件的发送或接收速度可能不够快,无法准确衡量作业实际失败的时间(我没有在此处包含它,因为它们可怕的数据类型选择将这些东西格式化为皇家 PITA)
    • 您可能希望在一段时间后清理旧行,因此可能还需要一个 purge 命令

    如果尚未设置数据库邮件,请参阅本教程。

    您还可以使用 3rd 方工具(例如SQL Sentry),这将使这一切变得更简单。完全披露:我为 SQL Sentry 工作。

    • 10
  2. user507
    2015-11-25T12:40:10+08:002015-11-25T12:40:10+08:00

    根据您的编辑,这只是 Aaron 的回答的扩展,涉及 SSRS 订阅失败本身(不仅仅是 SQL 代理作业)。我建议只在作业监控作业中添加一个步骤,或者您可以完全将其作为一项单独的作业来完成。

    要获得订阅状态,您只需检查ReportServer.dbo.ExecutionLog3 视图。该Status列将显示除rsSuccess失败之外的任何内容。只需过滤RequestType = 'Subscription'. 您将需要包括一些时间检查,因此您不会每次都检查所有记录。如果您每 15 分钟运行一次作业,只需检查TimeStart过去 15 分钟。

    • 0

相关问题

  • 死锁的主要原因是什么,可以预防吗?

  • 我在索引上放了多少“填充”?

  • 是否有开发人员遵循数据库更改的“最佳实践”类型流程?

  • 如何确定是否需要或需要索引

  • 从 SQL Server 2008 降级到 2005

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何查看 Oracle 中的数据库列表?

    • 8 个回答
  • Marko Smith

    mysql innodb_buffer_pool_size 应该有多大?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    从 .frm 和 .ibd 文件恢复表?

    • 10 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve