Oracle XMLType Generation mit null Werten von Trigger zur erweiterten Warteschlange
Frage
Guter Tag.
Ich habe mit Oracle Advanced Queues arbeitet ein Messaging-System zu schaffen, dass wir bestimmen können, wann neue Zeilen in die databse übergeben werden, wenn Updates auftreten und wenn Löschungen auftreten.
Ich bin eine einzelne Verbraucher Warteschlange und unter Verwendung von Korrelationen zu steuern, welche Daten zu bestimmten Zeiten gesucht und meine Nutzlast von xmltype.
die XML zu generieren, ich war ursprünglich eine xmlsequence mit der Nachricht zu erzeugen, wie unten.
<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>
Allerdings hat es zu meiner Aufmerksamkeit gekommen, dass xmlsequence Blätter aus Null-Elementen, die nicht ideal ist, als wenn es Zeit für die Nachrichten am anderen Ende abgeholt werden, können sie nicht einfach auf Datenfeld abgebildet werden. Um zu versuchen und zu arbeiten, um dies, ich habe versucht, die Verwendung von DBMS_XMLGEN innerhalb meines Trigger zu verwenden, da sie die Handhabung von NULL-Werten in genau die Art und Weise ermöglicht, ich mag es behandelt.
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);
Das Problem bei diesem Ansatz ist, dass es eine Ausnahme zu generieren, wie es auf dem gleichen Tisch zu bedienen versucht, dass der Auslöser von ausgeführt wurde.
ORA-04091: table RIT.LOCATIONS is mutating, trigger/function may not see it
So zog ich auf zu versuchen, die neue und alte Objekte zu verwenden, um die Daten raus und legen Sie es in dem Kontext, aber ich bin mit, um ein paar Schluckauf mit den Werten, die null sind, da sie Chaos spielen mit meinen sie in das Query-String verketten.
...
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;
Also meine Frage ist: Wie kann ich mich über diese Lösung, so dass ich meine leere Elemente für meinen Typen xml sehe
Ich bin auch offen für Vorschläge auf dem Weg auf, wie es zu lösen und wird wieder für jegliche Klärung Anfragen zu überprüfen.
Lösung
eine einfache Zeile in XML generieren Sie xmlelement
verwenden können:
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>