I have a table with column contains a request from an API that contains special characters and it looks like - sql

{
"Info": {
"code": "SPPACK"
},
"user": {
"firstName": "John",
"lastName": "Smith",
"login": {
"loginType": "MOBILE_NUMBER",
"userName": "91817343123"
}
}
}
I want to retrieve only LoginType and Username values from the JSON above such as
LoginType
Username
MOBILE_NUMBER
91817343123
How can I write a query in oracle to retrieve these values? Please help.

You can use JSON_TABLE() function such as
SELECT LoginType, userName
FROM t,
JSON_TABLE(jstr, '$'
COLUMNS (NESTED PATH '$."user"[*]."login"[*]'
COLUMNS (
LoginType VARCHAR2 PATH '$."loginType"',
userName VARCHAR2 PATH '$."userName"')
))
Demo

Related

Update json data in oracle sql

This is my json data in one of the oracle sql columns "jsoncol" in a table named "jsontable"
{
"Company": [
{
"Info": {
"Address": "123"
},
"Name": "ABC",
"Id": 999
},
{
"Info": {
"Address": "456"
},
"Name": "XYZ",
"Id": 888
}
]
}
I am looking for an UPDATE query to update all the value of "Name" with a new value based on a particular "Id" value.
Thanks in advance
From Oracle 19, you can use JSON_MERGEPATCH:
UPDATE jsontable j
SET jsoncol = JSON_MERGEPATCH(
jsoncol,
(
SELECT JSON_OBJECT(
KEY 'Company'
VALUE JSON_ARRAYAGG(
CASE id
WHEN 999
THEN JSON_MERGEPATCH(
json,
'{"Name":"DEF"}'
)
ELSE json
END
FORMAT JSON
RETURNING CLOB
)
FORMAT JSON
RETURNING CLOB
)
FROM jsontable jt
CROSS APPLY JSON_TABLE(
jt.jsoncol,
'$.Company[*]'
COLUMNS(
json VARCHAR2(4000) FORMAT JSON PATH '$',
id NUMBER PATH '$.Id'
)
)
WHERE jt.ROWID = j.ROWID
)
)
Which, for the sample data:
CREATE TABLE jsontable (
jsoncol CLOB CHECK (jsoncol IS JSON)
);
INSERT INTO jsontable (jsoncol)
VALUES ('{
"Company": [
{
"Info": {
"Address": "123"
},
"Name": "ABC",
"Id": 999
},
{
"Info": {
"Address": "456"
},
"Name": "XYZ",
"Id": 888
}
]
}');
Then after the UPDATE, the table contains:
JSONCOL
{"Company":[{"Info":{"Address":"123"},"Name":"DEF","Id":999},{"Info":{"Address":"456"},"Name":"XYZ","Id":888}]}
db<>fiddle here
You can use REPLACE() within JSON_TABLE() function in order to update the value of the Name(from ABC to DEF) for a specific Id value(999) such as
UPDATE jsontable jt0
SET jsoncol = ( SELECT REPLACE(jsoncol,jt.name,'DEF')
FROM jsontable j,
JSON_TABLE(jsoncol,
'$' COLUMNS(NESTED PATH '$.Company[*]'
COLUMNS(
name VARCHAR2 PATH '$.Name',
id INT PATH '$.Id'
)
)
) jt
WHERE jt.id = 999
AND j.id = jt0.id )
for the DB version prior to 19 provided that the identity values(id) of the table and of the JSON values are unique throughout the table and each individual JSON value, respectively.
Demo

How to get an element in json array of objects db2

DB2 - I'm trying to get an specific item of my json array of objects...
Given this value saved in my column user_properites:
{
"properties":[
{ "key": "firstName", "value": "Jon" },
{ "key": "lastName", "value": "Doe" },
{ "key": "age", "value": 20 }
]
}
I'm using JSON_QUERY and I was doing something like:
SELECT
JSON_QUERY(u.user_properties, '$.properties[1]') AS lastName
FROM
USER u
But I need to get the lastName without pass the position on the array...
Is there a way to search an item by some value?
Thanks for the support :)

How to update value in nested json Postgres

