условно добавить атрибут xmlattribute в элемент xmlelement с Oracle SQL - PullRequest
0 голосов
/ 07 июня 2018

Я имею дело с системой, которая принимает данные в формате XML.Например, есть поле с именем «col1», и в этом поле есть значение «мир».Система интерпретирует <col1 />, <col1></col1> и отсутствующий элемент <col1> как "без изменений" в поле, называемом col1.(Это хорошо, потому что, если бы мы создавали новые данные, «без изменений» означало бы принять любое значение по умолчанию.) Если мне нужно удалить все, что находится в поле, элемент <col1> должен иметь xsi:nil атрибут со значением true.

Итак, когда я извлекаю данные из одного экземпляра системы для загрузки в другой экземпляр (вставка с помощью SQL не вариант), мне нужно условно добавитьxsi:nil="true" атрибут XML, возвращенный из запроса в Oracle 12c, чтобы явно указать, что значение элемента равно нулю.(Всегда добавление xsi:nil со значением true или false, в зависимости от ситуации, может работать, но это нежелательно, поскольку это нарушает соглашение и увеличивает размер файла.)

Можно настроить тестовый примерследующим образом.

create table table1 (id number(10), col1 varchar2(5));
insert into table1 values (1,'hello');
insert into table1 values (2,null);
commit;

Я хочу получить это обратно из запроса:

<outer><ID>1</ID><COL1>hello</COL1></outer>
<outer><ID>2</ID><COL1 xsi:nil="true"></COL1></outer>

Этот запрос выдает ошибку.

select
    xmlelement("outer",
        xmlforest(id),
        (case col1
            when null then xmlelement(COL1, xmlattributes('xsi:nil="true"'), null)
            else xmlforest(col1)
            end)
    )
from table1
;

Есть ли некоторыеДругой способ условно включить вызов xmlattributes или другой способ получить желаемый результат?

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Вы можете использовать NVL2, чтобы сделать его немного менее многословным:

Запрос 1 :

SELECT  XMLELEMENT(
          "outer",
          XMLFOREST( id ),
          XMLELEMENT( col1, xmlattributes( NVL2(col1,NULL,'true') as "xsi:nil"), col1 )
        ).getClobVal() AS element
FROM    table1;

Результат :

OUTPUT
-----------------------------------------------------
<outer><ID>1</ID><COL1>hello</COL1></outer>
<outer><ID>2</ID><COL1 xsi:nil="true"></COL1></outer>

Запрос 2 : Вы также можете использовать XMLFOREST для генерации элементов и затем APPENDCHILDXML для добавления отсутствующего элемента (включая пространства имен, оставленные в качестве упражнения для OP):

SELECT  APPENDCHILDXML( 
          XMLELEMENT( "outer", XMLFOREST( id, col1 ) ),
          '/outer',
          NVL2( col1, NULL, XMLTYPE('<COL1 nil="true"></COL1>') )
        ).getClobVal() AS element
FROM    table1;

Результат :

OUTPUT
-------------------------------------------
<outer><ID>1</ID><COL1>hello</COL1></outer>
<outer><ID>2</ID><COL1 nil="true"/></outer>
0 голосов
/ 07 июня 2018

Я обнаружил, что этот запрос работает, но он более многословен, чем хотелось бы.

select
    xmlelement("outer",
        xmlforest(id),
        xmlelement(col1,xmlattributes(case when col1 is null then 'true' else null end as "xsi:nil"), col1)
        ).getClobVal()
from table1
;
...