こんにちは。
私はOracleAdvancedQueuesと協力して、新しい行がいつデータベースに渡されるか、いつ更新が行われるか、いつ削除が行われるかを判別するために使用できるメッセージング・システムを作成してきました。
私は単一のコンシューマーキューを使用しており、相関関係を使用して特定の時間に検索されるデータを制御しており、ペイロードはxmltypeです。
xmlを生成するために、私はもともとxmlsequenceを使用して以下のようなメッセージを生成していました。
<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>
ただし、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タイプの空の要素を見ることができるようにこれを解決するにはどうすればよいですか?
また、解決方法についての提案も受け付けており、説明のリクエストがないか確認します。