2

こんにちは。

私はOracleAdvancedQueuesと協力して、新しい行がいつデータベースに渡されるか、いつ更新が行われるか、いつ削除が行われるかを判別するために使用できるメッセージング・システムを作成してきました。

私は単一のコンシューマーキューを使用しており、相関関係を使用して特定の時間に検索されるデータを制御しており、ペイロードはxmltypeです。

xmlを生成するために、私はもともとxmlsequenceを使用して以下のようなメッセージを生成していました。

<MESSAGE>
<LOCATIONS>
  <LOCATION_ID>9999</LOCATION_ID>
  <LOC_TYPE>S</LOC_TYPE>
  <NAME>Test Location</NAME>
  <RETAILER_UNIT_CODE>T&amp;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>

ただし、xmlsequenceがnull要素を除外していることに気付きました。これは、メッセージがもう一方の端で取得されるときに、データフィールドに簡単にマッピングできないため、理想的ではありません。これを回避するために、トリガー内でDBMS_XMLGENを使用することを試みました。これにより、nullを希望どおりに処理できるようになります。

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タイプの空の要素を見ることができるようにこれを解決するにはどうすればよいですか?

また、解決方法についての提案も受け付けており、説明のリクエストがないか確認します。

4

1 に答える 1

2

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>
于 2010-12-17T11:43:44.420 に答える