从 CLOB 列中过滤非 XML 数据

Posted

技术标签:

【中文标题】从 CLOB 列中过滤非 XML 数据【英文标题】:Filtering non-XML data from a CLOB column 【发布时间】:2015-09-10 14:07:52 【问题描述】:

我正在尝试从CLOB(或VARCHAR)中选择值并将XMLQUERY 应用于它。该列包含 XML 和非 XML 字符串数据的混合,似乎没有一种明显的方法可以过滤掉非 XML 行。

我正在寻找一种让 XMLPARSE 优雅地失败的方法,即在遇到非 XML 数据时返回 NULL 而不是整个查询失败。

1) XMLPARSE 带有有效的 XML

SELECT XMLPARSE('<?xml version="1.0"?><doc/>') FROM SYSIBM.SYSDUMMY1
1    
------
<doc/>

2) XMLPARSE 带有无效的 XML

SELECT XMLPARSE('<?xml version="1.0"?><doc/>badxml') FROM SYSIBM.SYSDUMMY1
[Error Code: -20398, SQL State: 2200M]  DB2 SQL Error: SQLCODE=-20398, 
SQLSTATE=2200M, SQLERRMC=27;An incorrect character was detected in the 
document RC=000C,RSN=3062., DRIVER=4.12.55

有没有办法添加函数、SET 或其他参数,使上述返回 NULL 或空结果集?

【问题讨论】:

我无法测试我的理论,因为我只能访问 IBM i 上的 DB2,它使用不同的语法并且有其他细微的差异。但是,我会将其包装在 UDF 中并捕获此错误并在它发生时返回 null。 我有一个丑陋的解决方法。我正在使用 SQL 生成查询,它为数据库的每一行生成一个单独的语句:SELECT 'SELECT XMLPARSE(clob_col) FROM clobtable WHERE clob_key = ''' || clob_key || ''';' FROM clobtable 然后我将上述结果输入一个 SQL 批处理并查找失败的语句。 【参考方案1】:

你在一块岩石和一个艰难的地方。优雅而有效地使用 XMLPARSE 和 XMLQUERY 的唯一方法是处理已知的 XML 数据。否则,如您所见,它们会以一种非常不雅的方式吐遍整个地方。

您可以编写(或使用现有的)非常简单的 XML 解析器(它们非常简单)并将其嵌入到用户定义的函数中,该函数将验证您在列中是否有格式良好的 XML 文档并返回 XML NULL 上的字符串。

然后您使用用户定义的函数来对数据进行子查询,然后再将其传递给 XMLPARSE/XMLQUERY。您可能希望返回一个空文档以使您的生活更轻松,而不是返回 NULL,但这取决于您计划应用的查询。

思考一下,如果你使用 XML 数据类型而不是 CLOB 和 VARCHAR,这个问题就会消失,所以如果你的表足够小,你可以选择候选行并将它们加载到具有强类型 XML 的临时表中吗?列?

【讨论】:

以上是关于从 CLOB 列中过滤非 XML 数据的主要内容,如果未能解决你的问题,请参考以下文章

从clob列中提取xml元素时出错

我想写一个sql查询来获取soap xml中两个标签之间的数据,这些标签出现在oracle表的clob列中

Oracle 11g:从 CLOB 和表更新中读取 XML 记录

在 Oracle 的 CLOB 列中更新 xml 标记

使用 XMLtable/Xpath 转换 XML Clob 并将其存储在数据库表中

无法从 CLOB 列写入正确的 XML 数据