DBMS_CHANGE_NOTIFICATION 和 NEW_REG_START

发布于 2024-11-30 18:41:21 字数 3283 浏览 1 评论 0原文

我阅读了一些如何使用 DBMS_CHANGE_NOTIFICATION 进行异步触发器的示例。

仅当 STATUS = 1709003 时,我才需要为表 CONTENT 创建触发器。

因此,我创建了以下过程:

  CREATE OR REPLACE PROCEDURE tables_changed_chnt(ntfnds IN SYS.chnf$_desc) IS
  l_table_name              VARCHAR2(60);
  l_event_type              NUMBER;
  l_numtables               NUMBER;
  status                    NUNBER;
  Row_id                    VARCHAR2(20);
  numrows                   NUMBER;
  token                     varchar2(100);
  subject                   varchar2(100);
  message                   varchar2(100);
  result                    varchar2(100);
  planid                                number := 0;
  userId                                    number := -10000;
  stoponefromatmissing          number := 0;
  timetostopprocess                 number := 0;
  retrials                                number := 2;
  stoponeinvalidaddress         number := 0;
  NL_CONTENT                number:=-1;
  event_status              number:=-1;
BEGIN
  l_numtables  := ntfnds.numtables;
  l_event_type := ntfnds.event_type;

  IF l_event_type = DBMS_CHANGE_NOTIFICATION.EVENT_OBJCHANGE THEN
    FOR i IN 1 .. l_numtables LOOP
      l_table_name      := ntfnds.table_desc_array(i).table_name;

      if l_table_name = 'CONTENT' then
        IF (bitand(operation_type, DBMS_CHANGE_NOTIFICATION.ALL_ROWS) = 0) THEN
          numrows := ntfnds.table_desc_array(i).numrows;
        ELSE 
          numrows :=0;   /* ROWID INFO NOT AVAILABLE */
        END IF;
       FOR j IN 1..numrows LOOP
         Row_id := ntfnds.table_desc_array(i).row_desc_array(j).row_id;
         select NL_CONTENT_ID into NL_CONTENT from CONTENT where rownum=:Row_id;
         select event_status_code into status from CONTENT where rownum=:Row_id; 
          if (status = 1709003) then
            select NL_CONTENT_PLAN_ID into planid from NL_CONTENT where NL_CONTENT_ID=:NL_CONTENT;
            result := workflow_cust.om_start_delivery(token,
                                             subject,
                                             message,
                                             planid,
                                                                     userId,
                                             stoponefromatmissing,
                                             timetostopprocess,
                                             retrials,
                                             stoponeinvalidaddress);
         end if;
      END LOOP;   
      end if    
    END LOOP; 
  END IF;      
END;

我发现我需要使用类似于以下内容的内容来调用它:

DECLARE
  REGDS      SYS.CHNF$_REG_INFO;
  regid      NUMBER;
  cust_id    varchar2(20);
  qosflags   NUMBER;
BEGIN
qosflags := DBMS_CHANGE_NOTIFICATION.QOS_RELIABLE + DBMS_CHANGE_NOTIFICATION.
 QOS_ROWIDS;
REGDS := SYS.CHNF$_REG_INFO ('SP_EVENT_GENERATE', qosflags, 0,0,0);
regid := DBMS_CHANGE_NOTIFICATION.NEW_REG_START (REGDS); 
  /* registe the customer table */
SELECT CUSTID INTO cust_id  FROM TB_CUSTOMER WHERE ROWNUM=1;
DBMS_CHANGE_NOTIFICATION.REG_END;
END;
  1. 我需要写什么而不是 SELECT CUSTID INTO cust_id FROM TB_CUSTOMER WHERE ROWNUM=1;

  2. 有没有办法检索更改的对象,而不是仅检索 rowid - 因为这会节省我在第一个过程中进行查找的时间?

I read some example of how to use DBMS_CHANGE_NOTIFICATION for an asynchronous trigger.

I need to create a trigger for table CONTENT only if STATUS = 1709003.

So I created the following PROCEDURE:

  CREATE OR REPLACE PROCEDURE tables_changed_chnt(ntfnds IN SYS.chnf$_desc) IS
  l_table_name              VARCHAR2(60);
  l_event_type              NUMBER;
  l_numtables               NUMBER;
  status                    NUNBER;
  Row_id                    VARCHAR2(20);
  numrows                   NUMBER;
  token                     varchar2(100);
  subject                   varchar2(100);
  message                   varchar2(100);
  result                    varchar2(100);
  planid                                number := 0;
  userId                                    number := -10000;
  stoponefromatmissing          number := 0;
  timetostopprocess                 number := 0;
  retrials                                number := 2;
  stoponeinvalidaddress         number := 0;
  NL_CONTENT                number:=-1;
  event_status              number:=-1;
