【问题标题】:How to create an email alert for a procedure if it does not finish within 5 minutes?如果程序未在 5 分钟内完成,如何为程序创建电子邮件警报?
【发布时间】:2026-01-18 04:25:01
【问题描述】:

当用户在我们的应用程序中运行程序但程序未完成时,我需要创建电子邮件警报。我知道如何生成电子邮件,但如何编写代码来检查该过程何时运行并确定它是否已运行超过 5 分钟?

我已经研究了所有的 dbms 实用程序,但没有一个比我想要的更接近。

我也知道如何放置长时间运行的会话,但我的问题是我只对一个过程感兴趣,并且从我收集到的 sqlid 可以改变。这就是我打算这样做的方式,但是因为这改变了我如何知道用户是在运行该过程还是他们正在运行其他东西。我可以提取用户会话 ID,但他们可以同时运行多个程序。我怎么知道哪一个是我的目标程序?

【问题讨论】:

  • 我进行了搜索,但没有任何内容接近我要查找的内容。我应该为你列出我的研究吗?
  • 我发布它是因为我不相信您在来这里并寻求解决方案之前没有进行任何研究。 Google 中的“Oracle 查找长期运行的查询”是一个很好的开始。
  • 我知道你来自哪里,所以我会留在那里。我做了谷歌搜索,我看到它可以在哪里查看长时间运行的会话,但我只对运行时的一个程序感兴趣。我们有数百个处于活动状态的会话,如果有特定程序,我需要找到一个或多个会话。我会继续寻找。
  • 要考虑的一种方法是让过程将其开始时间和进程 ID 写入状态表,并在完成时将其删除。一个单独的进程可以按照你想要的任何频率检查该表,如果它发现一个运行时间超过 5 分钟的条目,发送一封电子邮件——如果合适的话,可能会终止该进程。
  • 在将任何内容写入状态表时考虑事务。我认为您应该为此使用自治事务

标签: sql oracle plsql alert


【解决方案1】:

您也可以使用包DBMS_APPLICATION_INFO,而不是使用专用状态表。

DBMS_APPLICATION_INFO.SET_MODULE('Starting at '||TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS'), 'Starting procedure');

... your actual procedure

-- If you like you can set intermediate updates at any time:
DBMS_APPLICATION_INFO.SET_ACTION('Still running...');

DBMS_APPLICATION_INFO.SET_MODULE(NULL, NULL);

当程序运行时,您可以通过

查询它
SELECT SID, SERIAL#, USERNAME, OSUSER, MODULE, ACTION
from V$SESSION
where USERNAME = ...;

【讨论】:

    【解决方案2】:

    您可以运行两个程序(不同的会话),一个运行您的脚本/程序,另一个检查另一个程序是否已经运行完毕。

    以下是检查其他程序是否已在 5 分钟后运行完毕的脚本。

    DECLARE
        var VARCHAR2(1);
    BEGIN
        DBMS_LOCK.SLEEP(300);
        BEGIN
            SELECT column_if_has_value_means_program_was_done
              INTO var
              FROM some_table_that_your_procedure_will_update;
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                NULL;
        END;
        IF var IS NULL THEN
            SEND_EMAIL_PROCEDURE;
        END IF;
    END;
    /
    

    【讨论】: