22.2 COLUMNS Clause of SQL/JSON Function JSON_TABLE
The mandatory COLUMNS clause for SQL/JSON function
json_table defines the columns of the virtual table that the function
creates.
It consists of the keyword COLUMNS followed by the
following entries, enclosed in parentheses. Other than the optional FOR
ORDINALITY entry, each entry in the COLUMNS clause is
either a regular column specification or a nested columns specification.
-
At most one entry in the
COLUMNSclause can be a column name followed by the keywordsFOR ORDINALITY, which specifies a column of generated row numbers (SQL data typeNUMBER). These numbers start with one. For example:COLUMNS (linenum FOR ORDINALITY, ProductID)An array step in a row path expression can lead to any number of rows that match the path expression. In particular, the order of array-step indexes and ranges, multiple occurrences of an array index, and duplication of a specified position due to range overlaps produce one row for each position match. The ordinality row numbers reflect this.
-
A regular column specification consists of a column name followed by an optional data type for the column, which can be any SQL data type that can be used in the
RETURNINGclause ofjson_value, followed by an optional value clause and an optionalPATHclause. The default data type isVARCHAR2(4000).The column data type can thus be any of these:
BINARY_DOUBLE,BINARY_FLOAT,BOOLEAN,CHAR,CLOB,DATE(with optional keywordsPRESERVE TIMEorTRUNCATE TIME),DOUBLE PRECISION,FLOAT,INTEGER,NUMBER,INTERVAL YEAR TO MONTH,INTERVAL DAY TO SECOND,NCHAR,NCLOB,NVARCHAR2,RAWFoot 1,REAL,SDO_GEOMETRY,TIMESTAMP,TIMESTAMP WITH TIME ZONE, andVARCHAR2. You can also use a user-defined object type or a collection type.Data type
SDO_GEOMETRYis used for Oracle Spatial and Graph data. In particular, this means that you can usejson_tablewith GeoJSON data, which is a format for encoding geographic data in JSON.Oracle extends the SQL/JSON standard in the case when the returning data type for a column is
VARCHAR2(N), by allowing optional keywordTRUNCATEimmediately after the data type. WhenTRUNCATEis present and the value to return is wider thanN, the value is truncated — only the firstNcharacters are returned. IfTRUNCATEis absent then this case is treated as an error, handled as usual by an error clause or the default error-handling behavior. -
A nested columns specification consists of the keyword
NESTEDfollowed by an optionalPATHkeyword, a SQL/JSON row path expression, and then aCOLUMNSclause. ThisCOLUMNSclause specifies columns that represent nested data. The row path expression used here provides a refined context for the specified nested columns: each nested column path expression is relative to the row path expression. You can nest columns clauses to project values that are present in arrays at different levels to columns of the same row.A
COLUMNSclause at any level (nested or not) has the same characteristics. In other words, theCOLUMNSclause is defined recursively. For each level of nesting (that is, for each use of keywordNESTED), the nestedCOLUMNSclause is said to be the child of theCOLUMNSclause within which it is nested, which is its parent. Two or moreCOLUMNSclauses that have the same parent clause are siblings.The virtual tables defined by parent and child
COLUMNSclauses are joined using an outer join, with the parent being the outer table. The virtual columns defined by siblingCOLUMNSclauses are joined using aunionjoin.Example 22-1 and Example 22-9 illustrate the use of a nested columns clause.
The only thing required in a regular column specification is the column name. Defining the column projection in more detail, by specifying a scalar data type, value handling, or a target path, is optional.
-
The optional value clause specifies how to handle the data projected to the column: whether to handle it as would
json_value,json_exists, orjson_query. This value handling includes the return data type, return format (pretty or ASCII), wrapper, and error treatment.If you use keyword
EXISTSthen the projected data is handled as if byjson_exists(regardless of the column data type).Otherwise:
-
For a column of data type
JSON, the projected data is handled as if byjson_query. -
For a non-
JSONtype column (any type that can be used in ajson_valueRETURNINGclause), the projected data is handled by default as if byjson_value. But if you use keywordsFORMAT JSONthen it is handled as if byjson_query. You typically useFORMAT JSONonly when the projected data is a JSON object or array. (An error is raised if you useFORMAT JSONwith aJSONtype column.)
For example, here the value of column
FirstNameis projected directly usingjson_valuesemantics, and the value of columnAddressis projected as a JSON string usingjson_querysemantics:COLUMNS (FirstName, Address FORMAT JSON)If
json_valuesemantics are used then the targeted data can alternatively be a JSON array of numbers instead of a JSON scalar value, if theRETURNINGtype isVECTOR. An error is raised for array input if the return type is notVECTORor if the array has any non-number elements.json_querysemantics imply that the projected JSON data is well-formed. If the column is a non-JSONtype then this includes ensuring that non-ASCII characters in string values are escaped as needed. For example, a TAB character (CHARACTER TABULATION, U+0009) is escaped as\t. (ForJSONtype data, any such escaping is done when theJSONdata is created, not whenjson_queryis used.)When the column has
json_querysemantics:-
If database initialization parameter
compatibleis at least20then you can use keywordsDISALLOW SCALARSto affect thejson_querybehavior by excluding scalar JSON values. -
You can override the default wrapping behavior by adding an explicit wrapper clause.
You can override the default error handling for a given handler (
json_exists,json_value, orjson_query) by adding an explicit error clause appropriate for it. -
-
The optional
PATHclause specifies the portion of the row that is to be used as the column content. The column path expression following keywordPATHis matched against the context item provided by the virtual row. The column path expression must represent a relative path; it is relative to the path specified by the row path expression.If the
PATHclause is not present then the behavior is the same as if it were present with a path of'$.<column-name>', where<column-name>is the column name. That is, the name of the object field that is targeted is taken implicitly as the column name.For purposes of specifying the targeted field only, the SQL identifier used for
<column-name>is interpreted case-sensitively, even if it is not quoted. The SQL name of the column itself follows the usual rule: if it is enclosed in double quotation marks (") then the letter case used is significant; otherwise, it is not (it is treated as if uppercase).For example, these two
COLUMNSclauses are equivalent. For SQL, case is significant only for columnComments(because it is quoted). The other two columns have case-insensitive names (that is, their names are treated case-insensitively), regardless of whether aPATHclause is used. In the firstCOLUMNSclause the first two columns are written with mixed case that matches the field names they target implicitly.COLUMNS(ProductId, Quantity NUMBER, "Comments") COLUMNS(productid VARCHAR2(4000) PATH '$.ProductId', quantity NUMBER PATH '$.Quantity', "Comments" VARCHAR2(4000) PATH '$.Comments')Example 22-1 presents equivalent queries that illustrate this.
You can also use the dot notation in a
PATHclause, as an alternative to a SQL/JSON path expression. Example 22-2 and Example 22-9 illustrate this.
In a column path-expression array step, the order of indexes and ranges, multiple occurrences of an array index, and duplication of a specified position due to range overlaps have the effect they would have for the particular semantics use for the column: json_exists, json_query, or json_value:
-
json_exists— All that counts is the set of specified positions, not how they are specified, including the order or number of times they are specified. All that is checked is the existence of a match for at least one specified position. -
json_query— Each occurrence of a specified position is matched against the data, in order. -
json_value— If only one position is specified then it is matched against the data. Otherwise, there is no match — by default (NULL ON ERROR) a SQLNULLvalue is returned.
A columns clause with json_value semantics also accepts the
optional keyword combination TYPE (STRICT) following the
PATH clause. This has the same meaning and behavior as when it is
used in connection with the RETURNING clause of
json_value. For example, these two queries are equivalent. Only
PONumber fields whose value is numeric are considered
(projected).
SELECT jt.ponumb
FROM j_purchaseorder,
json_table(data, '$'
COLUMNS (ponumb NUMBER PATH '$.PONumber.numberOnly()')) jtSELECT jt.ponumb
FROM j_purchaseorder,
json_table(data, '$'
COLUMNS (ponumb NUMBER PATH '$.PONumber' TYPE (STRICT))) jtSee Also:
-
Oracle Spatial Developer's Guide for information about using Oracle Spatial and Graph data
Related Topics
- RETURNING Clause for SQL Functions
- Wrapper Clause for SQL/JSON Query Functions JSON_QUERY and JSON_TABLE
- Error Clause for SQL Functions and Conditions
- Empty-Field Clause for SQL/JSON Query Functions
- SQL/JSON Function JSON_QUERY
- Support for RFC 8259: JSON Scalars
- TYPE Clause for SQL Functions and Conditions
Parent topic: SQL/JSON Function JSON_TABLE
Footnote Legend
Footnote 1: You can useRAW as the return type only when the input data is of
JSON data type.