我正在尝试检测表格上的插入,更新或删除。我知道我不能使用QRCN,所以我试图使用OCN。我想要实现的是......当检测到插入/更新时,当检测到删除时调用“callback_iu”调用'callback_d'。
DECLARE
qosflags NUMBER;
reginfo_iu cq_notification$_reg_info;
reginfo_d cq_notification$_reg_info;
regid_iu NUMBER;
regid_d NUMBER;
v_cursor SYS_REFCURSOR;
opfilter_iu NUMBER;
opfilter_d NUMBER;
BEGIN
qosflags := DBMS_CQ_NOTIFICATION.QOS_ROWIDS;
opfilter_iu := DBMS_CQ_NOTIFICATION.INSERTOP + DBMS_CQ_NOTIFICATION.UPDATEOP;
opfilter_d := DBMS_CQ_NOTIFICATION.DELETEOP;
reginfo_iu := cq_notification$_reg_info('callback_iu', qosflags,0, opfilter_iu, 0);
regid_iu := DBMS_CQ_NOTIFICATION.NEW_REG_START(reginfo_iu);
OPEN v_cursor FOR
SELECT DBMS_CQ_NOTIFICATION.QOS_ROWIDS, department_id, department_name, manager_id, location_id
FROM HR.departments
CLOSE v_cursor;
DBMS_CQ_NOTIFICATION.REG_END;
reginfo_d := cq_notification$_reg_info('callback_d', qosflags,0, opfilter_d, 0);
regid_d := DBMS_CQ_NOTIFICATION.NEW_REG_START(reginfo_d);
OPEN v_cursor FOR
SELECT DBMS_CQ_NOTIFICATION.QOS_ROWIDS, department_id, department_name, manager_id, location_id
FROM HR.departments
CLOSE v_cursor;
DBMS_CQ_NOTIFICATION.REG_END;
END;
我知道我可以使用QRCN获得ROWID和“real_id”:
CREATE OR REPLACE PROCEDURE chnf_callback
(ntfnds IN CQ_NOTIFICATION$_DESCRIPTOR)
IS
event_type NUMBER;
tbname VARCHAR2(60);
numtables NUMBER;
operation_type NUMBER;
numrows NUMBER;
row_id VARCHAR2(2000);
numqueries NUMBER;
qid NUMBER;
real_id NUMBER;
BEGIN
event_type := ntfnds.event_type;
numqueries :=0;
IF (event_type = DBMS_CQ_NOTIFICATION.EVENT_QUERYCHANGE) THEN
numqueries := ntfnds.query_desc_array.count;
FOR i in 1..numqueries LOOP
qid := ntfnds.QUERY_DESC_ARRAY(i).queryid;
numtables := 0;
numtables := ntfnds.QUERY_DESC_ARRAY(i).table_desc_array.count;
FOR j IN 1..numtables LOOP
tbname := ntfnds.QUERY_DESC_ARRAY(i).table_desc_array(j).table_name;
operation_type := ntfnds.QUERY_DESC_ARRAY(i).table_desc_array(j).Opflags;
IF (bitand(operation_type, DBMS_CQ_NOTIFICATION.ALL_ROWS) = 0)
THEN
numrows := ntfnds.query_desc_array(i).table_desc_array(j).numrows;
ELSE
numrows :=0; /* ROWID INFO NOT AVAILABLE */
END IF;
/* The body of the loop is not executed when numrows is ZERO */
FOR k IN 1..numrows LOOP
Row_id := ntfnds.query_desc_array(i).table_desc_array(j).row_desc_array(k).row_id;
select department_id into real_id from hr.departments where rowid = Row_id;
-->INSERT IN NFROWCHANGES<--
INSERT INTO nfrowchanges VALUES(qid, tbname, Row_id, real_id);
END LOOP; /* loop over rows */
END LOOP; /* loop over tables */
END LOOP; /* loop over queries */
END IF;
COMMIT;
END;
我也知道我可以检查 operation_type 以了解它是Insert(2)还是Update(4),但我无法使用Delete。
那么如何使用OCN获取ROWID和“real_id”并将其传递给回调中的UTL_HTTP.REQ?
DECLARE req UTL_HTTP.REQ;
resp UTL_HTTP.RESP;
BEGIN
req := utl_http.begin_request(
url => 'localhost:3000/departments/'||real_id,
method => 'GET'
);
resp := utl_http.get_response(r => req);
utl_http.end_response(r => resp);
END;
答案 0 :(得分:1)
我仍然不知道如何使用OCN,在这个解决方案中我使用的是QRCN。由于删除行时无法获取row_id,因此我创建了一个名为“Active”的新列,而不是删除行,所以当我想“删除”一行时,我将“Active”从“Yes”更改为“No” ”。
所以这是使用UTL_HTTP从Inserted / Updated /“Deleted”行发送“real_id”的解决方案。
匿名阻止:
DECLARE
l_reginfo CQ_NOTIFICATION$_REG_INFO;
l_cursor SYS_REFCURSOR;
l_regid NUMBER;
qosflags NUMBER;
BEGIN
qosflags := DBMS_CQ_NOTIFICATION.QOS_QUERY + DBMS_CQ_NOTIFICATION.QOS_ROWIDS;
l_reginfo := cq_notification$_reg_info ('query_callback', qosflags, 0, 0, 0);
l_regid := dbms_cq_notification.new_reg_start(l_reginfo);
OPEN l_cursor FOR
SELECT
id,
city_name,
country_name,
votes,
active
FROM hr.jsao_super_cities
WHERE active = 'YES';
CLOSE l_cursor;
dbms_cq_notification.reg_end;
END;
/
回调:
CREATE OR REPLACE PROCEDURE query_callback
(ntfnds IN CQ_NOTIFICATION$_DESCRIPTOR)
IS
event_type NUMBER;
numtables NUMBER;
operation_type NUMBER;
numrows NUMBER;
row_id VARCHAR2(2000);
is_active VARCHAR2(20);
numqueries NUMBER;
real_id NUMBER;
l_req UTL_HTTP.REQ;
l_resp UTL_HTTP.RESP;
BEGIN
event_type := ntfnds.event_type;
numqueries :=0;
IF (event_type = DBMS_CQ_NOTIFICATION.EVENT_QUERYCHANGE) THEN
numqueries := ntfnds.query_desc_array.count;
FOR i in 1..numqueries LOOP
numtables := 0;
numtables := ntfnds.QUERY_DESC_ARRAY(i).table_desc_array.count;
FOR j IN 1..numtables LOOP
operation_type := ntfnds.QUERY_DESC_ARRAY(i).table_desc_array(j).Opflags;
IF (bitand(operation_type, DBMS_CQ_NOTIFICATION.ALL_ROWS) = 0)
THEN
numrows := ntfnds.query_desc_array(i).table_desc_array(j).numrows;
ELSE
numrows :=0;
END IF;
FOR k IN 1..numrows LOOP
Row_id := ntfnds.query_desc_array(i).table_desc_array(j).row_desc_array(k).row_id;
--getting "real_id"
select id into real_id from hr.jsao_super_cities where rowid = Row_id;
-- 2 = insert
IF(operation_type = 2) THEN
l_req := utl_http.begin_request(
url => 'localhost:3000/city/'||real_id,
method => 'GET'
);
l_resp := utl_http.get_response(r => l_req);
utl_http.end_response(r => l_resp);
-- 4 = update
ELSIF (operation_type = 4) THEN
select active into is_active from hr.jsao_super_cities where id = real_id;
IF (is_active = 'YES') THEN
l_req := utl_http.begin_request(
url => 'localhost:3000/city/'||real_id,
method => 'GET'
);
l_resp := utl_http.get_response(r => l_req);
utl_http.end_response(r => l_resp);
ELSIF (is_active = 'NO') THEN
l_req := utl_http.begin_request(
url => 'localhost:3000/delete/'||real_id,
method => 'GET'
);
l_resp := utl_http.get_response(r => l_req);
utl_http.end_response(r => l_resp);
END IF;
END IF;
END LOOP; /* loop over rows */
END LOOP; /* loop over tables */
END LOOP; /* loop over queries */
END IF;
END query_callback;
/
我希望这可以帮助别人。