Stack Overflow на русском Asked on January 28, 2021
Пробую добавить пустую строку к сушности типа JSON_OBJECT_T
, но как результат получаю значение null
, а не пустую строку.
DECLARE
V_OBJ JSON_OBJECT_T;
BEGIN
V_OBJ := JSON_OBJECT_T();
V_OBJ.PUT('customerAccRef','');
DBMS_OUTPUT.PUT_LINE(V_OBJ.stringify);
END;
Результат работы кода выше, следующий JSON:
{"customerAccRef":null}
, но желаемый результат такой:
{"customerAccRef":""}
Может кто-то подсказать, что надо изменить, чтобы получить пустую строку?
Свободный перевод вопроса How to put empty string in JSON_OBJECT_T object? от участника @Kinjan Bhavsar
Для лучшей читаемости, предложил бы как решение квотированный литерал, как то так:
var jsonObject varchar2 (32)
declare
jo json_object_t := json_object_t();
begin
jo.put ('abc', q'""');
:jsonObject := jo.stringify ();
end;
/
JSONOBJECT
----------
{"abc":""}
Две одиночные кавычки ''
это символьный литерал и его значение - пустая строка, а не NULL
. Расхождение со стандартом SQL начинается при присвоении символьного литерала переменной или колонке с конкретным типом данных.
Выше упомянут стандарт SQL, но PL/SQL это не SQL и поведение может отличаться. Например, обе переменные имеют значение NULL
, но как параметры для встроенных функций БД они интерпретируются по разному:
var ret varchar2 (64)
declare
jo json_object_t := json_object_t();
nullstr varchar2(1) := null;
zerostr varchar2(1) := '';
begin
jo.put ('foo', nullstr);
jo.put ('bar', zerostr);
:ret := jo.stringify ()||' # >>'||nullstr||zerostr||'<< '||
case when nullstr is null and zerostr is null then 'both values are null' end;
end;
/
RET
-------------------------------------------------
{"foo":null,"bar":""} # >><< both values are null
Это отличие в поведении пока не документированно.
В SQL, напротив, литерал с пустой строкой при присвоении становится NULL
, никаких отличий в поведении нет:
select
json_object ('foo' value q'""') jo1,
json_object ('bar' value trim (' ')) jo2,
json_object ('baz' value cast ('' as varchar2(1))) jo3
from dual
/
JO1 JO2 JO3
---------------- ---------------- ----------------
{"foo":null} {"bar":null} {"baz":null}
Answered by 0xdb on January 28, 2021
Причина такого поведения, потому что Oracle иннерпретирует пустую строку как NULL
.
Так исторически сложилось, что поведение пустой строки отличается от стандарта SQL, и можно почитать в этом ответе, чтобы ознакомиться с этим более подробно.
Прим.ред.: на SO по русски можно найти аналогичную информацию в этой теме, или в этой с укороченным переводом ответа выше.
Сам я не смог найти нигде в документации по JSON объектам, описания, как обойти эту проблему. Был бы рад, если бы кто-нибудь смог подсказать, где её можно найти.
В качестве пути решения, можно использовать функцию TRIM
для преобразования одного пробела в пустую строку, вот так:
V_OBJ.PUT('customerAccRef' , TRIM(' '));
Что даст:
{"customerAccRef":""}
Похоже, это работает как в версии 12.2, тестировал на локальной машине, так и в 18c db<>fiddle, а также в 19c LiveSQL.
Здесь следует заметить, что запрос select TRIM(' ') from dual
всегда возвращает NULL
. Это удивительно, почему он работает как ожидалось с JSON объектами.
Свободный перевод ответа от участника @Kaushik Nayak
Answered by 0xdb on January 28, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP