在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。
答案 0 :(得分: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参数的过程)。
答案 1 :(得分:1)
类似的东西:
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 )
);