oracle CLOB modify to obtain columns for json_table() - json

Since oracle does not support dynamic conversion of JSON column keys as relational column and JSON column value as relational column value, I had thought to generate my dynamic list of columns as CLOB column
col_a,col_b,col_c,col_d
and then convert it into below form
col_a NUMBER(22,3) PATH '$.col_a',col_b NUMBER(22,3) PATH '$.col_b',col_c NUMBER(22,3) PATH '$.col_c',col_d NUMBER(22,3) PATH '$.col_d'
Basically each of my column "col_a" is converted to "col_a NUMBER(22,3) PATH '$.col_a'"
so that I can directly place this clob value in my plsql block and fetch like below
select t.*,jt.*
from
table_1 t,
json_table(t.json_doc,'$' columns (col_a NUMBER(22,3) PATH '$.col_a',col_b NUMBER(22,3) PATH '$.col_b',col_c NUMBER(22,3) PATH '$.col_c',col_d NUMBER(22,3) PATH '$.col_d'))jt
but I'm not sure if i can do it using REPLACE or any other function.
I'm able to achieve it by concatenating while generating the original list of dynamic columns, but that additional burden I want to avoid.
NOTE: All columns are NUMBER(22,3) datatypes so not a burden on that side.

If your CLOB is valid JSON, you may be able to retrieve the keys for your CLOB using the function json_dataguide. Below is an example
My Table
create table json_doc (
data clob check (data is json)
);
insert into json_doc(data) values ('{"col1": "A"}');
insert into json_doc(data) values ('{"col2": "B"}');
Checking the table
select doc.data from json_doc doc;
-- DATA
-- 1 {"col1": "A"}
-- 2 {"col2": "B"}
Then using json_dataguide
select json_dataguide(doc.data) columns from json_doc doc;
-- COLUMNS
-- 1 [{"o:path":"$","type":"object","o:length":16},{"o:path":"$.col1","type":"string","o:length":1},{"o:path":"$.col2","type":"string","o:length":1}]
Finally, using json_table
select jt.* from
(select json_dataguide(doc.data) columns from json_doc doc) d,
json_table(d.columns, '$[*]' COLUMNS (
path varchar2(22) path '$."o:path"'
)) jt
-- PATH
-- 1 $
-- 2 $.col1
-- 3 $.col2
You can then get the JSON keys including the root (which you can easily remove as well as the $. in the beginning, perhaps using LTRIM).
If this solves your problem, remember to mark it as the answer ;)

Related

Unnest key value pairs from json object

I have a map with multiple key value pairs and I want to unnest them into separate rows.
"dayValueMap": {
"2022-06-01": 1,
"2022-06-02": 1,
"2022-06-03": 1,
"2022-06-04": 1,
"2022-06-05": 1,
"2022-06-06": 1,
}
I tried JSON_EXTRACT but that only extracts json from particular schema. Here I need to convert these key values as separate rows and in the map keys are dynamic.
Can someone help?
In MySQL 8.0 you can use:
JSON_KEYS: to extract the array of keys from "$.dayValueMap" path
JSON_TABLE: to generate a table containing your extracted keys, one per record
JSON_EXTRACT: to extract the value from your table, using the previously extracted keys
SELECT json_key,
JSON_EXTRACT(info, CONCAT('$.dayValueMap.', json_key)) AS json_value
FROM tab,
JSON_TABLE(
JSON_KEYS(info, '$.dayValueMap'), '$[*]'
COLUMNS(
json_key JSON PATH '$'
)
) t;
Check the demo here.

How do I return a JSON updated document in Oracle?

From the docs I see an example:
SELECT json_mergepatch(po_document, '{"Special Instructions":null}'
RETURNING CLOB PRETTY)
FROM j_purchaseorder;
But When I try this code in SQL Developer I get a squiggly line under CLOB and an error when I run the query?
It works in Oracle 18c:
SELECT json_mergepatch(
po_document,
'{"Special Instructions":null}'
RETURNING CLOB PRETTY
) AS updated_po_document
FROM j_purchaseorder;
Which for the test data:
CREATE TABLE j_purchaseorder( po_document CLOB CHECK ( po_document IS JSON ) );
INSERT INTO j_purchaseorder ( po_document )
VALUES ( '{"existing":"value", "Special Instructions": 42}' );
Outputs:
| UPDATED_PO_DOCUMENT |
| :------------------------------- |
| {<br> "existing" : "value"<br>} |
Removing the Special Instructions attribute as per the documentation you linked to:
When merging object members that have the same field:
If the patch field value is null then the field is dropped from the source — it is not included in the result.
Otherwise, the field is kept in the result, but its value is the result of merging the source field value with the patch field value. That is, the merging operation in this case is recursive — it dives down into fields whose values are themselves objects.
db<>fiddle here

Oracle reading JSON data using json_query

