从XMLTYPE

时间:2018-08-20 01:01:02

标签: oracle xmltype dynamic-columns xmltable

我想使用 Oracle SQL XML 文件中选择数据。

这是我的 XML 文件:

<worksheet>
    <sheetData>
        <row>
            <column>
                <value>0</value>
            </column>
            <column>
                <value>1</value>
            </column>
            <column>
                <value>2</value>
            </column>
        </row>
        <row>
            <column>
                <value>3</value>
            </column>
            <column>
                <value>4</value>
            </column>
            <column>
                <value>5</value>
            </column>
        </row>
        <row>
            <column>
                <value>6</value>
            </column>
            <column>
                <value>7</value>
            </column>
            <column>
                <value>8</value>
            </column>
        </row>
    </sheetData>
</worksheet>

以下代码是我用来提取 XML (在SQL查询中已缩小)的 SQL

SELECT
    *
FROM
    XMLTABLE(
        'for $i in worksheet/sheetData/row return $i'
        PASSING XMLTYPE('<worksheet><sheetData><row><column><value>0</value></column><column><value>1</value></column><column><value>2</value></column></row><row><column><value>3</value></column><column><value>4</value></column><column><value>5</value></column></row><row><column><value>6</value></column><column><value>7</value></column><column><value>8</value></column></row></sheetData></worksheet>')
        COLUMNS
            column1  CLOB PATH 'column[1]/value',
            column2  CLOB PATH 'column[2]/value'
    ) xml;

这是输出:

---------------------
| COLUMN1 | COLUMN2 |
|---------|---------|
| 0       | 1       |
| 3       | 4       |
| 6       | 7       |
---------------------

您会看到输出中缺少<column>的第三个<row>子项,但是如果我将column3 CLOB PATH 'column[3]/value'添加到COLUMNS属性中,它将出现。

我的问题是XML可以有任意数量的<column>标签,并且由于我从一开始就不知道计数,所以无法定义固定的解决方案。

您能告诉我哪种修改才能使我的查询适用于多个<column>标签吗?还是哪个查询应该输出动态数字<column>

1 个答案:

答案 0 :(得分:2)

简便方法

预定义的冗余列数。

SELECT
    *
FROM
    XMLTABLE(
        '/worksheet/sheetData/row'
        PASSING XMLTYPE('<worksheet><sheetData><row><column><value>0</value></column><column><value>1</value></column><column><value>2</value></column></row><row><column><value>3</value></column><column><value>4</value></column><column><value>5</value></column></row><row><column><value>6</value></column><column><value>7</value></column><column><value>8</value></column></row></sheetData></worksheet>')
        COLUMNS
            column_cnt number path 'count(column)',
            column1  varchar2(4000) PATH 'column[1]/value',
            column2  varchar2(4000) PATH 'column[2]/value',
          --etc. ...
            column10   varchar2(4000) path 'column[10]/value'
    ) xml;

透视结果

SELECT
    row_nr,
    col_nr,
    col_value
FROM
    XMLTABLE(
        '/worksheet/sheetData/row'
        PASSING XMLTYPE('<worksheet><sheetData><row><column><value>0</value></column><column><value>1</value></column><column><value>2</value></column></row><row><column><value>3</value></column><column><value>4</value></column><column><value>5</value></column></row><row><column><value>6</value></column><column><value>7</value></column><column><value>8</value></column></row></sheetData></worksheet>')
        COLUMNS
                    columns_xml   xmltype path '.',
                    row_nr  FOR ORDINALITY 
    ) xml
    ,xmltable('row/column' passing columns_xml 
             columns 
                    col_nr for ordinality,
                    col_value varchar2(10) path './value/text()') 

核心方法。 始终可以使用管道表功能。

1)查找最大列数
2)产生动态类型
3)填充动态类型
4)两天后,享受用pl sql编写的最复杂的代码:)

以下管道功能的好例子。这并不是您真正需要的,但您可以在此基础上构建

Return dynamic result set from sys_refcursor