25.1 Overview of JSON Generation
An overview is presented of JSON data generation: best practices, the
SQL/JSON generation functions, a simple JSON
constructor syntax, handling of
input SQL values, and resulting generated data.
The best way to generate JSON data from non-JSON database data is to use SQL. The
standard SQL/JSON functions, json_object
, json_array
,
json_objectagg
, and json_arrayagg
are designed
specifically for this. If the generated data is of JSON
type then a handy
alternative is to use the JSON
data type constructor function,
JSON
.
Both make it easy to construct JSON data directly from a SQL query. They allow
non-JSON data to be represented as JSON objects and JSON arrays. You can generate complex,
hierarchical JSON documents by nesting calls to the generation functions or constructor
JSON
. Nested subqueries can generate JSON data that represents one-to-many
relationships.Foot 1
The Best Way to Construct JSON Data from Non-JSON Data
Alternatives to using the SQL/JSON generation functions are generally error prone or inefficient.
-
Using string concatenation to generate JSON documents is error prone. In particular, there are a number of complex rules that must be respected concerning when and how to escape special characters, such as double quotation marks (
"
). It is easy to overlook or misunderstand these rules, which can result in generating incorrect JSON data. -
Reading non-JSON result sets from the database and using client-side application code to generate JSON data is typically quite inefficient, particularly due to network overhead. When representing one-to-many relationships as JSON data, multiple
SELECT
operations are often required, to collect all of the non-JSON data needed. If the documents to be generated represent multiple levels of one-to-many relationships then this technique can be quite costly.
The SQL/JSON generation functions and constructor JSON
do
not suffer from such problems; they are designed for the job of constructing JSON data from
non-JSON database
data.
-
They always construct well-formed JSON documents.
-
By using SQL subqueries with the functions, you can generate an entire set of JSON documents using a single SQL statement, which allows the generation operation to be optimized.
-
Because only the generated documents are returned to a client, network overhead is minimized: there is at most one round trip per document generated.
The SQL/JSON Generation Functions
-
Functions
json_object
andjson_array
construct a JSON object or array, respectively. In the simplest case,json_object
takes SQL name–value pairs as arguments, andjson_array
takes SQL values as arguments. -
Functions
json_objectagg
, andjson_arrayagg
are aggregate SQL functions. They transform information that is contained in the rows of a grouped SQL query into JSON objects and arrays, respectively. Evaluation of the arguments determines the number of object members and array elements, respectively; that is, the size of the result reflects the current queried data.For
json_objectagg
andjson_arrayagg
, the order of object members and array elements, respectively, is unspecified. Forjson_arrayagg
, you can use anORDER BY
clause within thejson_arrayagg
invocation to control the array element order.
Result Returned by SQL/JSON Generation Functions
By default, the generated JSON
data is returned from a generation function as a SQL VARCHAR2(4000)
value.
You can use the optional RETURNING
clause to specify a different
VARCHAR2
size or to specify a JSON
,
CLOB
or BLOB
return value instead. When
BLOB
is the return type, the character set is
AL32UTF8.
Unless the return type is JSON
, the JSON values produced from the
input SQL values are serialized to textual JSON. This serialization has the same effect as
SQL/JSON function json_serialize
.
Note:
SQL/JSON function json_serialize
consistently serializes
values of Oracle JSON-language scalar types, such as float and date, using standard
formats.
For example, it serializes a JSON date value using the ISO 8601 date format
YYYY-MM-DD
.
If you want to generate a textual JSON object or array that contains a JSON string
value in some other format, then provide a string in that format as input to the
generation function. (String input to json_serialize
is simply output as
is.)
For example, if you want json_object
to produce an object with a string
field that has a different ISO 8601 date format, then use SQL conversion function such as
to_char
to provide that string and pass it to
json_object
.
Handling of Input Values For SQL/JSON Generation Functions
The SQL/JSON generation functions take SQL values as input and, from them, produce JSON values inside the JSON object or array that is returned. How the input values produce the JSON values used in the output depends on their SQL data type. See Handling of Input Values For SQL/JSON Generation Functions.
Optional Behavior For SQL/JSON Generation Functions
You can optionally specify a SQL
NULL
-handling clause, a RETURNING
clause, and keywords
STRICT
and WITH UNIQUE KEYS
.
-
NULL
-handling clause — Determines how a SQLNULL
value resulting from input evaluation is handled.-
NULL ON NULL
— An input SQLNULL
value is converted to JSONnull
for inclusion in the output JSON object or array. This is the default behavior forjson_object
andjson_objectagg
. -
ABSENT ON NULL
— An input SQLNULL
value results in no corresponding output. This is the default behavior forjson_array
andjson_arrayagg
. EMPTY STRING ON NULL
An input SQLNULL
value is converted to an empty JSON string,""
for inclusion in the output JSON object or array.
-
-
RETURNING
clause — The SQL data type used for the function return value. The return type can be any of the SQL types that support JSON data:JSON
,VARCHAR2
,CLOB
, orBLOB
. The default return type (noRETURNING
clause) isVARCHAR2(4000)
. -
STRICT
keyword — If present, the returned JSON data is checked to be sure it is well-formed. IfSTRICT
is present and the returned data is not well-formed then an error is raised.Note:
In general, you need not specify
STRICT
when generating data ofJSON
data type, and doing so can introduce a small performance penalty.When an input and the returned data are both of
JSON
type, if you do not specifySTRICT
then that input is used as is in the returned data; it is not checked for strict well-formedness.You might want to use
STRICT
when returningJSON
type data if (1) the input data is also ofJSON
type and (2) you suspect that it is not completely strict. That could be the case, for example, if a client application created the input data and it did not ensure that each JSON string is represented by a valid UTF-8 sequence of bytes. -
WITH UNIQUE KEYS
keywords, when generating textual JSON data — If present, the returned JSON object is checked to be sure there are no duplicate field names. If there are duplicates, an error is raised. These keywords are available only forjson_object
andjson_objectagg
.When generating textual JSON data, if
WITH UNIQUE KEYS
is absent (or ifWITHOUT UNIQUE KEYS
is present) then no check for unique fields is performed. In that case all fields are used, including any duplicates.WITH[OUT] UNIQUE KEYS
has no effect when producingJSON
-type data. An error is always raised when there are duplicate keys if the return type isJSON
.
JSON Data Type Constructor
You can use constructor JSON
with a special syntax as an
alternative to using json_object
and json_array
when
generating data of data type JSON
. (You can use constructor
JSON
and JSON
type only if database initialization
parameter compatible is at least 20. Otherwise an error is raised.)
The only difference in behavior is that the return data type when you use the constructor is always JSON
(there is no RETURNING
clause for the constructor).
When employed as an alternative syntax for json_object
or json_array
, you follow constructor JSON
directly with braces ({}
) and brackets ([]
), respectively, for object and array generation, instead of the usual parentheses (()
).
-
JSON { … }
has the same effect asJSON(json_object( … ))
, which has the same effect asjson_object( … RETURNING JSON)
. -
JSON [ … ]
has the same effect asJSON(json_array( … ))
, which has the same effect asjson_array( … RETURNING JSON)
.
All of the behavior and syntax possibilities that json_object
and
json_array
offer when they are used with RETURNING JSON
are also available when you use constructor JSON
with the special syntax.
See Example 25-2, Example 25-3, Example 25-4, Example 25-5, Example 25-6, Example 25-8, and Example 25-9
JSON {…}
and JSON […]
provide alternative syntax
only for json_object
and json_array
, not for the aggregate
generation functions, json_objectagg
and json_arrayagg
.
But you can pass a SQL query expression as argument to json_array
,
and thus also use it as the (single) argument to JSON […]
. For example,
these two queries are equivalent:
SELECT json_arrayagg(department_name)FROM departments;
SELECT json_array(SELECT department_name FROM departments) FROM DUAL;
And you can of course use constructor JSON
(without the
special syntax) on the result of an explicit call to json_objectagg
or
json_arrayagg
. For example, these two queries are equivalent:
SELECT JSON(json_objectagg(department_name VALUE department_id))
FROM departments;
SELECT json_objectagg(department_name VALUE department_id
RETURNING JSON)
FROM departments;
See Also:
-
Oracle Database SQL Language Reference in Oracle Database SQL Language Reference
-
Oracle Database SQL Language Reference in Oracle Database SQL Language Reference
-
Oracle Database SQL Language Reference in Oracle Database SQL Language Reference
-
Oracle Database SQL Language Reference in Oracle Database SQL Language Reference
-
JSON Type Constructor in Oracle Database SQL Language Reference
Related Topics
Parent topic: Generation of JSON Data Using SQL
Footnote Legend
Footnote 1: The behavior of the SQL/JSON generation functions for JSON data is similar to that of the SQL/XML generation functions for XML data.