带点符号和双引号的Oracle 12c JSON查询问题

带点符号和双引号的Oracle 12c JSON查询问题,json,oracle,syntax,oracle12c,Json,Oracle,Syntax,Oracle12c,我有一个表“EvMetadata”,其中列“Metadata”的检查约束为“IS JSON”。请注意,表及其列是按设计用双引号创建的 下面的SQL在我没有指定任何要由Oracle完成的JSON工作的情况下工作 select m."Metadata" from "EvMetadata" m 正如您在下面看到的,元数据列只显示其内容,而内容恰好是JSON数据 然而,如果我发出一个json查询,我会得到一个错误,如下所示 select m."Metadata"."FileName" f

我有一个表“EvMetadata”,其中列“Metadata”的检查约束为“IS JSON”。请注意,表及其列是按设计用双引号创建的

下面的SQL在我没有指定任何要由Oracle完成的JSON工作的情况下工作

select 
  m."Metadata"
from "EvMetadata" m
正如您在下面看到的,元数据列只显示其内容,而内容恰好是JSON数据

然而,如果我发出一个json查询,我会得到一个错误,如下所示

select 
  m."Metadata"."FileName"
from "EvMetadata" m
我只是用点符号添加了“文件名”。如上所示,“FileName”是一个有效的json字段。那么为什么会出现错误呢

错误是

ORA-00904:“M”“元数据”“文件名”:无效标识符00904。00000-“%s:无效标识符”*原因:*操作:第2行第3列出错

在使用双引号声明数据库对象的特定场景下,这可能是Oracle使用点表示法支持JSON查询的错误吗?我怀疑这可能是真的,因为下面的等价查询不使用点表示法,可以工作

select 
  JSON_VALUE(m."Metadata", '$.FileName')
from "EvMetadata" m

您不需要报价,这应适用于:

从EvMetadata m中选择m.Metadata.FileName

请参考官方的例子:

从j_采购订单po中选择po.po_document.PONumber

从j_purchaseorder中选择json_值(po_文档,$.PONumber)

您需要在列上有一个“IS JSON”检查约束,点表示法才能工作:

以下是文档的摘录:

每个json_键必须是有效的SQL标识符,列必须具有is json检查约束,这确保它包含格式良好的json数据。如果不遵守这些规则中的任何一条,则会在查询编译时引发错误。(必须存在check约束以避免引发错误;但是,它不需要处于活动状态。如果停用约束,则不会引发此错误。)

下面是我做的一个测试示例,以验证它是如何工作的:

--create a table to put stuff in
create table foo (
 json varchar2(4000)
);
--------------------------------
Table FOO created.

--insert test value
insert into foo(json) values('{"attr1":5,"attr2":"yes"}');
commit;
--------------------------------
1 row inserted.
Commit complete.


--try some selects
--no table alias, no constraint, borked
select json.attr1 from foo;
--------------------------------
Error starting at line : 12 in command -
select json.attr1 from foo
Error at Command Line : 12 Column : 8
Error report -
SQL Error: ORA-00904: "JSON"."ATTR1": invalid identifier
00904. 00000 -  "%s: invalid identifier"
*Cause:    
*Action:


--with table alias, no constraint, borked
select a.json.attr1 from foo a;
--------------------------------
Error starting at line : 15 in command -
select a.json.attr1 from foo a
Error at Command Line : 15 Column : 8
Error report -
SQL Error: ORA-00904: "A"."JSON"."ATTR1": invalid identifier
00904. 00000 -  "%s: invalid identifier"
*Cause:    
*Action:


--add our constraint
alter table foo add constraint json_isjson check (json is json);
--------------------------------
Table FOO altered.

--no table alias, with constraint, borked
select json.attr1 from foo;
--------------------------------
Error starting at line : 21 in command -
select json.attr1 from foo
Error at Command Line : 21 Column : 8
Error report -
SQL Error: ORA-00904: "JSON"."ATTR1": invalid identifier
00904. 00000 -  "%s: invalid identifier"
*Cause:    
*Action:


--table alias and constraint, works!
select a.json.attr1 from foo a;
--------------------------------
ATTR1                                                                          
--------------------------------------------------------------------------------
5                                                                               

如果其他任何人遇到此问题,请将其记录在Oracle支持中的注释2192052.1中

基本上,这是一个错误,点表示法在使用NOTNULL约束创建的列上不起作用,即

如果您这样做:

CREATE TABLE foo.bar (id NUMBER NOT NULL, json_doc CLOB NOT NULL CHECK (json_doc IS JSON));
当您运行以下命令时,将出现错误:

SELECT a.json_doc.elementName FROM foo.bar a;
但如果你这样做了:

CREATE TABLE foo.bar (id NUMBER NOT NULL, json_doc CLOB CHECK (json_doc IS JSON));
ALTER TABLE bar MODIFY (json_doc NOT NULL);

点表示法会起作用。

事实上,我面临着同样的问题,在数小时的网络搜索之后,我没有找到任何相关的答案。希望悬赏能引起足够的注意。如果你在没有双引号的情况下运行点符号投影会发生什么
select m.Metadata.FileName from“EvMetadata”m
我只看到点表示法在字段周围没有引号的情况下工作,我认为需要引号的混合情况会使执行复杂化。在我的例子中,我尝试了这两种方法,但遇到了相同的问题。我想甲骨文也会这样对待他们。引号只是为了确保特殊字符的正确处理。当谈到JSON符号时,Oracle对引号和未引号的处理方式完全相同。但是引号让您在键名中有特殊字符。表别名是我的问题。。。谢谢