Oracle json 使用多个上下文的路径复合表达式不起作用

Oracle json path compound expression using multiple context does not work

我有以下 json:

{
   "signedOffTasks":[
      "TASK2"
   ],
   "taskDeadlines":[
      {
         "taskKey":"TASK1",
         "deadline":"2016-05-02"
      },
      {
         "taskKey":"TASK2",
         "deadline":"2016-05-02"
      },
      {
         "taskKey":"TASK3",
         "deadline":"2016-05-02"
      },
      {
         "taskKey":"TASK4",
         "deadline":"2016-05-02"
      },
      {
         "taskKey":"TASK5",
         "deadline":"2016-05-02"
      },
      {
         "taskKey":"TASK6",
         "deadline":"2020-05-18"
      }
   ]
}

和以下 json 路径表达式:

$.taskDeadlines[?(@.deadline == "2020-05-18" && $.signedOffTasks.indexOf(@.taskKey) == -1)]

那是我想要 return 截止日期是 2020-05-18,并且适当的任务键不在 signedOffTasks 数组中的东西。

这在

中非常有效

https://codebeautify.org/jsonpath-tester

但不幸的是,如果我在 Oracle 12c CLOB 列中使用相同的 JSON,Oracle 不允许我混合上下文。第二个谓词中的 $ 有问题。

如何使用 Oracle Json 路径实现来表达我想要的内容?

这就是我想要进行 Oracle 查询的方式:

SELECT
     *
 FROM
     TABLE MY_TABLE T
 WHERE
    JSON_EXISTS ( T.JSON_COLUMN,'$.taskDeadlines[?(@.deadline == "2020-05-18" && $.signedOffTasks.indexOf(@.taskKey) == -1)]')

谢谢

indexOf 方法不受支持(从 Oracle Database 19c 开始)。所以你不能用它来检查 signedOffTasks.

中是否存在任务

我不确定您如何使用 Oracle 数据库中的 JSON 路径表达式编写此代码。但是 SQL!

是可能的

您可以使用 json_table:

将数组转换为行和列
select j.* from t, json_table (
  c1, '$.taskDeadlines[*]'
  columns (
    taskKey path '$.taskKey',
    deadline path '$.deadline'
  )
) j
where  deadline = '2020-05-18';

TASKKEY    DEADLINE     
TASK6      2020-05-18  

select j.* from t, json_table (
  c1, '$.signedOffTasks[*]'
  columns (
    task path '$'
  )
) j;

TASK    
TASK2   

从那里你可以使用 not exists/minus 到 return 不在签名数组中的截止日期任务:

select j.taskKey from t, json_table (
  c1, '$.taskDeadlines[*]'
  columns (
    taskKey path '$.taskKey',
    deadline path '$.deadline'
  )
) j
where  deadline = '2020-05-18'
minus
select j.task from t, json_table (
  c1, '$.signedOffTasks[*]'
  columns (
    task path '$'
  )
) j;

TASKKEY   
TASK6  

有点繁琐,但如果需要,您可以在 where 子句中完成所有操作:

select * from t
where  exists (
  select * from json_table (
    c1, '$.taskDeadlines[*]'
    columns (
      taskKey path '$.taskKey',
      deadline path '$.deadline'
    )  
  ) j1
  where  deadline = '2020-05-18'
  and    not exists ( 
    select * from json_table (
      c1, '$.signedOffTasks[*]'
      columns (
        task path '$'
      )
    ) j2
    where  j1.taskKey = j2.task
  )
);

C1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
{
   "signedOffTasks":[
      "TASK2"
   ],
   "taskDeadlines":[ ...