如何在Oracle中将列值作为xml元素名称

时间:2015-11-04 11:32:23

标签: sql xml oracle oracle11g

我有两张桌子。我正在尝试加入它们并在oracle中使用SQL / XML(SQLX)来准备XML。这里的问题是XMLELEMENT函数正在为元素名称取硬编码值,但我希望将这些名称作为列数据。有可能吗?

create table PRODUCTEDIT
(
PRODUCTEDIT_NUM NUMBER(12) primary key,  
API_NAME        VARCHAR2(255)
);

create table PRODUCTEDITPARAMETER
(
PRODUCTEDIT_NUM NUMBER(12) not null,
PARAMETER_SEQ   NUMBER(9) not null,
PARAMETER_VALUE VARCHAR2(4000),
CONSTRAINT fk_producteditparameter
FOREIGN KEY (PRODUCTEDIT_NUM )
REFERENCES PRODUCTEDIT(PRODUCTEDIT_NUM )
);

第一张表中有2条记录。

PRODUCTEDIT_NUM         Api_Name
1                       ModifyProd
2                       CreateProd

第二张表中的记录:

PRODUCTEDIT_NUM       PARAMETER_SEQ     PARAMETER_VALUE 
1                        1                    10
1                        2                    Data
1                        3                    1
1                        4                    Data1
1                        5                    1
2                        1                    11
2                        2                    Voice
2                        3                    1

现在我想得到如下所示的XMLOUTPUT:

<?xml version='1.0'?>
<ModifyProd>
    <1>10</1>
    <2>Data</2>
    <3>1</3>
    <4>Data1</4>
    <5>1</5>
</ModifyProd>
<CreateProd>
    <1>11</1>
    <2>Voice</2>
    <3>1</3>    
</CreateProd>

在上面的XML中,我们有来自表数据的XMLELEMENT名称(ModifyProd,CreateProd,1,2 e.t.c)。我无法通过在oracle中使用SQLXML来实现这一点。

我在下面试过,但似乎没有工作。 XMLELEMENT没有按照我传递的方式获取价值。

SELECT XMLROOT(
      XMLELEMENT(d.api_name,
             (SELECT XMLAGG(
                       XMLELEMENT(e.parameter_seq,e.parameter_value                            
                       )
                     )
              FROM   producteditparameter e
              WHERE  e.productedit_num = d.productedit_num
             ) 

         ),version '1.0', standalone yes
       )

FROM   productedit d

2 个答案:

答案 0 :(得分:2)

我认为你正在寻找这个:

WITH t AS 
    (SELECT 'foo' AS ELEMENT_NAME, 'bar' AS ELEMENT_CONTENT FROM dual)
SELECT XMLELEMENT(EVALNAME ELEMENT_NAME, ELEMENT_CONTENT)
FROM t;

<foo>bar</foo>

根据其他输入进行更新

您的结果不是格式良好的XML。 XML文档必须只有一个根元素。所以,要么你要求几个XML文档,那么你可以这样做:

SELECT 
    XMLELEMENT(
        EVALNAME Api_Name, 
        XMLAGG(XMLELEMENT(EVALNAME parameter_seq, e.parameter_value) ORDER BY parameter_seq)
    ) AS xml_result
FROM PRODUCTEDITPARAMETER e
    JOIN PRODUCTEDIT d USING (productedit_num)
GROUP BY productedit_num, Api_Name;

<ModifyProd><1>10</1><2>Data</2><3>1</3><4>Data1</4><5>1</5></ModifyProd>
<CreateProd><1>11</1><2>Voice</2><3>1</3></CreateProd>

或者如果您需要单个XML,则必须将其包含在另一个元素中,例如:

SELECT 
    XMLELEMENT("Products",  
        XMLAGG(
            XMLELEMENT(
                EVALNAME Api_Name, 
                XMLAGG(XMLELEMENT(EVALNAME parameter_seq, e.parameter_value) ORDER BY parameter_seq)
            )
        ) 
    ) AS xml_result
FROM PRODUCTEDITPARAMETER e
    JOIN PRODUCTEDIT d USING (productedit_num)
GROUP BY productedit_num, Api_Name;

<Products><ModifyProd><1>10</1><2>Data</2><3>1</3><4>Data1</4><5>1</5></ModifyProd><CreateProd><1>11</1><2>Voice</2><3>1</3></CreateProd></Products>

答案 1 :(得分:0)

如果我明白你想要的话,另一个解决方案是:

WITH t AS
       (    SELECT LEVEL col1, 'test' || LEVEL col2
              FROM DUAL
        CONNECT BY LEVEL < 10)
SELECT XMLSERIALIZE (DOCUMENT (xmltype (CURSOR (SELECT col1, col2 FROM t))) INDENT SIZE = 0)
  FROM DUAL;

然后,您可以根据需要使用XSD转换输出。

希望有所帮助