使用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
相关产品推荐
相关产品推荐

