在Oracle视图中的JSON列上使用点表示法

在Oracle视图中的JSON列上使用点表示法,json,oracle,Json,Oracle,我试图弄清楚如何将JSON列从表中拉入视图,并且仍然能够在WHERE子句中使用点表示法 我目前已经正确定义了列,并且可以在直接命中表的查询中的WHERE子句中使用点表示法。我遇到的问题是,该表当前在一个视图中使用,我需要使用该视图返回所有相关数据 如果我只是在视图定义中包含列,我将失去使用点表示法在字符串中搜索值的能力 如果我在从视图检索数据的查询中将视图连接回这个表,我就能够在where子句中使用点表示法,但是,我会受到巨大的性能影响(慢4-5倍) 下面是存储在每一行中的JSON示例 {&qu

我试图弄清楚如何将JSON列从表中拉入视图,并且仍然能够在
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更新了问题,以重现问题。