トリガーから高度なキューまでのnull値を持つOracle xmltype生成
質問
こんにちは。
Oracle Advanced Keuesと協力して、新しい行がデータベースに渡される時期、更新が発生したとき、削除が発生する時期を判断するために使用できるメッセージングシステムを作成しています。
私は単一の消費者キューを使用しており、相関を使用して特定の時間にどのデータが探しているかを制御し、私のペイロードはXMLTYPEです。
XMLを生成するために、私はもともとXMLシーケンスを使用して、以下のようにメッセージを生成していました。
<MESSAGE>
<LOCATIONS>
<LOCATION_ID>9999</LOCATION_ID>
<LOC_TYPE>S</LOC_TYPE>
<NAME>Test Location</NAME>
<RETAILER_UNIT_CODE>T&L</RETAILER_UNIT_CODE>
<REGION_CODE>SA</REGION_CODE>
<DELETE_FLAG>N</DELETE_FLAG>
<EXTERNAL_WHSE_FLAG>N</EXTERNAL_WHSE_FLAG>
<CREATED_BY>SYSADMIN</CREATED_BY>
<CREATED_DATE>04/MAR/08</CREATED_DATE>
<STATE_CODE>SA</STATE_CODE>
<ADDRESS>223 Road Ridsonville</ADDRESS>
<POSTCODE>1234</POSTCODE>
<PHONE_NUM>08 </PHONE_NUM>
<LAST_MODIFIED_BY>SYSADMIN</LAST_MODIFIED_BY>
<LAST_MODIFIED_DATE>21/APR/09</LAST_MODIFIED_DATE>
<POS_CODE>TRANS</POS_CODE>
<SOP_FLAG>N</SOP_FLAG>
</LOCATIONS>
</MESSAGE>
ただし、XMLシーケンスがヌル要素を除外していることに注意してください。これは理想的ではありません。メッセージを反対側でピックアップする時が来たとき、データフィールドに簡単にマッピングできないからです。これを回避するために、トリガー内でdbms_xmlgenの使用を採用しようとしました。これにより、ヌルが処理されたい方法でヌルを処理できるようにしました。
ctx := dbms_xmlgen.newContext('SELECT * FROM LOCATIONS WHERE LOCATION_ID = ' || :new.LOCATION_ID);
dbms_xmlgen.setrowsettag(ctx, 'MESSAGE');
dbms_xmlgen.setrowtag(ctx, 'LOCATIONS');
dbms_xmlgen.setnullhandling(ctx, dbms_xmlgen.EMPTY_TAG);
l_xml:=dbms_xmlgen.getxmltype(ctx);
このアプローチの問題は、トリガーが実行されたのと同じテーブルで動作しようとしているため、例外を生成することです。
ORA-04091: table RIT.LOCATIONS is mutating, trigger/function may not see it
だから私は新しいオブジェクトと古いオブジェクトを使用してデータを出してコンテキストに配置しようとすることに移りましたが、私の連結との大混乱を演じているので、nullの値でいくつかのしゃっくりに走っていますそれらはクエリ文字列に入ります。
...
REFERENCING NEW AS NEW OLD AS OLD
for each row
DECLARE
l_xml xmltype;
ctx dbms_xmlgen.ctxHandle;
begin
ctx := dbms_xmlgen.newContext('SELECT '||:new.id||'as id, '||:new.nullfield||' as nullfield from dual');
dbms_xmlgen.setrowsettag(ctx, 'MESSAGE');
dbms_xmlgen.setrowtag(ctx, 'INT_CREDIT_CLAIMS');
dbms_xmlgen.setnullhandling(ctx, dbms_xmlgen.EMPTY_TAG);
l_xml:=dbms_xmlgen.getxmltype(ctx);
...
end;
だから私の質問は、XMLタイプの空の要素を見ることができるように、これを解決するにはどうすればよいですか?
また、それを解決する方法についての途中で提案を受け入れており、明確化のリクエストを確認します。
解決
XMLで簡単な行を生成するには、使用できます xmlelement
:
SQL> CREATE TABLE emp AS SELECT * FROM scott.emp;
Table created
SQL> CREATE TABLE message (xml XMLTYPE);
Table created
SQL> CREATE OR REPLACE TRIGGER trg_b4_emp
2 BEFORE UPDATE ON emp
3 FOR EACH ROW
4 BEGIN
5 INSERT INTO message VALUES (
6 xmlelement("MESSAGE",
7 xmlelement("EMP",
8 xmlelement("empno", :new.empno),
9 xmlelement("comm", :new.comm)
10 )
11 )
12 );
13 END;
14 /
SQL> update emp set comm=NULL;
14 rows updated
SQL> select * from message where rownum = 1;
XML
----------------------------------------------------------------
<MESSAGE><EMP><empno>7369</empno><comm></comm></EMP></MESSAGE>
所属していません StackOverflow