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":[ ...
我有以下 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":[ ...