如何使用 PL-SQL 查询包含 XML 的 Clob 节点
Posted
技术标签:
【中文标题】如何使用 PL-SQL 查询包含 XML 的 Clob 节点【英文标题】:How to Query an XML-containing Clob for nodes with PL-SQL 【发布时间】:2016-05-24 13:17:10 【问题描述】:在 T-SQL 中我这样做:
CREATE PROCEDURE [dbo].[ps_GetAuditUpdatesRequired]
@AuditXML xml
AS
SET NOCOUNT ON
SELECT
doc.col.value('@id', 'int') AS id
FROM
@AuditXML.nodes('/rths/rth') AS doc(col)
WHERE (
-- Get anything needs to be deleted and does exist in the database already
doc.col.value('@method', 'nvarchar(16)') = 'DELETE' AND EXISTS ( SELECT 1 FROM audits_ WHERE doc.col.value('@id', 'int') = audits_.Id_RetinaId ) OR
-- Get anything that is not set to be deleted and does not already exist with a newer version
doc.col.value('@method', 'nvarchar(16)') != 'DELETE' AND NOT EXISTS ( SELECT 1 FROM audits_ WHERE doc.col.value('@id', 'int') = audits_.Id_RetinaId AND doc.col.value('@versionSerial', 'int' ) <= audits_.nl_VersionSerial)
)
SET NOCOUNT OFF
我怎样才能在 oracle 中做到这一点? 注意:AuditXML 参数在 Oracle 版本中将是一个 CLOB。
【问题讨论】:
您能否添加一个示例 XML 文档和其他数据,以及您希望发生什么? 你能给出你想选择的元素/属性的 XPath 吗? 【参考方案1】:如果我了解您在做什么,您需要an XMLTable 将节点属性提取为关系数据;然后,您可以在 where
子句中使用由此生成的列:
SELECT doc.id
FROM XMLTable('/rths/rth'
PASSING XMLType(:auditXML)
COLUMNS id NUMBER PATH '@id',
method NVARCHAR2(16) PATH '@method',
versionSerial NUMBER PATH '@versionSerial'
) doc
WHERE (
-- Get anything needs to be deleted and does exist in the database already
doc.method = 'DELETE' AND EXISTS (
SELECT 1
FROM audits_
WHERE doc.id = audits_.Id_RetinaId
)
OR (
-- Get anything that is not set to be deleted and does not already exist with a newer version
doc.method != 'DELETE' AND NOT EXISTS (
SELECT 1
FROM audits_
WHERE doc.id = audits_.Id_RetinaId
AND doc.versionSerial <= audits_.nl_VersionSerial)
)
)
我使用:auditXML
作为绑定变量,但您可以传入表格列或字符串文字 - 尽管后者在纯 SQL 中限制为 4K(最高 12c)。
Oracle 过程无法像在 T-SQL 中那样返回查询结果。在一个过程中,查询必须选择 into 一些东西,但是根据你使用它的方式,你可能实际上需要一个流水线表函数和一个游标循环来将行输出,或者一个函数返回一个引用游标(或具有引用游标 OUT 参数的过程)。
【讨论】:
这是一个美丽的人。我必须使用字符串文字。我应该很好,因为我正在运行 12 c。谢谢!【参考方案2】:类似:
SELECT id
FROM (
SELECT EXTRACTVALUE( column_value, '/rth/@method' ) AS method,
EXTRACTVALUE( column_value, '/rth/@id' ) AS id,
EXTRACTVALUE( column_value, '/rth/@versionSerial' ) AS serial
FROM TABLE(
XMLSequence(
EXTRACT( XMLType( auditXml ), '/rths/rth' )
)
)
) x
WHERE (
method = 'DELETE'
AND EXISTS( SELECT 1
FROM audits_ a
WHERE x.id = a.Id_RetinaId )
)
OR
(
( method IS NULL OR method <> 'DELETE' )
AND NOT EXISTS( SELECT 1
FROM audits_ a
WHERE x.id = a.Id_RetinaId
AND x.serial <= a.nl_VersionSerial )
);
【讨论】:
这可行(当然),但extract 和extractvalue 已弃用。以上是关于如何使用 PL-SQL 查询包含 XML 的 Clob 节点的主要内容,如果未能解决你的问题,请参考以下文章