BEGIN
  l_numtables  := ntfnds.numtables;
  l_event_type := ntfnds.event_type;

  IF l_event_type = DBMS_CHANGE_NOTIFICATION.EVENT_OBJCHANGE THEN
    FOR i IN 1 .. l_numtables LOOP
      l_table_name      := ntfnds.table_desc_array(i).table_name;

      if l_table_name = 'CONTENT' then
        IF (bitand(operation_type, DBMS_CHANGE_NOTIFICATION.ALL_ROWS) = 0) THEN
          numrows := ntfnds.table_desc_array(i).numrows;
        ELSE 
          numrows :=0;   /* ROWID INFO NOT AVAILABLE */
        END IF;
       FOR j IN 1..numrows LOOP
         Row_id := ntfnds.table_desc_array(i).row_desc_array(j).row_id;
         select NL_CONTENT_ID into NL_CONTENT from CONTENT where rownum=:Row_id;
         select event_status_code into status from CONTENT where rownum=:Row_id; 
          if (status = 1709003) then
            select NL_CONTENT_PLAN_ID into planid from NL_CONTENT where NL_CONTENT_ID=:NL_CONTENT;
            result := workflow_cust.om_start_delivery(token,
                                             subject,
                                             message,
                                             planid,
                                                                     userId,
                                             stoponefromatmissing,
                                             timetostopprocess,
                                             retrials,
                                             stoponeinvalidaddress);
         end if;
      END LOOP;   
      end if    
    END LOOP; 
  END IF;      
END;

I saw that I need to invoke it with something similar to:

DECLARE
  REGDS      SYS.CHNF$_REG_INFO;
  regid      NUMBER;
  cust_id    varchar2(20);
  qosflags   NUMBER;
BEGIN
qosflags := DBMS_CHANGE_NOTIFICATION.QOS_RELIABLE + DBMS_CHANGE_NOTIFICATION.
 QOS_ROWIDS;
REGDS := SYS.CHNF$_REG_INFO ('SP_EVENT_GENERATE', qosflags, 0,0,0);
regid := DBMS_CHANGE_NOTIFICATION.NEW_REG_START (REGDS); 
  /* registe the customer table */
SELECT CUSTID INTO cust_id  FROM TB_CUSTOMER WHERE ROWNUM=1;
DBMS_CHANGE_NOTIFICATION.REG_END;
END;
  1. What do I need to write instead of SELECT CUSTID INTO cust_id FROM TB_CUSTOMER WHERE ROWNUM=1;

  2. Is there a way to retrieve the changed object, instead only the rowid - since it will save me time to do the find in the first procedure?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不交电费瞎发啥光 2024-12-07 18:41:21

在注册块中(DBMS_CHANGE_NOTIFICATION.NEW_REG_STARTDBMS_CHANGE_NOTIFICATION.REG_END 之间),您需要对表 CONTENT 执行一个简单的查询来注册您对该表的更改的兴趣,例如:

SELECT select NL_CONTENT_ID into NL_CONTENT from CONTENT WHERE ROWNUM = 1;

通过ROWID访问速度非常快。因此,除了可以将两个查询合并为一个之外,我看不到任何节省时间的潜力:

select NL_CONTENT_ID, EVENT_STATUS_CODE into NL_CONTENT, STATUS from CONTENT
where ROWID = Row_id;

请注意,我更改了 WHERE 子句:它是 ROWID 而不是 ROWNUM。

顺便说一句:行:

REGDS := SYS.CHNF$_REG_INFO ('SP_EVENT_GENERATE', qosflags, 0,0,0);

应该是:

REGDS := SYS.CHNF$_REG_INFO ('TABLES_CHANGED_CHNT', qosflags, 0,0,0);

或者您的存储过程应重命名为 SP_EVENT_GENERATE

In the registration block (between DBMS_CHANGE_NOTIFICATION.NEW_REG_START and DBMS_CHANGE_NOTIFICATION.REG_END), you need to execute a simple query on the table CONTENT to register your interest in changes to this table, e.g.:

SELECT select NL_CONTENT_ID into NL_CONTENT from CONTENT WHERE ROWNUM = 1;

Access by ROWID is very fast. So I don't see any potential for saving time except that you can combine the two queries into one:

select NL_CONTENT_ID, EVENT_STATUS_CODE into NL_CONTENT, STATUS from CONTENT
where ROWID = Row_id;

Note that I have changed the WHERE clause: it's ROWID not ROWNUM.

BTW: The line:

REGDS := SYS.CHNF$_REG_INFO ('SP_EVENT_GENERATE', qosflags, 0,0,0);

shoud probably be:

REGDS := SYS.CHNF$_REG_INFO ('TABLES_CHANGED_CHNT', qosflags, 0,0,0);

or your stored procedure should be renamed to SP_EVENT_GENERATE.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文