DBMS_CHANGE_NOTIFICATION 和 NEW_REG_START
我阅读了一些如何使用 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;
我需要写什么而不是
SELECT CUSTID INTO cust_id FROM TB_CUSTOMER WHERE ROWNUM=1;
有没有办法检索更改的对象,而不是仅检索 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;
What do I need to write instead of
SELECT CUSTID INTO cust_id FROM TB_CUSTOMER WHERE ROWNUM=1;
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在注册块中(
DBMS_CHANGE_NOTIFICATION.NEW_REG_START
和DBMS_CHANGE_NOTIFICATION.REG_END
之间),您需要对表 CONTENT 执行一个简单的查询来注册您对该表的更改的兴趣,例如:通过ROWID访问速度非常快。因此,除了可以将两个查询合并为一个之外,我看不到任何节省时间的潜力:
请注意,我更改了 WHERE 子句:它是 ROWID 而不是 ROWNUM。
顺便说一句:行:
应该是:
或者您的存储过程应重命名为
SP_EVENT_GENERATE
。In the registration block (between
DBMS_CHANGE_NOTIFICATION.NEW_REG_START
andDBMS_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.: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:
Note that I have changed the WHERE clause: it's ROWID not ROWNUM.
BTW: The line:
shoud probably be:
or your stored procedure should be renamed to
SP_EVENT_GENERATE
.