Sql 如何使用Oracle JSON_值

Sql 如何使用Oracle JSON_值,sql,json,oracle,stored-procedures,json-value,Sql,Json,Oracle,Stored Procedures,Json Value,我正在做一个扳机 declare v_time number(11, 0); begin for i in 0..1 loop select JSON_VALUE(body, '$.sections[0].capsules[0].timer.seconds') into v_time from bodycontent where contentid=1081438; dbms_output.put_line(v_time); end loop; end; 但是,索引引用不会变成动态的

我正在做一个扳机

declare
  v_time number(11, 0);
begin
for i in 0..1
loop
  select JSON_VALUE(body, '$.sections[0].capsules[0].timer.seconds') into v_time from bodycontent where contentid=1081438;
dbms_output.put_line(v_time);
end loop;
end;
但是,索引引用不会变成动态的

like JSON_VALUE(body, '$.sections[i].capsules[i].timer.seconds')

有什么方法可以做到这一点吗?

您需要将变量连接到json路径中:

JSON_值(body,'$.sections['| | | to_char(i)| |'].capsules[0]。timer.seconds')

我真的看不出你的问题与触发器有什么关系。

你可以使用
JSON\u TABLE

declare
  v_time number(11, 0);
begin
for i in 0..1
loop
  select JSON_VALUE(body, '$.sections[0].capsules[0].timer.seconds') into v_time from bodycontent where contentid=1081438;
dbms_output.put_line(v_time);
end loop;
end;
声明
v_时间数(11,0);
开始
对于0..1循环中的i
选择时间
进入v_时间
来自bodycontent b
交叉应用
JSON_表(
b、 身体,
“$.sections[*]”
纵队(
第九节普通性指数,
嵌套路径“$.capsules[*]”
纵队(
普通性指数,
时间编号(11,0)路径“$.timer.seconds”
)
)
)j
其中j.截面指数=i+1
j.u指数=i+1
b.contentid=1081438;
dbms_输出。输出线(v_时间);
端环;
结束;
/
其中,对于测试数据:

创建表bodycontent(bodyclob检查(body是JSON),contentid号);
插入到bodycontent(body,contentid)值中(
“{”部分:[
{“胶囊”:[{“计时器”:{“秒”:0},{“计时器”:{“秒”:1},{“计时器”:{“秒”:2}]},
{“胶囊”:[{“计时器”:{“秒”:3},{“计时器”:{“秒”:4},{“计时器”:{“秒”:5}]},
{“胶囊”:[{“计时器”:{“秒”:6},{“计时器”:{“秒”:7},{“计时器”:{“秒”:8}}]}},
1081438
);
产出:

或者,您可以只使用查询:

选择节索引、胶囊索引、时间
来自bodycontent b
交叉应用
JSON_表(
b、 身体,
“$.sections[*]”
纵队(
第九节普通性指数,
嵌套路径“$.capsules[*]”
纵队(
普通性指数,
时间编号(11,0)路径“$.timer.seconds”
)
)
)j
式中((1,1)、(2,2))中的(j.截面指数,j.胶囊指数)
b.contentid=1081438;
哪些产出:

节段|胶囊|索引|时间 ------------: | ------------: | ---: 1 | 1 | 0 2 | 2 | 4 (注意:
中用于顺序性的索引比JSON路径中的数组索引高1。)


DBFIDLE

因此,问题是您希望循环索引(对角遍历数组,只拾取两个元素)-但是JSON函数不使用变量作为数组索引-它们需要硬编码索引

PL/SQL对此有一个答案——本机动态SQL,如下所示

但是,请注意,这种方法在同一文档上重复调用
JSON\u VALUE()。根据实际需求(我假设您的问题中的一个只是为了说明)和文档的大小,对
JSON_TABLE()
进行一次调用可能更有效,如MT0的回答所示。如果实际上您只从一个非常大的文档中提取了两个标量值,那么对
JSON_VALUE()
的两个调用可能是合理的,尤其是当文档比这里显示的要大得多时;但是,如果您要从一个不太复杂的文档中提取许多标量值,那么对
JSON_TABLE()
进行一次调用可能会更好,即使最终您没有使用它生成的所有数据

无论如何-作为本机动态SQL的一个示例,下面是替代解决方案(使用MT0的表):


首先,谢谢你的回答。当更新表数据时,我们正在创建一个触发器来将JSON数据存储在其他表中。但是如果你按照你告诉我的那样做,就会出现以下错误。[ORA-00907:缺少右括号]我应该如何修复它?不是那样的。路径必须是文本文字。解决方案是动态SQL。我只是写了一个答案来说明。 SECTION_INDEX | CAPSULE_INDEX | TIME ------------: | ------------: | ---: 1 | 1 | 0 2 | 2 | 4
declare
  v_time number(11, 0);
begin
  for i in 0..1 loop
    execute immediate q'#
    select json_value(body, '$.sections[#' || i ||
                      q'#].capsules[#' || i || q'#].timer.seconds')
    from   bodycontent
    where  contentid = 1081438#'
    into v_time;
    dbms_output.put_line(v_time);
  end loop;
end;
/


0
4

PL/SQL procedure successfully completed.