2017-06-09 11 views
0

Ich benutze Oracle (12cR2) JSON, konnte aber keine Möglichkeit zum Abfragen von Arrays mit bestimmten Elementen finden. Hier ist der Testcode:Abfrage JSON-Array mit Oracle 12cR2 JSON Funktionen

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; 

einen Domain-Index erstellen:

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

Ich möchte alle Zeilen finden, die das Array-Element 2 und 5, unabhängig ihrer Reihenfolge in der Anordnung, dh die SQL sollte Rück die Zeilen mit id 3, 4, 6.

ich viele Möglichkeiten ausprobiert:

SQL1:

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

==> Zurück die Zeilen, die 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)'); 

==> return Zeilen, die 2 oder 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)'); 

==> Rückkehr keine Zeile

SQL4:

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

==> return Zeilen, die 2 oder 5: id = 2, 3, 4, 5, 6

SQL5:

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

==> liefert Reihen die 2 und 5 mit 2 vorhergehenden 5

die einzige SQL, die zurückgibt, was ich will, ist: sql6:

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

==> Rückgabe id = 3, 4, 6

Aber diese Lösung kann sehr mühsam sein, wenn die Anzahl der Elemente erhöht.

Frage: Gibt es bessere Option, dass SQL6 die gleichen Ergebnisse zurückgibt?

Oracle Version zum Testen 12c R2

Vielen Dank im Voraus

James

Antwort

0

Ist diese Hilfe ...

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> 
+0

Das ist meine Frage beantwortet. Vielen Dank! (Entschuldigung, ich konnte keinen Weg finden, diese Antwort als Lösung zu markieren). – james800