【问题标题】:Oracle DBMS_ALERT in Oracle 12cOracle 12c 中的 Oracle DBMS_ALERT
【发布时间】:2020-07-31 16:37:10
【问题描述】:

我有一个表 (my_tab),其中包含针对同一表中特定 ID 的 STATUS 列。

我需要一种通过 DBMS_ALERT 进程在 STATUS 列更改值时收到警报的方法。

我正在考虑使用触发器来启动 ALERT,即:

create or replace trigger my_tab_upd after update of status on my_tab for each row
begin
   dbms_alert.signal('mystatusalert', 'changed from '||:old.status||' to '||:new.status||'.');
end;
/

有了这个,我现在如何在 PL/SQL 过程中收到此 STATUS 更改的警报/通知,以便现在开始并根据此 STATUS 更改执行另一个操作?

除此之外,通过我的应用程序设置,将有多个用户。基于此,我如何将警报定位到特定用户/会话,以便正确的用户只收到他们的警报,而不是其他人的。

我正在查看来自基于 Web 的应用程序 (Oracle APEX) 的警报,因此不想锁定前端,因此任何关于此的建议都会很好。

举个例子就好了。

【问题讨论】:

    标签: oracle plsql notifications oracle12c


    【解决方案1】:

    我会给自己发一封电子邮件。例如:

    create or replace trigger my_tab_upd 
      after update of status on my_tab 
      for each row
    begin
      utl_mail.send (sender     => 'me@company.com',
                     recipients => 'me@company.com',
                     subject    => 'MY_TAB status changed',
                     message    => 'old = ' || :old.status ||', new = ' || :new.status
                    );
    end;
    

    DBMS_ALERT 示例:在 Scott 的架构中,我想通知我的存储过程 EMP 表中的某些内容发生了变化,然后做一些事情(我将只显示消息)。

    首先,创建一个触发器;警报名称为alert_emp,稍后将在存储过程中使用:

    SQL> create or replace trigger trg_au_emp
      2    after update on emp
      3    for each row
      4  begin
      5    dbms_alert.signal
      6      ('alert_emp', 'Salary changed for ' || :new.ename ||
      7                    ' from ' || :old.sal ||
      8                    ' to '   || :new.sal);
      9  end;
     10  /
    
    Trigger created.
    

    程序:

    SQL> create or replace procedure p_test is
      2    l_msg    varchar2(200);
      3    l_status number;
      4  begin
      5    dbms_alert.register ('alert_emp');
      6    dbms_alert.waitone  ('alert_emp', l_msg, l_status);
      7    dbms_output.put_line(l_msg ||': '|| l_status);
      8  end;
      9  /
    
    Procedure created.
    

    现在,执行程序:

    SQL> exec p_test;
    

    在这里,它只是在等待 EMP 表中发生某些事情。 在另一个会话中我正在更新表格。提交是强制性;否则,什么也不会发生。 p_test 仍在等待。

    update emp set sal = 1000 where empno = 7369;
    commit;
    

    在第一个会话中,一旦 commit 被执行,屏幕显示如下: PL/SQL 过程成功完成。

    Salary changed for SMITH from 800 to 1000: 0
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    【讨论】:

    • 感谢您的回复,但我实际上不想发送电子邮件。实际上,我希望在 PL/SQL 中收到 STATUS 值已更改的警报,以便通知我。
    • 好吧,我发布了一个关于 dbms_alert 如何工作的示例。看看吧。
    • 太棒了 - 会看看。
    • 请教几个问题:1) 有没有一种方法可以检查 ALERT 是否已经注册,以免再次注册? 2)使用我的应用程序设置,将有多个用户。基于此,我如何针对特定用户/会话定位警报,以便正确的用户收到他们的警报而不是其他人?
    • 注册对执行它的会话有效,并在会话终止后关闭。所以你可以安排它(正如@Littlefoot 建议的那样),但是你会丢失所有在周期性作业运行之间触发的信号。尽管 Oracle 文档在这里没有明确说明,但测试表明 未订阅的信号 被丢弃。您可以切换到AQ 以获取消息persistance,但这里似乎矫枉过正。您应该将事件 推送 给订阅者,而不是让他们 poll 数据库 - 一种原始的电子邮件提议。
    猜你喜欢
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 2014-10-03
    • 2018-10-26
    • 2019-02-06
    • 2017-09-12
    • 2018-06-09
    • 1970-01-01
    相关资源
    最近更新 更多