在Oracle视图中的JSON列上使用点表示法
我试图弄清楚如何将JSON列从表中拉入视图,并且仍然能够在在Oracle视图中的JSON列上使用点表示法,json,oracle,Json,Oracle,我试图弄清楚如何将JSON列从表中拉入视图,并且仍然能够在WHERE子句中使用点表示法 我目前已经正确定义了列,并且可以在直接命中表的查询中的WHERE子句中使用点表示法。我遇到的问题是,该表当前在一个视图中使用,我需要使用该视图返回所有相关数据 如果我只是在视图定义中包含列,我将失去使用点表示法在字符串中搜索值的能力 如果我在从视图检索数据的查询中将视图连接回这个表,我就能够在where子句中使用点表示法,但是,我会受到巨大的性能影响(慢4-5倍) 下面是存储在每一行中的JSON示例 {&qu
WHERE
子句中使用点表示法
我目前已经正确定义了列,并且可以在直接命中表的查询中的WHERE
子句中使用点表示法。我遇到的问题是,该表当前在一个视图中使用,我需要使用该视图返回所有相关数据
如果我只是在视图定义中包含列,我将失去使用点表示法在字符串中搜索值的能力
如果我在从视图检索数据的查询中将视图连接回这个表,我就能够在where
子句中使用点表示法,但是,我会受到巨大的性能影响(慢4-5倍)
下面是存储在每一行中的JSON示例
{"fields":
{
"field1":{ "name": "field1","label": "My Field 1","value": "ABCD"},
"field2":{ "name": "field2","label": "My Field 2","value": ""},
"field3":{ "name": "field3","label": "My Field 3","value": "XYZ"},
"field4":{ "name": "field4","label": "My Field 4","value": ""},
"field5":{ "name": "field5","label": "My Field 5","value": ""},
"field6":{ "name": "field6","label": "My Field 6","value": "Y"},
"field7":{ "name": "field7","label": "My Field 7","value": ""}
}
}
我希望能够在视图中执行的操作是其中json\u col\u name.fields.field1.value='ABCD'
请记住,对象键(如field1
、field2
)将是任意值,不总是遵循命名约定,也不总是有7个字段
我并没有和这个模式结过婚,我很乐意改变它,让它发挥作用
下面是重现表/视图和数据的SQL语句
create table MAIN_TABLE
(
ID NUMBER(10) not null
constraint MY_PK
primary key,
JSON_DATA CLOB
constraint JSON_DATA_CONST
check (JSON_DATA IS JSON)
)
INSERT INTO MAIN_TABLE (ID, JSON_DATA) VALUES (1, '{"fields": {"field1":{ "name": "field1","label": "My Field 1","value": "ABCD"},"field2":{ "name": "field2","label": "My Field 2","value": "XYZ"},"field3":{ "name": "field3","label": "My Field 3","value": "Y"},"field4":{ "name": "field4","label": "My Field 4","value": ""},"field5":{ "name": "field5","label": "My Field 5","value": ""},"field6":{ "name": "field6","label": "My Field 6","value": ""},"field7":{ "name": "field7","label": "My Field 7","value": ""},}}');
INSERT INTO MAIN_TABLE (ID, JSON_DATA) VALUES (2, '{"fields": {"field1":{ "name": "field1","label": "My Field 1","value": ""},"field2":{ "name": "field2","label": "My Field 2","value": "XYZ"},"field3":{ "name": "field3","label": "My Field 3","value": "Y"},"field4":{ "name": "field4","label": "My Field 4","value": "QWERTY"},"field5":{ "name": "field5","label": "My Field 5","value": ""},"field6":{ "name": "field6","label": "My Field 6","value": ""},"field7":{ "name": "field7","label": "My Field 7","value": ""},}}');
create or replace view JSON_TEST_VIEW as
select id, JSON_DATA
from MAIN_TABLE
union all
select id, JSON_DATA from MAIN_TABLE;
这个命中表的查询按预期工作
select * from MAIN_TABLE m where m.json_data.fields.field1.value='ABCD'
此查询命中视图,抛出一个无效标识符
错误
select * from JSON_TEST_VIEW jtv where jtv.JSON_DATA.fields.field1.value='ABCD'
我相当确定问题源于
UNION
,因为我最初在我的repo案例中看到问题时没有添加它(原始视图具有UNION
)点表示法仅对标记了“is-JSON”检查约束的JSON有效
在您的表中,我们知道数据是JSON,但一旦您将其放入视图中,我们就不再有这种信心。毕竟你本可以做的
create view V as
select [some json]
union all
select [some junk]
因此,在本例中,您需要让我们知道JSON确实可以这样处理
SQL> create or replace view JSON_TEST_VIEW as
2 select m.id, treat(m.json_data as json) JSON_DATA
3 from
4 (
5 select id, JSON_DATA
6 from MAIN_TABLE
7 union all
8 select id, JSON_DATA from MAIN_TABLE
9 ) m;
View created.
SQL>
SQL> select * from JSON_TEST_VIEW jtv where jtv.JSON_DATA.fields.field1.value='ABCD';
ID JSON_DATA
---------- --------------------------------------------------------------------------------
1 {"fields": {"field1":{ "name": "field1","label": "My Field 1","value": "ABCD"},"
field2":{ "name": "field2","label": "My Field 2","value": "XYZ"},"field3":{ "nam
e": "field3","label": "My Field 3","value": "Y"},"field4":{ "name": "field4","la
bel": "My Field 4","value": ""},"field5":{ "name": "field5","label": "My Field 5
","value": ""},"field6":{ "name": "field6","label": "My Field 6","value": ""},"f
ield7":{ "name": "field7","label": "My Field 7","value": ""},}}
1 {"fields": {"field1":{ "name": "field1","label": "My Field 1","value": "ABCD"},"
field2":{ "name": "field2","label": "My Field 2","value": "XYZ"},"field3":{ "nam
e": "field3","label": "My Field 3","value": "Y"},"field4":{ "name": "field4","la
bel": "My Field 4","value": ""},"field5":{ "name": "field5","label": "My Field 5
","value": ""},"field6":{ "name": "field6","label": "My Field 6","value": ""},"f
ield7":{ "name": "field7","label": "My Field 7","value": ""},}}
点表示法仅对标记有“is JSON”检查约束的JSON有效 在您的表中,我们知道数据是JSON,但一旦您将其放入视图中,我们就不再有这种信心。毕竟你本可以做的
create view V as
select [some json]
union all
select [some junk]
因此,在本例中,您需要让我们知道JSON确实可以这样处理
SQL> create or replace view JSON_TEST_VIEW as
2 select m.id, treat(m.json_data as json) JSON_DATA
3 from
4 (
5 select id, JSON_DATA
6 from MAIN_TABLE
7 union all
8 select id, JSON_DATA from MAIN_TABLE
9 ) m;
View created.
SQL>
SQL> select * from JSON_TEST_VIEW jtv where jtv.JSON_DATA.fields.field1.value='ABCD';
ID JSON_DATA
---------- --------------------------------------------------------------------------------
1 {"fields": {"field1":{ "name": "field1","label": "My Field 1","value": "ABCD"},"
field2":{ "name": "field2","label": "My Field 2","value": "XYZ"},"field3":{ "nam
e": "field3","label": "My Field 3","value": "Y"},"field4":{ "name": "field4","la
bel": "My Field 4","value": ""},"field5":{ "name": "field5","label": "My Field 5
","value": ""},"field6":{ "name": "field6","label": "My Field 6","value": ""},"f
ield7":{ "name": "field7","label": "My Field 7","value": ""},}}
1 {"fields": {"field1":{ "name": "field1","label": "My Field 1","value": "ABCD"},"
field2":{ "name": "field2","label": "My Field 2","value": "XYZ"},"field3":{ "nam
e": "field3","label": "My Field 3","value": "Y"},"field4":{ "name": "field4","la
bel": "My Field 4","value": ""},"field5":{ "name": "field5","label": "My Field 5
","value": ""},"field6":{ "name": "field6","label": "My Field 6","value": ""},"f
ield7":{ "name": "field7","label": "My Field 7","value": ""},}}
请提供一个问题的最小可复制示例。您能给出一个针对表和视图使用的查询示例吗,除了表和视图的定义之外?我正在简化表和视图的定义。@pmdba我已经用必要的SQL更新了问题以重现问题。请提供一个最小的可重现问题的示例。您能给出一个您正在使用的查询的示例吗,表和视图以及表和视图的定义?我正在简化表和视图的定义。@pmdba我已使用必要的SQL更新了问题,以重现问题。