简化,我使用SQL查询生成一组XML元素,例如:
SELECT XMLELEMENT(NAME "project", project) FROM project;
<project>project1</project>
<project>project2</project>
...
现在我需要将此序列包装到主“projects”元素中,并将其输出到一个漂亮的缩进XML文件中。
我尝试过如下:
db2 -x "SELECT XMLSERIALIZE(CONTENT XMLELEMENT(NAME "projects", XMLAGG(XMLELEMENT(NAME "project", project))) AS CLOB INCLUDING XMLDECLARATION) FROM project" >output.xml
我得到类似的东西:
<projects><project>project1</project><project>project2</project>...</projects>
XMLAGG可以工作(它已将所有内容包装到主项目元素中)。但是,有了10万个项目,db2抱怨“SQL0433N Value”...太长了。 SQLSTATE = 22001"
此外,output.xml没有缩进(一切都在一行中)。
实现这一目标的正确方法是什么?
此致 大卫
答案 0 :(得分:1)
看起来您需要创建一个临时表并手动放置开始和结束标记以及查询结果(确保为查询结果的缩进添加一些空格)。如果您有一个ID列并按表中的顺序放置所有内容,那么您只需要查询该表(没有id,但按id排序)并将结果保存到文件中。
或者,您有一个存储过程检查查询结果并以格式化方式输出。这可能比第一个解决方案慢,但需要更少的内存。
您使用原始查询的最后一个选项,并使用外部工具对结果进行后期处理。
答案 1 :(得分:1)
您可能无法获得所需的确切缩进,但如果您没有将整个文档XMLAGG整合到一个巨大的CLOB中,那么每行至少会获得一个保证换行符。
公用表表达式是指定不必出现在最终select语句中的排序列的便捷方式。
WITH xmlheader( xmlrow, sort_seq ) AS ( VALUES (
' <?xml version="1.0" ?>'|| CHR( 10 ) || '<projects>', 1 ))
,
xmlbody( xmlrow, sort_seq ) AS ( VALUES(
'<project>Replace this with your XMLSERIALIZE query, '
|| 'but only focus on generating XML for one project per row. '
|| 'This will enable you to specify a narrower data type, such AS VARCHAR(1000) '
|| 'for each row, and you will get each separate project '
|| 'followed by the normal newline at the end of each SQL row. '
|| 'No XMLAGG is necessary in this query.</project>', 2))
,
xmlfooter( xmlrow, sort_seq) AS ( VALUES( '</projects>', 3 ))
SELECT xmlrow FROM (
SELECT xmlrow, sort_seq FROM xmlheader
UNION ALL
SELECT xmlrow, sort_seq FROM xmlbody
UNION ALL
SELECT xmlrow, sort_seq FROM xmlfooter
) AS fullxml
ORDER BY sort_seq