It's time to keep writing about Oracle Database 12.1.0.2 new features! In this article we will talk about JavaScript Object Notation better known as "JSON". Wow! Time goes by! I worked with JSON some years ago when I was creating some mobile applications with Android SDK (yes, believe me, I had fun making android apps :) ) and know I am working again with JSON but using Oracle Database. Oracle database starting with 12.1.0.2 supports JSON format. We can now store JSON values inside Oracle Tables and we can recover JSON Values using SQL, it's amazing!. In this article I will show you a few examples about how to work with this. You can manage JSON value with VARCHAR2, CLOB or BLOB and that is what I will show you here.
- JSON using CLOB
- JSON using VARCHAR2
- JSON using BLOB
You can thought "mmm I see here only Data Types for Text" and Yes! that's absolutely right, CLOB and VARCHAR2 are Text data types and in BLOB you can store whatever, so let's say for this case that BLOB is for Text as well. Basically, JSON data is managed inside the database as Text, that's true. As per the Oracle Documentation, Oracle recommends to use BLOB. What oracle introduced is the mechanism to query JSON data using SQL, you can recover a JSON Child using a SELECT sentence for example, but the JSON data inside database is stored as text.
JSON and VARCHAR2
Creating a table with JSON column: We will create the table DGOMEZ.JSON where I will include a column of type VARCHAR2 with a length of 1000 (you decide the length, there is not any specific requirement).
SQL> drop table dgomez.json purge;
Table dropped.
SQL> CREATE TABLE dgomez.json(
id number,
jsondata varchar2(1000)
CONSTRAINT jsoncheck CHECK (jsondata IS JSON));
Table created.
SQL>
Be aware that we are using a CHECK CONSTRAINT called "jsoncheck" and the condition we are using is "IS JSON". "IS JSON" is a condition that verify a Text, parse it and confirm if the Text indeed is JSON formar or if errors exist in the syntax. For example.
Inserting JSON data: Now let's insert a row, put attention on the value we are inserting for the column JSONDATA, as you can see the value is inside ''this is because we are using JSON data as a Text, be sure that the Text you are inserting has JSON format.
Since we have a CHECK CONSTRAINTS that verifies for us the JSON syntax , I will test it. I will insert a row with a value for the JSON column with Syntax errors. between "info" and "name" should be a symbol "{" that's the error that I am typing intentionally.
SQL> INSERT INTO dgomez.json
VALUES (1,
'{"cod" : 10,
"value" : "test10",
"info" : "name" : "Deiby Gomez",
"Address": { "street" : "Guatemala",
"city" : "Guatemala",
"state" : "NA",
"zipCode" : 01111,
"country" : "Guatemala" },
"Phone" : 99999999}}'); 2 3 4 5 6 7 8 9 10 11
INSERT INTO dgomez.json
*
ERROR at line 1:
ORA-02290: check constraint (DGOMEZ.JSONCHECK) violated
SQL>
As you see the insert failed because the CHECK CONSTRAINT validated and found error in the syntax. Now let's insert a value with a correct syntax:
SQL> INSERT INTO dgomez.json
VALUES (1,
'{"cod" : 10,
"value" : "test10",
"info" : {"name" : "Deiby Gomez",
"Address": { "street" : "Guatemala",
"city" : "Guatemala",
"state" : "NA",
"zipCode" : 01111,
"country" : "Guatemala" },
"Phone" : 99999999}}'); 2 3 4 5 6 7 8 9 10 11
1 row created.
SQL> commit;
Commit complete.
SQL>
Querying JSON data: We are ready to query our data. The first thing that you have to know is that you have to use what we (DBAs) call "alias", I think that Oracle see that as a"instance" of the object because you refere to the Oracle Table column with the alias, for example, in the next example "object" is the alias, which is used here as an JSON instance. "jsondata" is the column of our Table (JSON Instance). "info" is a JSON child. If you don't use alias and you try to query the data like if it was a normal Table you will get an error as you can see below:
SQL> select jsondata.cod from dgomez.json;
select jsondata.cod from dgomez.json
*
ERROR at line 1:
ORA-00904: "JSONDATA"."COD": invalid identifier
So... we have to use an alias:
SQL> select object.jsondata.info.Phone from dgomez.json object;
INFO
--------------------------------------------------------------------------------
99999999
there it go! we were able to get our data.
JSON and CLOB
In this section we will work with JSON data but using CLOB data type. Basically, CLOB is the same than VARCHAR2, the only difference is that VARCHAR2 is an small limit for text while CLOB is really longer.
SQL> drop table dgomez.json purge;
Table dropped.
Creating a table with JSON column: As VARCHAR2, let's create a table:
SQL> CREATE TABLE dgomez.json(
id number,
jsondata CLOB
CONSTRAINT jsoncheck CHECK (jsondata IS JSON));
Table created.
SQL>
The only difference with the last example is that now we are using a longer data type which is CLOB.
Inserting JSON data: Inserting a JSON value with CLOB is basically the same that if we were working with VARCHAR2, as you can see below:
SQL> INSERT INTO dgomez.json
VALUES (1,
'{"cod" : 10,
"value" : "test10",
"info" : {"name" : "Deiby Gomez",
"Address": { "street" : "Guatemala",
"city" : "Guatemala",
"state" : "NA",
"zipCode" : 01111,
"country" : "Guatemala" },
"Phone" : 99999999}}');
1 row created.
SQL> commit;
Commit complete.
Querying JSON data: We are able to query our JSON data. Another tip you have to know is that you have to specify the JSON child name exactly how it is, I mean, JSON child name is case sensitive, if you specify the JSON child as if it was no case sensitive you will get no data. In the following example the child "phone" is wrong, the right name is "Phone" with "P" in uppercase, so you will see that we won't get data:
SQL> select object.jsondata.info.phone from dgomez.json object;
INFO
--------------------------------------------------------------------------------
Now I will specify the JSON child name correctly, I mean "Phone" instead of "phone" and then we will be able to get our data:
SQL> select object.jsondata.info.Phone from dgomez.json object;
INFO
--------------------------------------------------------------------------------
99999999
Below some more examples for get data:
SQL> select object.jsondata.cod from dgomez.json object;
COD
--------------------------------------------------------------------------------
10
SQL> select object.jsondata.info.Address.city from dgomez.json object;
INFO
--------------------------------------------------------------------------------
Guatemala
SQL>
JSON and BLOB
The last category is when we store JSON data inside a column of data type BLOB. The documentation says that when we are working with JSON data and BLOB we have to use the functions or conditions: json_value, json_query, json_table and json_exists
However you can manage it as if it was text as well, without using those functions. Of course, you can always use those functions, as I will show in the next examples.
Creating a table with JSON column: As in the other examples, let's create a table, this time with a column of type BLOB.
SQL> drop table dgomez.json purge;
Table dropped.
SQL> CREATE TABLE dgomez.json(
id NUMBER,
jsondata BLOB
CONSTRAINT jsoncheck CHECK (jsondata IS JSON FORMAT JSON)); 2 3 4
Table created.
SQL>
Inserting JSON data: Inserting a value will be quit different, we are using "utl_raw.cast_to_raw" in order to cast the text:
SQL> INSERT INTO dgomez.json
VALUES (1,
utl_raw.cast_to_raw ('{"cod" : 10,
"value" : "test10",
"info" : {"name" : "Deiby Gomez",
"Address": { "street" : "Guatemala",
"city" : "Guatemala",
"state" : "NA",
"zipCode" : 01111,
"country" : "Guatemala" },
"Phone" : 99999999}}')); 2 3 4 5 6 7 8 9 10 11
1 row created.
SQL> commit;
Commit complete.
SQL>
Since we are using "utl_raw.cast_to_raw" to inser the data, we don't need to use any of the following functions or conditions: json_value, json_query, json_table and json_exists. We can query the JSON Data as before when we were working with CLOB and VARCHAR2:
Querying JSON data:
SQL> select object.jsondata.info.Phone from dgomez.json object;
INFO
--------------------------------------------------------------------------------
99999999
SQL> select object.jsondata.info.Address.city from dgomez.json object;
INFO
--------------------------------------------------------------------------------
Guatemala
Follow me: