【问题标题】:Passing dynamic key in JSON_VALUE() in Oracle在 Oracle 中传递 JSON_VALUE() 中的动态键
【发布时间】:2017-03-17 15:13:03
【问题描述】:

我有一个包含 Json 数据的俱乐部类型列。 我有大约 100 个键,每条记录都是唯一的。 我们正在使用 json_value('json_data', 'keyname')。 就我而言,我不知道该记录的实际情况。所以我需要加入另一个定义了键的表。代替键名,我想传递列名。 它给出了一些错误说:

语法错误,
期望:字符串

任何人都可以建议,如何通过在运行时传递动态键从 json 列中获取数据。

假设我有两个表 table_1 和 table_2。 Table_1 有一个名为 json_data_column 的列,它以 json 格式存储数据。 Table_1 具有 FK 到具有映射键的 TABLE_2。 所以我们必须找出每条记录的动态键的值是什么。

如果我用任何静态字符串代替 t2.json_key ,那么它就可以工作了。 但是在给出动态值时,它不起作用。

工作

select
       json_value ( json_value (t1.json_data_column, '$.string'), '$.my_key' )
from TABLE_1 t1
       inner join TABLE_2 t2 on t1.json_key_fk = t2.id

不工作

select
       json_value ( json_value (t1.json_data_column, '$.string'), t2.json_key )
from TABLE_1 t1
       inner join TABLE_2 t2 on t1.json_key_fk = t2.id

数据集:

{"string":"{\"id\":133100,\"data_found\":5,\"isActive\":\"true\",\"process\":\"completed\",\"status\":\"COMPLETED\"}"}

{"string":"{\"id\":133100,\"data_found\":5,\"isDelete\":\"true\",\"process\":\"completed\",\"status\":\"COMPLETED\"}"}

{"string":"{\"id\":133100,\"data_found\":5,\"isUnderProgress\":\"false\",\"process\":\"completed\",\"status\":\"COMPLETED\"}"}

{"string":"{\"id\":133100,\"data_found\":5,\"isSentToClient\":\"false\",\"process\":\"completed\",\"status\":\"COMPLETED\"}"}

【问题讨论】:

  • 你能发布一些示例数据吗?这将帮助我们可视化您的问题

标签: sql json oracle


【解决方案1】:

架构无法直接支持您尝试做的事情。基本上,我们设置了一个 JSON PATH 引擎,它在表中的每一行(集合中的文档)中搜索一组在语句编译时定义的路径。在您的情况下,您希望我们使用在检索到行之前无法知道的路径。

在 12.2(现在是 GA)中,我们可以使用 PL/SQL JSON 功能来执行此操作..

SQL> set lines 120 pages 0
SQL> with FUNCTION GET_NAME(P_JSON_DOC in VARCHAR2) RETURN VARCHAR2
  2  is
  3  begin
  4    return SUBSTR(P_JSON_DOC,INSTR(P_JSON_DOC,'"',1,5)+1,INSTR(P_JSON_DOC,'"',1,6)-INSTR(P_JSON_DOC,'"',1,5)-1);
  5  end;
  6  FUNCTION GET_KEY_VALUE(P_JSON_DOC VARCHAR2, P_KEY VARCHAR2) RETURN VARCHAR2
  7  is
  8    JO JSON_OBJECT_T;
  9  begin
 10    JO := JSON_OBJECT_T(P_JSON_DOC);
 11    return JO.get_STRING(P_KEY);
 12  end;
 13  MY_TABLE as (
 14    select COLUMN_VALUE JSON_DOC
 15      from TABLE(
 16             XDB$STRING_LIST_T(
 17               '{"string":"{\"id\":133100,\"data_found\":5,\"isActive\":\"true\",\"process\":\"completed\",\"status\"
:\"COMPLETED\"}"}',
 18               '{"string":"{\"id\":133100,\"data_found\":5,\"isDelete\":\"true\",\"process\":\"completed\",\"status\"
:\"COMPLETED\"}"}',
 19               '{"string":"{\"id\":133100,\"data_found\":5,\"isUnderProgress\":\"false\",\"process\":\"completed\",\"
status\":\"COMPLETED\"}"}',
 20               '{"string":"{\"id\":133100,\"data_found\":5,\"isSentToClient\":\"false\",\"process\":\"completed\",\"s
tatus\":\"COMPLETED\"}"}'
 21             )
 22           )
 23  )
 24  select GET_NAME(EMBEDDED_JSON),GET_KEY_VALUE(EMBEDDED_JSON,GET_NAME(EMBEDDED_JSON))
 25    from (
 26           select JSON_VALUE(JSON_DOC,'$.string') EMBEDDED_JSON
 27             from MY_TABLE
 28         )
 29  /
isActive
true

isDelete
true

isUnderProgress
false

isSentToClient
false


SQL>

在 12.1 中,GET_NAME 函数可以使用 EXECUTE IMMEDIATE

FUNCTION GET_KEY_VALUE(P_JSON_DOC VARCHAR2, P_KEY VARCHAR2) RETURN VARCHAR2
is
  V_RESULT VARCHAR2(200);
begin
  EXECUTE IMMEDIATE 'select JSON_VALUE(:1,''$.' || P_KEY || ''') from dual' into V_RESULT using P_JSON_DOC;
  return V_RESULT;
end;

【讨论】:

  • 更正:在 Oracle 12.1 中,“GET_KEY_VALUE”函数(不是 GET_NAME)可以使用 EXECUTE IMMEDIATE。因为 JSON_OBJECT_T 不可用。谢谢你的回答!由于我们仍处于 12.1 版本,因此帮助很大。
猜你喜欢
  • 2020-07-07
  • 1970-01-01
  • 1970-01-01
  • 2019-09-27
  • 2021-02-12
  • 1970-01-01
  • 2023-03-20
  • 2012-04-11
  • 1970-01-01
相关资源
最近更新 更多