Simple Dot-Notation Access to JSON Data
This query selects the value of field PONumber from the
po_document JSON type column and returns it as a JSON value.
SELECT po.po_document.PONumber FROM j_purchaseorder po;The returned value is an instance of JSON data type.
However, JSON values are generally not so useful in SQL. Instead of returning JSON data,
you may want to return an instance of a SQL scalar data type. You do that by applying an
item method to the targeted data. This query, like the previous one, selects the value
of field PONumber, but it returns it as a NUMBER SQL
value.
SELECT po.po_document.PONumber.number() FROM j_purchaseorder po;An item method transforms the targeted JSON data. The transformed data is then processed and returned by the query in place of that original data. When you use dot-notation syntax you generally want to use an item method. Consider the following:
-
A dot-notation query with an item method always returns a SQL scalar value. It has the effect of using the
JSON_VALUESQL/JSON function to convert a JSON scalar value to a SQL scalar value. -
A dot-notation query without an item method always returns JSON data. It has the effect of using the
JSON_QUERYSQL/JSON function (orJSON_TABLEwith a column that hasJSON_QUERYsemantics).
Example 3-1 shows equivalent dot-notation and JSON_VALUE queries. Example 3-2 shows equivalent dot-notation and JSON_QUERY queries.
Dot Notation With an Item Method
A dot-notation query that uses an item method is equivalent to a
JSON_QUERY query with a RETURNING clause that
returns a scalar SQL type—the type that is indicated by the item method.
For example, if the number() item method is applied to JSON data
that can be transformed to a number then the result is a NUMBER SQL
value; if date() item method is applied to data that is in a
supported ISO 8601 date or date-time format then the result is a
DATE SQL value; and so on.
Dot Notation Without an Item Method
If a dot-notation query does not use an item method then a SQL value representing JSON data is returned.
If a dot-notation query does not use an item method then the returned JSON data depends on the targeted JSON data, as follows:
-
If a single JSON value is targeted, then that value is returned, whether it is a JSON scalar, object, or array.
-
If multiple JSON values are targeted, then a JSON array, whose elements are those values, is returned. (The order of the array elements is undefined.)
This behavior contrasts with that of JSON_VALUE and
JSON_QUERY SQL/JSON functions, which you can use for more
complex queries. They can return NULL or raise an error if the path
expression you provide them does not match the queried JSON data. They accept
optional clauses to specify:
-
The data type of the return value (
RETURNINGclause) -
Whether or not to wrap multiple values as an array (
WRAPPERclause) -
How to handle errors generally (
ON ERRORclause) -
How to handle missing JSON fields (
ON EMPTYclause)
When a single value JSON value is targeted, the dot-notation behavior is similar to
that of function JSON_VALUE for a JSON scalar value, and it is
similar to that of JSON_QUERY for an object or array value. When
multiple values are targeted, the behavior is similar to that of
JSON_QUERY with an array wrapper.
Dot Notation Syntax
The dot-notation syntax is a table alias followed by dot or period
(.), the name of the JSON type column, and one or more pairs of
a dot or period (.) and a json_field or a
json_field followed by an
array_step, where json_field is
a JSON field name and array_step is an array step expression
as described in Basic SQL/JSON Path Expression Syntax.
table_alias.column_name.json_field[array_step]{.json_field[array_step] ...}
Each json_field must have the syntax of a valid
SQL identifier, and the column must be of JSON data type. If either of these rules
is not respected then an error is raised at query compile time.
For JSON dot-notation queries, unquoted identifiers (after the column
name) are case sensitive, just as if they were quoted. In other words, you can use
JSON field names as identifiers without quoting them. For example, you can use
po.po_document.PONumber instead of
po.po_document."PONumber"—the meaning is the same. This also
means that if a JSON field name is uppercase or pascal case, such as
PONumber, then you must use
po.po_document.PONumber, not
po.po_document.ponumber.
Here are some examples of dot-notation syntax. All examples use
po as table alias for the j_purchaseorder
table and refer to the po_document JSON type column in such
table.
-
po.po_document.PONumber: Queries the value of thePONumberfield. The query returns an instance ofJSONtype. -
po.po_document.PONumber.number(): Queries the value of thePONumberfield. Thenumber()item method ensures that the query returns aNUMBERSQL value. -
po.po_document.LineItems[1]: Queries the value of the second element inLineItemsarray. The query returns an instance ofJSONtype. -
po.po_document.LineItems[*]: Queries all the elements of theLineItemsarray. The query returns an instance ofJSONtype. -
po.po_document.ShippingInstructions.name: Queries the value of thenamefield, a child of the JSON object that is the value of theShippingInstructionsfield. The query returns an instance ofJSONtype.
Matching of a JSON dot-notation expression against JSON data is the same
as matching of a SQL/JSON path expression, including the relaxation to allow implied
array iteration (see SQL/JSON Path Expression Syntax Relaxation). The JSON type column of a dot-notation expression corresponds
to the context item of a path expression, and each identifier used in the dot
notation corresponds to an identifier used in a path expression.
For example, if the po_document JSON type column corresponds to the
path-expression context item, then the
po_document.ShippingInstructions expression corresponds to the
$.ShippingInstructions path expression and
po_document.ShippingInstructions.name corresponds to
$.ShippingInstructions.name.
For the latter example, the context item could be an object or an array of objects.
If it is an array of objects then each of the objects in the array is matched for a
ShippingInstructions field. The value of the
ShippingInstructions field can itself be an object or an array
of objects. In the latter case, the first object in the array is used.
Note:
Other than the implied use of a wildcard for array elements (see
SQL/JSON Path Expression Syntax Relaxation) and the explicit use of a wildcard between array brackets
([*]), you cannot use wildcards in a path expression when
you use the dot-notation syntax. This is because an asterisk
(*) is not a valid SQL identifier. For example, this raises a
syntax error: po.po_document.LineItems.*.Description
Dot-notation syntax is a handy alternative to using simple path expressions; it is not a replacement for using path expressions in general.
Example 3-1 JSON Dot-Notation Query Compared With JSON_VALUE
Given the data from Example 2-2, each of these queries returns 1599 and 1600 as
JSON numbers.
SELECT po.po_document.PONumber FROM j_purchaseorder po;
SELECT JSON_VALUE(po_document, '$.PONumber') FROM j_purchaseorder;
Each of these queries returns 1599 and 1600 as
NUMBER SQL values.
SELECT po.po_document.PONumber.number() FROM j_purchaseorder po;
SELECT JSON_VALUE(po_document, '$.PONumber.number()') FROM j_purchaseorder;
Example 3-2 JSON Dot-Notation Query Compared With JSON_QUERY
Given the data from Example 2-2, each of these queries returns an array of JSON objects representing phone numbers.
SELECT po.po_document.ShippingInstructions.Phone FROM j_purchaseorder po;
SELECT JSON_QUERY(po_document, '$.ShippingInstructions.Phone') FROM j_purchaseorder;
Each of these queries returns an array of JSON strings representing phone types.
SELECT po.po_document.ShippingInstructions.Phone.type FROM j_purchaseorder po;
SELECT JSON_QUERY(po_document, '$.ShippingInstructions.Phone.type' WITH WRAPPER)
FROM j_purchaseorder;