使用Oracle 12cR2 json功能查询json数组

时间:2017-06-09 23:07:17

标签: json oracle

我正在使用Oracle(12cR2)json,但找不到查询包含某些元素的数组的方法。这是测试代码:

CREATE TABLE json_array (
  id    NUMBER NOT NULL,
  array CLOB,
  CONSTRAINT json_array_pk PRIMARY KEY (id),
  CONSTRAINT json_array_chk_1 CHECK (array IS JSON)
);

INSERT INTO json_array (id, array) VALUES (1, '{"a":[1, 3]}');
INSERT INTO json_array (id, array) VALUES (2, '{"a":[2, 4, 6]}');
INSERT INTO json_array (id, array) VALUES (3, '{"a":[1, 2, 5]}');
INSERT INTO json_array (id, array) VALUES (4, '{"a":[2, 5]}');
INSERT INTO json_array (id, array) VALUES (5, '{"a":[5]}');
INSERT INTO json_array (id, array) VALUES (6, '{"a":[5, 2]}');


COMMIT;

创建域索引:

CREATE SEARCH INDEX idx_json_array ON json_array (array) FOR JSON;

我想查找包含数组元素2和5的所有行,无论它们在数组中的顺序如何,即SQL应该返回id为3,4,6的行。

我尝试了很多选择:

SQL1:

select * from json_array j  -- return any arrays containing 2
where json_exists(j.array, '$?(@.a[0] == 2)');

==>返回包含2的行:id = 2,3,4,6

SQL2:

select * from json_array j  -- return arrays containing 2 at index 1
where json_exists(j.array, '$?(@.a[0] == 2  || @.a[0] == 5)');

==>返回包含2或5的行:id = 2,4,5,6

SQL3:

select * from json_array j  -- return arrays containing 2 at index 1
where json_exists(j.array, '$?(@.a[0] == 2  && @.a[0] == 5)');

==>不返回行

SQL4:

select * from json_array j  -- returns arrays containing 2 OR 5
where json_textcontains(j.array, '$.a', '[2,5]');

==>返回包含2或5的行:id = 2,3,4,5,6

SQL5:

select * from json_array j  
where json_textcontains(j.array, '$.a', '{[2] & [5]}');

==>返回包含2个AND 5的行,其中2个在5之前

唯一返回我想要的SQL是: SQL6:

select * from json_array j
where json_textcontains(j.array, '$.a', '[2]') AND json_textcontains(j.array, '$.a', '[5]');

==>返回id = 3,4,6

但是当元素数量增加时,这个解决方案会非常麻烦。

问题:SQL6有更好的选择可以返回相同的结果吗?

用于测试12c R2的Oracle版本

提前致谢

詹姆斯

1 个答案:

答案 0 :(得分:0)

这有帮助......

   SQL> with MY_TABLE as
  2  (
  3    select 1 as ID, '{"a":[1, 3]}' as ARRAY
  4      from DUAL
  5    union all
  6    select 2 as ID, '{"a":[2, 4, 6]}' as ARRAY
  7      from DUAL
  8    union all
  9    select 3 as ID, '{"a":[1, 2, 5]}' as ARRAY
 10      from DUAL
 11    union all
 12    select 4 as ID, '{"a":[2, 5]}' as ARRAY
 13      from DUAL
 14    union all
 15    select 5 as ID, '{"a":[5]}' as ARRAY
 16      from DUAL
 17    union all
 18    select 6 as ID, '{"a":[5, 2]}' as ARRAY
 19      from DUAL
 20  )
 21  select ID
 22    from MY_TABLE
 23   where json_exists(ARRAY,'$?(@.a == 2 && @.a == 5)')
 24  /

        ID
----------
         3
         4
         6

SQL>