While working on oracle json datatype and trying to extract data from it, not able to extract name & value elements from this. tried using all known notations but getting null.
select json_query(po_document, '$.actions.parameters[0]') from j_purchaseorder where ID='2';
You can use the JSON_VALUE function as follows:
SQL> select JSON_VALUE('{"_class":"123", "name":"tejash","value":"so"}', '$.name') as name,
2 JSON_VALUE('{"_class":"123", "name":"tejash","value":"so"}', '$.value') as value
3 from dual;
NAME VALUE
---------- ----------
tejash so
SQL>
Thanks for your help. got required output using below
select json_value(json_query(po_document, '$.actions.parameters[0]'),'$.value') from j_purchaseorder where ID='2' and
json_value(json_query(po_document, '$.actions.parameters[0]'),'$.name') = 'SERVERUSER';
As explained, for example, in the Oracle documentation, multiple calls to JSON_VALUE() on the same JSON document may result in very poor performance. When we need to extract multiple values from a single document, it is often best (for performance) to make a single call to JSON_TABLE().
Here is how that would work on the provided document. First I create and populate the table, then I show the query and the output. Note the handling of column (attribute) "_class", both in the JSON document and in the SQL SELECT statement. In both cases the name must be enclosed in double-quotes, because it begins with an underscore.
create table j_purchaseorder (
id number primary key,
po_document clob check (po_document is json)
);
insert into j_purchaseorder (id, po_document) values (
2, '{"_class":"hudson.model.StringParameterValue","name":"SERVERUSER","value":"avlipwcnp04"}'
);
commit;
select "_CLASS", name, value
from j_purchaseorder
cross apply
json_table(po_document, '$'
columns (
"_CLASS" varchar2(40) path '$."_class"',
name varchar2(20) path '$.name',
value varchar2(20) path '$.value'
)
)
where id = 2
;
_CLASS NAME VALUE
---------------------------------------- ------------------ ------------------
hudson.model.StringParameterValue SERVERUSER avlipwcnp04

How to convert Result set into Json in MYSQL

select id,name,age from person where id=1;
This query gives result like below
id | name | age
1 |manoj | 20
I want a JSON like below
"{"id":1,"name":"manoj","age":5}"
I want a dynamic way.When I try another query from another table ,that result as like previous JSON
I want to generate JSON from a table and store into a column in MYSQL, I don't want to use php or other server side language for generate this JSON.
How can I get JSON in MYSQL ?
Use the JSON_OBJECT() function:
SELECT JSON_OBJECT('id', id, 'name', name, 'age', age)
FROM person
WHERE id = 1;
This requires at least MySQL 5.7 or MariaDB 10.2.3, that's when all the JSON-related functions were added.
If you don't want to hard-code the column names into the query, you'll need to write a stored procedure that creates dynamic SQL, using INFORMATION_SCHEMA.COLUMNS to get all the column names.
Look into JSON data type and JSON functions. If column is of JSON data type and insert string is in JSON format it's easy to insert and retrieve too.
MySQL JSON data type
JSON functions

how to parse json using json_populate_recordset in postgres

I have a json stored as text in one of my database row. the json data is as following
[{"id":67272,"name":"EE_Quick_Changes_J_UTP.xlsx"},{"id":67273,"name":"16167.txt"},{"id":67274,"name":"EE_12_09_2013_Bcum_Searchall.png"}]
to parse this i want to use postgresql method
json_populate_recordset()
when I post a command like
select json_populate_recordset(null::json,'[{"id":67272,"name":"EE_Quick_Changes_J_UTP.xlsx"},{"id":67273,"name":"16167.txt"},{"id":67274,"name":"EE_12_09_2013_Bcum_Searchall.png"}]') from anoop;
it gives me following error
first argument of json_populate_recordset must be a row type
note : in the from clause "anoop" is the table name.
can anyone suggest me how to use the json_populate_recordset method to extract data from this json string.
I got method's reference from
http://www.postgresql.org/docs/9.3/static/functions-json.html
The first argument passed to pgsql function json_populate_recordsetshould be a row type. If you want to use the json array to populate the existing table anoop you can simply pass the table anoop as the row type like this:
insert into anoop
select * from json_populate_recordset(null::anoop,
'[{"id":67272,"name":"EE_Quick_Changes_J_UTP.xlsx"},
{"id":67273,"name":"16167.txt"},
{"id":67274,"name":"EE_12_09_2013_Bcum_Searchall.png"}]');
Here the null is the default value to insert into table columns not set in the json passed.
If you don't have an existing table, you need to create a row type to hold your json data (ie. column
names and their types) and pass it as the first parameter, like this anoop_type:
create TYPE anoop_type AS (id int, name varchar(100));
select * from json_populate_recordset(null :: anoop_type,
'[...]') --same as above
no need to create a new type for that.
select * from json_populate_recordset(null::record,'[{"id_item":1,"id_menu":"34"},{"id_item":2,"id_menu":"35"}]')
AS
(
id_item int
, id_menu int
)