使用Oracle SQL

时间:2018-06-06 21:30:31

标签: oracle oracle12c

我正在处理一个接受XML格式的数据加载的系统。例如,有一个名为&#34; col1&#34;的字段,该字段的值为&#34; world&#34;在里面。系统将<col1 /><col1></col1>和缺少的<col1>元素解释为&#34;无变化&#34;到名为col1的字段。 (这很好,因为,如果我们创建新数据,&#34;没有更改&#34;将意味着接受默认值。)如果我需要删除字段中的任何内容,<col1>元素需要具有xsi:nil属性,其值为true

因此,当我从系统的一个实例中提取数据以加载到另一个实例时(使用SQL插入不是一个选项),我需要有条件地将xsi:nil="true"属性添加到从Oracle 12c中的一个查询,用于显式指示该元素的值为null。 (根据需要,始终添加值xsi:niltrue的{​​{1}}可能有效但不可取,因为它会破坏约定和膨胀文件大小。)

测试用例可以设置如下。

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 ; 调用,或其他方式来获取我想要的输出?

2 个答案:

答案 0 :(得分:1)

我发现这个查询有效,但它比我想要的更冗长。

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
;

答案 1 :(得分:1)

您可以使用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>