Sql DBMS更改通知和新注册启动
我读了一些关于如何使用DBMS_CHANGE_通知进行异步触发器的示例 仅当STATUS=1709003时,我需要为表内容创建触发器 因此,我创建了以下过程: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
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代码>
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秒,这可能会卡住我的应用程序