Проблема с запросом Oracle 12c JSON с точечной нотацией и двойными кавычками

У меня есть таблица «EvMetadata» со столбцом «Метаданные», в которой есть проверочное ограничение «IS JSON». Обратите внимание, что таблица и ее столбцы изначально созданы с использованием ДВОЙНЫХ КАТЫЧОК.

Следующий SQL работает там, где я не указываю какую-либо работу JSON, которую должен выполнять Oracle.

select 
  m."Metadata"
from "EvMetadata" m

Как вы можете видеть ниже, столбец метаданных просто отображает свое содержимое, которое является данными JSON.

Показ содержимого столбца метаданных в формате JSON

Однако я получаю сообщение об ошибке, если я должен выполнить запрос json следующим образом.

select 
  m."Metadata"."FileName"
from "EvMetadata" m

Я только что добавил «Имя файла», используя запись через точку. Как вы можете видеть выше, «FileName» является допустимым полем json. Так почему ошибка?

Ошибка

ORA-00904: "M"."Метаданные"."FileName": неверный идентификатор 00904. 00000 - "%s: неверный идентификатор" *Причина: *Действие: Ошибка в строке: 2 Столбец: 3

Может ли это быть ошибкой с поддержкой запросов Oracle JSON с использованием точечной нотации в конкретном сценарии, когда объекты базы данных объявляются с двойными кавычками? Причина, по которой я подозреваю, что это может быть правдой, заключается в том, что следующий эквивалентный запрос, не использующий запись через точку, работает.

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

person SamDevx    schedule 22.07.2015    source источник
comment
На самом деле я сталкиваюсь с той же проблемой и не нахожу подходящего ответа после нескольких часов поиска в Интернете. Надеюсь, награда привлечет там достаточно внимания.   -  person ffarquet    schedule 26.09.2015
comment
Что произойдет, если вы запустите проекцию записи через точку без двойных кавычек? select m.Metadata.FileName from "EvMetadata" m Я видел только точечную запись без кавычек вокруг полей, и я полагаю, что смешанный регистр, требующий кавычек, усложняет выполнение.   -  person leroyJr    schedule 26.09.2015
comment
В моем случае я пробовал оба с той же проблемой. Думаю, Oracle относится к ним так же. Кавычки нужны только для того, чтобы обеспечить правильную обработку специальных символов.   -  person ffarquet    schedule 29.09.2015


Ответы (3)


Вам нужно иметь проверочное ограничение «IS JSON» для столбца, чтобы точечная запись работала:

Вот выдержка из документации:

Каждый ключ json_key должен быть допустимым идентификатором SQL, а столбец должен иметь ограничение проверки json, которое гарантирует, что он содержит правильно сформированные данные JSON. Если какое-либо из этих правил не соблюдается, возникает ошибка во время компиляции запроса. (Ограничение проверки должно присутствовать, чтобы избежать возникновения ошибки, однако оно не обязательно должно быть активным. Если вы деактивируете ограничение, эта ошибка не возникает.)

Вот тестовый пример, который я сделал, чтобы проверить, как это работает:

--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                                                                               
person Snowbuilder    schedule 14.06.2016
comment
псевдоним таблицы был моей проблемой ... Спасибо! - person Toolkit; 29.10.2018

Если у кого-то еще возникнет эта проблема, она задокументирована в службе поддержки Oracle под примечанием 2192052.1.

По сути, это ошибка, из-за которой точечная нотация не работает для столбца, созданного с ограничением NOT NULL, т.е.

Если вы сделаете:

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);

запись через точку будет работать.

person Andrew Tindle    schedule 09.12.2016
comment
Блестящий ответ - person Andremoniy; 22.07.2021

Вам не нужны кавычки, это должно работать:

select m.Metadata.FileName from EvMetadata m

См. пример официальной документации:

SELECT po.po_document.PONumber FROM j_purchaseorder po;

SELECT json_value(po_document, '$.PONumber') FROM j_purchaseorder;

person Aram Antonyan    schedule 02.10.2015
comment
Oracle обращается с кавычками и без кавычек точно так же, когда речь идет о нотации JSON. Но кавычки позволяют использовать специальные символы в имени ключа. - person ffarquet; 03.10.2015