【问题标题】:Oracle SQL : Select Query : search if clob Contains a string with pattern matchingOracle SQL : Select Query : search if clob contains a string with pattern matching
【发布时间】:2021-04-13 01:43:59
【问题描述】:

我有一个包含 JSON 数据的 CLOB 列的 Orable 表。我需要一个在 CLOB 数据中搜索的查询。

我使用了条件where DBMS_LOB.instr(colName,'apple:')>0,它给出了具有apple: 的记录。但是,我需要查询返回包含任意数量的苹果的记录除了空白,这意味着 json apple 键应该有一个值。

我正在考虑类似where DBMS_LOB.instr(colName,'apple:**X**')>0 的东西,其中X 可以是任何不为空的数字。我试过regexp_instr,但这似乎不适合CLOB。

有没有办法解决这个问题?

【问题讨论】:

  • 这是对关系数据库的误用。将 json 数据存储在 db 中非常好,但如果您需要能够在该 json 数据中进行搜索,您应该真正还提取您在插入/更新时关心的字段并提供真实的字段自己的列。
  • oracle 已内置支持查询 json。仔细阅读
  • ... 从 Oracle 12.1 开始并在后续版本中得到改进。
  • 如果您将 JSON 存储在 Oracle 数据库中,您必须告诉我们您的 Oracle 版本。新版本对 JSON 的支持非常强大,而旧版本(最高 11.2)则不支持。

标签: sql oracle


【解决方案1】:

用于解析 JSON 输入的通用字符串函数是危险的 - 例如,当看起来像 JSON 对象的东西实际上嵌入到字符串值中时,您会得到误报。 (在下面的示例中以 ID = 101 说明。)

理想的情况是您使用的是 Oracle 19 或更高版本;在这种情况下,您可以使用对json_exists 的简单调用,如下所示。在我创建的示例表中,第一个 JSON 字符串不包含名为 apple 的成员。在第二行中,字符串确实包含成员apple,但值为null。我显示的第一个查询(查找所有带有apple 成员的 JSON)将在输出中包含这一行。最后一个查询是您需要的:它添加了一个过滤器,以便 JSON 字符串必须包含至少一个具有非null 值的 apple 成员(无论它是否还包括其他名为 apple 的成员,可能带有 @ 987654329@值)。

create table sample_data
( id      number primary key
, colname clob   check (colname is json)
);

insert into sample_data
    values (101, '{name:"Chen", age:83, values:["{apple:6}", "street"]}');

insert into sample_data
    values (102, '{data: {fruits: [{orange:33}, {apple:null}, {plum:44}]}}');
    
insert into sample_data
    values (103, '[{po:3, "prods":[{"apple":4}, {"banana":null}]},
                   {po:4, "prods":null}]');

请注意,我故意将引用和未引用的成员名称混合在一起,以验证以下查询在所有情况下都能正常工作。 (还请记住,JSON 中的成员名称区分大小写,即使在 Oracle 中也是如此!)

select id
from   sample_data
where  json_exists(colname, '$..apple')
;


 ID
---
102
103

这是您需要的查询。注意路径中的..(意思是-在JSON中找到一个名为apple的对象成员anywhere)和最后的过滤器。

select id
from   sample_data
where  json_exists(colname, '$..apple?(@ != null)')
;

 ID
---
103

【讨论】:

    【解决方案2】:

    您可以为此使用 regexp_like 函数: 其中 regexp_like(colName,'apple : [0-9]')

    【讨论】:

    • 它将跳过与{apple:10}相同的{"apple":10},并为{"someKey": "apple : 1"}返回正假。如果 JSON 处理器已经存在,则无需重新发明它。
    • 与 json.regexp_like 我得到错误,说明该功能不可用。
    猜你喜欢
    • 2022-12-01
    • 2022-12-27
    • 2011-09-16
    • 2010-09-23
    • 2013-08-13
    • 2022-12-02
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多