Sql DBMS更改通知和新注册启动

Sql DBMS更改通知和新注册启动,sql,oracle,plsql,triggers,Sql,Oracle,Plsql,Triggers,我读了一些关于如何使用DBMS_CHANGE_通知进行异步触发器的示例 仅当STATUS=1709003时,我需要为表内容创建触发器 因此,我创建了以下过程: CREATE OR REPLACE PROCEDURE tables_changed_chnt(ntfnds IN SYS.chnf$_desc) IS l_table_name VARCHAR2(60); l_event_type NUMBER; l_numtables

我读了一些关于如何使用DBMS_CHANGE_通知进行异步触发器的示例

仅当STATUS=1709003时,我需要为表内容创建触发器

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

  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;
  • 我需要写什么,而不是
    从TB_CUSTOMER中选择CUSTID到cust_id,其中ROWNUM=1

  • 有没有办法检索已更改的对象,而只检索rowid,因为这样可以节省我在第一个过程中查找的时间

  • 在注册块中(在
    DBMS\u CHANGE\u NOTIFICATION.NEW\u REG\u START
    DBMS\u CHANGE\u NOTIFICATION.REG\u END
    之间),您需要对表内容执行简单查询,以注册对此表所做更改的兴趣,例如:

    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\u EVENT\u GENERATE

    为什么触发器需要是aysnc?当状态更新时,将消息排入队列或将行写入另一个表的普通触发器能否更简单地解决您的问题?因为我的触发器调用web服务。我没有写完整的代码。调用它可能需要20秒,这可能会卡住我的应用程序