如何在 Oracle SQL 中搜索特定的 XML 值?
Posted
技术标签:
【中文标题】如何在 Oracle SQL 中搜索特定的 XML 值?【英文标题】:How do I search for a specific XML value in Oracle SQL? 【发布时间】:2021-11-14 02:50:57 【问题描述】:我正在尝试在 SQL 表 (BLOB) 的 XML 二进制类型列中搜索给定值。
该表有 +3000 条记录。我需要从如下所示的 XML 中查找与 /properties/ip/ 中特定 IP 对应的所有值:
<?xml version="1.0" encoding="UTF-8"?>
<properties>
<port>8000</port>
<ip>12.345.67.80</ip>
</properties>
到目前为止,我已经能够获得 一些 输出,但不是我需要的(我只能使用最后一个 WHERE 子句运行查询,而不是没有):
SELECT
d.*,
extractvalue(xmltype(d.CONFIGURATION,nls_charset_id('AL32UTF8')),'properties/ip') as ip_lookup
FROM
AZ.DEVICES d
WHERE
NAME = 'Door-Entrance';
我对查找具有特定 IP 的所有记录很感兴趣,所以是这样的:
SELECT
d.*,
extractvalue(xmltype(d.CONFIGURATION,nls_charset_id('AL32UTF8')),'properties/ip') as ip_lookup
FROM
AZ.DEVICES d
WHERE
ip_lookup = '12.345.67.80';
有什么想法吗?
【问题讨论】:
【参考方案1】:您可以使用 Oracle 推荐的 XMLTABLE
而不是已弃用的
函数XMLSEQUENCE
或EXTRACTVALUE
如
WITH devices(configuration,name) AS
(SELECT XMLType('<?xml version="1.0" encoding="UTF-8"?>
<properties>
<port>8000</port>
<ip>12.345.67.80</ip>
</properties>'),
'Door-Entrance'
FROM dual)
SELECT ip
FROM devices,
XMLTABLE('/properties' PASSING devices.configuration COLUMNS "IP"
VARCHAR2(50) PATH 'ip')
WHERE name = 'Door-Entrance'
Demo
【讨论】:
嗨,巴巴罗斯,感谢您的评论!最后我是否可以制作类似“WHERE ip_lookup = '12.345.67.80'”的内容来搜索特定的IP? 不客气@jfe1337。对于前一个已弃用的情况,您仍然可以使用this 作为一种向后兼容的选项。对于您当前的语句,由于 XmlType 的使用方式,应该会引发错误。 我有一个大表,其中包含 BLOB 列中的 XML 类型值。我能用 WITH 子句解析所有这些,找到一个特定的 IP 吗?据我所知,根据您的查询,这只是 1 条 XML 记录。谢谢! 正如已经提到的 extractvalue 已被弃用并且不应该被首选 @jfe1337 ,以 WITH 子句开头的查询只是一个说明,您可以创建一个带有 XmlType 列的表(即configuration
) ,这将检查值的正确性(XML 值是否存在违规),如在此 demo 而不是 BLOB 中。
再次感谢您的友好回复,Barbaros,我现在明白您的意思了。我正在使用已配置为 BLOB 的数据库。我可以以某种方式为此 DEVICES 表中的每条记录选择 每个 IP 吗?我想将它们全部提取出来以便能够识别重复项。【参考方案2】:
您可以使用XMLTABLE
和WHERE
子句中的任一过滤器:
SELECT *
FROM AZ.devices d
CROSS APPLY XMLTABLE(
'/properties'
PASSING XMLTYPE(d.configuration,nls_charset_id('UTF8'))
COLUMNS
port NUMBER(5,0) PATH './port',
ip VARCHAR2(15) PATH './ip'
) x
WHERE x.ip = '12.345.67.80';
或者在 XPath 中:
SELECT *
FROM AZ.devices d
CROSS APPLY XMLTABLE(
'/properties[ip="12.345.67.80"]'
PASSING XMLTYPE(d.configuration,nls_charset_id('UTF8'))
COLUMNS
port NUMBER(5,0) PATH './port',
ip VARCHAR2(15) PATH './ip'
) x
其中,对于样本数据:
CREATE TABLE AZ.devices (
name VARCHAR2(30),
configuration BLOB
);
INSERT INTO AZ.devices (name, configuration)
VALUES (
'Door-Entrance',
UTL_RAW.CAST_TO_RAW('<?xml version="1.0" encoding="UTF-8"?>
<properties>
<port>8000</port>
<ip>12.345.67.80</ip>
</properties>')
);
两个输出:
NAME CONFIGURATION PORT IP_LOOKUP Door-Entrance <?xml version="1.0" encoding="UTF-8"?><properties> <port>8000</port> <ip>12.345.67.80</ip></properties> 8000 12.345.67.80
db小提琴here
【讨论】:
您好 MT0,感谢您的友好回复。我认为这是一个很好的方法。但是,我在 CONFIGURATION blob 中确实有很多额外的值,我没有包含在问题中。 @jfe1337 然后将它们添加到COLUMNS
子句中,如果你想输出它们,或者如果你不想输出它们就不要。我没有看到问题是什么。
@jfe1337 您没有提供任何信息让我回答您关于如何映射它们的问题。我建议您只需在 XMLTABLE
的 COLUMNS
子句中添加适当的行,并使用适当的 Xpath 来映射您要映射的属性,但除此之外我不能更具体,因为您没有分享任何细节。
如果我收到错误“ORA-06502: PL/SQL: numeric or value error ORA-06512: at "SYS.XMLTYPE", line 283”,这是否是由于数据类型映射不正确?
@jfe1337 我不知道,你还没有分享你的查询或数据。以上是关于如何在 Oracle SQL 中搜索特定的 XML 值?的主要内容,如果未能解决你的问题,请参考以下文章
在 gmail api 中搜索特定的 in-reply-to 标头
在一个用 JSON 填充的 NSArray 中搜索特定的标题
Javascript,Nodejs:在文件中搜索特定的单词字符串