I have following JSON stored in "Info" column
{
"customConfig": {
"isCustomGoods": 1
},
"new_addfields": {
"data": [
{
"val": {
"items": [
{
"Code": "calorie",
"Value": "365.76"
},
{
"Code": "protein",
"Value": "29.02"
},
{
"Code": "fat",
"Value": "23.55"
},
{
"Code": "carbohydrate",
"Value": "6.02"
},
{
"Code": "spirit",
"Value": "1.95"
}
],
"storageConditions": "",
"outQuantity": "100"
},
"parameterType": "Nutrition",
"name": "00000000-0000-0000-0000-000000000001",
"label": "1"
},
{
"name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
"val": "true"
}
]
}
}
I want to update value of nested json
{
"name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
"val": "true"
}
and set "val"to "Yes" str so the result should be like
{
"name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
"val": "Yes"
}
How can i do that ? Assuming that i need to update this value in json for many records in database
Considering you have a constant JSON Structure and a primary key in your table. Idea is to get the exact path of element val having value true (which can be at any index in the array) then replace it with desired value. So you can write your query like below:
with cte as (
select
id,
('{new_addfields,data,'||index-1||',val}')::text[] as json_path
from
test,
jsonb_array_elements(info->'new_addfields'->'data')
with ordinality arr(vals,index)
where
arr.vals->>'val' ilike 'true'
)
update test
set info = jsonb_set(info,cte.json_path,'"Yes"',false)
from cte
where test.id=cte.id;
DEMO
We can use jsonb_set() which is available from Postgres 9.5+
From Docs:
jsonb_set(target jsonb, path text[], new_value jsonb [, create_missing boolean])
Query to update the nested object:
UPDATE temp t
SET info = jsonb_set(t.info,'{new_addfields,data,1,val}', jsonb '"Yes"')
where id = 1;
It can also be used in select query:
SELECT
jsonb_set(t.info,'{new_addfields,data,1,val}', jsonb '"Yes"')
FROM temp t
LIMIT 1;

Nested JSON using ms sql server

I have a table with USER_DATA (user data table) with 2 rows (2 entries basically)
I created one nested JSON query ->
SELECT CONCAT( first_name,' ', last_name) AS displayName,
first_name AS givenName, last_name AS surname,
identities = (SELECT login_name AS issuerAssignedId
FROM user_data
FOR JSON AUTO)
FROM user_data
FOR JSON PATH, ROOT('users');
Here, I am getting this output ->
{
"users": [
{
"displayName": "David Dave",
"givenName": "David",
"surname": "Dave",
"identities": [
{
"issuerAssignedId": "System"
},
{
"issuerAssignedId": "Administrators"
}
]
},
{
"displayName": "Tony Padila",
"givenName": "Tony",
"surname": "Padila",
"identities": [
{
"issuerAssignedId": "System"
},
{
"issuerAssignedId": "Administrators"
}
]
}
But the problem is -> inside identities,
"issuerAssignedId": "System" ----> Belongs to Dave
"issuerAssignedId": "Administrators" ----> Belongs to Tony
But I am not able to stop the inner select query (Not able to map correctly)
The correct output should be --->
{
"users": [
{
"displayName": "David Dave",
"givenName": "David",
"surname": "Dave",
"identities": [
{
"issuerAssignedId": "System"
}
]
},
{
"displayName": "Tony Padila",
"givenName": "Tony",
"surname": "Padila",
"identities": [
{
"issuerAssignedId": "Administrators"
}
]
}
PLEASE HELP.
You are missing the condition in the inner query and why do you want the identities to be a separate array in the JSON output.
I have updated the query as per my understanding please refer below sql, I'm not sure why you are having the ** in the query
SELECT CONCAT (
FIRST_NAME
,' '
,LAST_NAME
) AS displayName
,FIRST_NAME AS givenName
,LAST_NAME AS surname
,identities = (
SELECT innr.LOGIN_NAME AS issuerAssignedId
FROM USER_DATA
innr
WHERE
innr.LOGIN_NAME = ottr.LOGIN_NAME
FOR JSON AUTO
)
FROM USER_DATA ottr
FOR JSON PATH
,ROOT('users');

How to select field values from array of objects?

I have a JSON column with following JSON
{
"metadata": { "value": "JABC" },
"force": false,
"users": [
{ "id": "111", "comment": "abc" },
{ "id": "222", "comment": "abc" },
{ "id": "333" }
]
}
I am expecting list of IDs from the query output ["111","222", "333"]. I tried following query but getting null value.
select colName->'users'->>'id' ids from tableName
How to get this specific field value from the array of object?
You need to extract the array as rows and then get the id:
select json_array_elements(colName->'users')->>'id' ids from tableName;
If you're using jsonb rather than json, the function is jsonb_array_elements.