In PL/SQL I can read and get a JSON_ARRAY_T object from the payload. Say I want to query a list of documents identified by their id
s. The JSON sent in the payload is:
{"id": [1, 2, 3]}
and my PL/SQL would be like
DECLARE
payload JSON_OBJECT_T;
idArray JSON_ARRAY_T;
cur SYS_REFCURSOR;
BEGIN
payload := JSON_OBJECT_T.parse(:body_text);
idArray := payload.get_Array('id');
OPEN cur FOR
SELECT * FROM INVOICES WHERE id IN idArray;
:result := cur;
END;
I encounter an error however saying ORA-00932: inconsistent datatypes: expected NUMBER got SYS.JSON_ARRAY_T
. How should I get this working?
The problem here is that the "in" clause is expecting a list on its right side but can't process a json_array_t instance.
One option is to unflatten the array into numbers. In order to do this, the right side argument to the "in" clause would be the result of json_table, which unflattens the input array.
drop table invoices;
create table invoices (id number);
insert into invoices values (2);
insert into invoices values (4);
select * from invoices where id in
(select * from json_table('{"id":[1,2,3]}', '$.id[*]' columns (a path '$')));
Another alternative is to convert the json_array into a varray/nested table and unflatten that on the right side of the "in" clause. Same as above, but needs the varray/nested table as an intermediate step.
drop table invoices;
create table invoices (id number);
insert into invoices values (2);
insert into invoices values (4);
drop type narr;
create type narr as array(5) of number;
/
select * from invoices where id in
(select * from table
(select json_value('{"id":[1,2,3]}', '$.id' returning narr)));
That said, if you want to keep using json_array_t, then you might want to iterate over the elements of json_array_t like this:
DECLARE
payload JSON_OBJECT_T;
idArray JSON_ARRAY_T;
idx number;
BEGIN
payload := JSON_OBJECT_T.parse('{"id":[1,2,3]}');
idArray := payload.get_Array('id');
for idx in 1..idArray.get_Size loop
dbms_output.put_line(idArray.get(idx-1).to_Number());
end loop;
END;
/