Оракул xmltype генерация с нулевыми значениями от триггера до расширенной очереди

StackOverflow https://stackoverflow.com/questions/4467080

  •  11-10-2019
  •  | 
  •  

Вопрос

Добрый день.

Я работал с Oracle Advanced Ofeues, чтобы создать систему обмена сообщениями, которую мы можем использовать, чтобы определить, когда новые линии передаются в базу данных, когда происходят обновления и когда происходят удаления.

Я использую одну очередь потребителей и использую корреляции для контроля того, какие данные ищут в определенное время, и моя полезная нагрузка имеет Xmltype.

Чтобы сгенерировать XML, я изначально использовал XML -посылку для генерации сообщения, как показано ниже.

<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>

Тем не менее, мое внимание привлекло к тому, что 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

Поэтому я перешел к попытке использовать новые и старые объекты, чтобы вывести данные и поместить их в контекст, но я прибегаю к нескольким икотам с нулевыми ценностями, так как они разрушают с моими сознаниями их в строке запроса.

...
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>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top