You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PL/SQL生成指定XML的技术问题咨询

Oracle XML生成相关问题解答

目标XML结构

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Form1>
<ContentForm>
<SectionI>
<Date>13/01/2023</Date>
</SectionI>
<SectionII>
<Type>C</Type>
<ID>1809</ID>
<RIC></RIC>
<UEN>019</UEN>
<Name>Limited</Name>
</SectionII>
</ContentForm>
</Form1>

现有查询语句

合并节点查询

SELECT
    xmlconcat
    (   
        XMLELEMENT
        ("SectionI",XMLELEMENT("Date",SYSDATE)
        )
    ,
        XMLELEMENT
        ("SectionII",
            XMLELEMENT("Type",'C'),
            XMLELEMENT("ID",'1809'),
            XMLELEMENT("RIC",NULL),
            XMLELEMENT("UEN",'019'),
            XMLELEMENT("Name",'Limited')
        ) 
    )
    from dual

生成XML声明尝试

Select 
XMLELEMENT("?xml",xmlattributes('1.0' as  "Version",'UTF-8' as  "encoding",'no' as  "standalone"))
from dual

问题解答

1. 使用xmlconcat合并不同节点是否正确,有无其他实现方式?

用xmlconcat合并节点是合法的,但更贴合XML层级结构的写法是直接嵌套XMLELEMENT,将需要合并的节点作为父元素的子节点参数传入,无需额外调用xmlconcat。比如把SectionI和SectionII直接放在ContentForm的XMLELEMENT参数中,自然形成层级合并,代码更简洁直观。

2. 如何生成XML声明标签并将其与主XML拼接?

Oracle的XMLELEMENT无法直接生成标准XML声明(因为?xml不是合法的XML元素名),推荐用XMLSERIALIZE函数,它可以将XMLType对象序列化为带声明的字符串,同时支持指定版本、编码、独立属性和格式化:

SELECT XMLSERIALIZE(DOCUMENT 
    XMLELEMENT("Form1", 
        XMLELEMENT("ContentForm", 
            XMLELEMENT("SectionI", XMLELEMENT("Date", TO_CHAR(SYSDATE, 'DD/MM/YYYY'))),
            XMLELEMENT("SectionII", 
                XMLELEMENT("Type", 'C'),
                XMLELEMENT("ID", '1809'),
                XMLELEMENT("RIC", NULL),
                XMLELEMENT("UEN", '019'),
                XMLELEMENT("Name", 'Limited')
            )
        )
    ) AS CLOB INDENT SIZE=2 VERSION '1.0' ENCODING 'UTF-8' STANDALONE NO)
FROM dual;

如果手动拼接,可将声明字符串与XMLType.getStringVal()的结果拼接,但这种方式容易出现编码问题,不如XMLSERIALIZE规范。

3. 能否将生成的XML存入PL/SQL的OUT变量,若可以该如何操作?

可以,支持将XML存储为XMLType或CLOB类型的OUT变量,示例如下:

存储为XMLType类型

CREATE OR REPLACE PROCEDURE generate_form_xml(p_out_xml OUT XMLType) AS
BEGIN
    SELECT XMLELEMENT("Form1", 
        XMLELEMENT("ContentForm", 
            XMLELEMENT("SectionI", XMLELEMENT("Date", TO_CHAR(SYSDATE, 'DD/MM/YYYY'))),
            XMLELEMENT("SectionII", 
                XMLELEMENT("Type", 'C'),
                XMLELEMENT("ID", '1809'),
                XMLELEMENT("RIC", NULL),
                XMLELEMENT("UEN", '019'),
                XMLELEMENT("Name", 'Limited')
            )
        )
    ) INTO p_out_xml FROM dual;
END;
/

存储为带声明的CLOB类型

CREATE OR REPLACE PROCEDURE generate_form_clob(p_out_clob OUT CLOB) AS
BEGIN
    SELECT XMLSERIALIZE(DOCUMENT 
        XMLELEMENT("Form1", 
            XMLELEMENT("ContentForm", 
                XMLELEMENT("SectionI", XMLELEMENT("Date", TO_CHAR(SYSDATE, 'DD/MM/YYYY'))),
                XMLELEMENT("SectionII", 
                    XMLELEMENT("Type", 'C'),
                    XMLELEMENT("ID", '1809'),
                    XMLELEMENT("RIC", NULL),
                    XMLELEMENT("UEN", '019'),
                    XMLELEMENT("Name", 'Limited')
                )
            )
        ) AS CLOB INDENT SIZE=2 VERSION '1.0' ENCODING 'UTF-8' STANDALONE NO)
    INTO p_out_clob FROM dual;
END;
/

4. 如何在查询中添加Form1和ContentForm标签?

通过嵌套XMLELEMENT实现层级结构,将ContentForm作为Form1的子元素,SectionI和SectionII作为ContentForm的子元素,完整查询如下:

SELECT XMLELEMENT("Form1", 
    XMLELEMENT("ContentForm", 
        XMLELEMENT("SectionI", XMLELEMENT("Date", TO_CHAR(SYSDATE, 'DD/MM/YYYY'))),
        XMLELEMENT("SectionII", 
            XMLELEMENT("Type", 'C'),
            XMLELEMENT("ID", '1809'),
            XMLELEMENT("RIC", NULL),
            XMLELEMENT("UEN", '019'),
            XMLELEMENT("Name", 'Limited')
        )
    )
) FROM dual;

这里将SYSDATE转换为DD/MM/YYYY格式的字符串,确保日期格式与目标XML一致。


内容的提问来源于stack exchange,提问作者sharan jain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:19:55