将 JSON_ARRAY_T 转换为 SQL 表达式的表达式列表
Converting JSON_ARRAY_T to expression list for SQL expression
在 PL/SQL 中,我可以从有效负载中读取并获取 JSON_ARRAY_T 对象。假设我想查询由 id
标识的文档列表。 payload中发送的JSON为:
{"id": [1, 2, 3]}
我的PL/SQL会像
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;
我遇到一个错误,但是说 ORA-00932: inconsistent datatypes: expected NUMBER got SYS.JSON_ARRAY_T
。我应该如何让它工作?
使用 JSON_TABLE
在 SQL 中全部完成:
BEGIN
OPEN :result FOR
SELECT i.*
FROM INVOICES i
INNER JOIN JSON_TABLE(
:body_text,
'$.id[*]'
ERROR ON ERROR
COLUMNS (
id NUMBER PATH '$'
)
) j
ON (i.id = j.id);
END;
/
db<>fiddle here
这里的问题是“in”子句期望右侧有一个列表,但无法处理 json_array_t 实例。
一个选项是将数组展开为数字。为了做到这一点,“in”子句的右侧参数将是 json_table 的结果,它将输入数组展开。
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 '$')));
另一种方法是将 json_array 转换为 varray/nested table 并在“in”子句的右侧展开。同上,但需要 varray/nested table 作为中间步骤。
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)));
就是说,如果您想继续使用 json_array_t,那么您可能想像这样迭代 json_array_t 的元素:
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;
/
在 PL/SQL 中,我可以从有效负载中读取并获取 JSON_ARRAY_T 对象。假设我想查询由 id
标识的文档列表。 payload中发送的JSON为:
{"id": [1, 2, 3]}
我的PL/SQL会像
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;
我遇到一个错误,但是说 ORA-00932: inconsistent datatypes: expected NUMBER got SYS.JSON_ARRAY_T
。我应该如何让它工作?
使用 JSON_TABLE
在 SQL 中全部完成:
BEGIN
OPEN :result FOR
SELECT i.*
FROM INVOICES i
INNER JOIN JSON_TABLE(
:body_text,
'$.id[*]'
ERROR ON ERROR
COLUMNS (
id NUMBER PATH '$'
)
) j
ON (i.id = j.id);
END;
/
db<>fiddle here
这里的问题是“in”子句期望右侧有一个列表,但无法处理 json_array_t 实例。
一个选项是将数组展开为数字。为了做到这一点,“in”子句的右侧参数将是 json_table 的结果,它将输入数组展开。
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 '$')));
另一种方法是将 json_array 转换为 varray/nested table 并在“in”子句的右侧展开。同上,但需要 varray/nested table 作为中间步骤。
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)));
就是说,如果您想继续使用 json_array_t,那么您可能想像这样迭代 json_array_t 的元素:
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;
/