SQL JSON - Append Json to Json - json

I Have this json:
{"keyvalue": {"head": {"id": ""},"column": {"id": ""},"degrees": {"id": ""}}}
How do i add this json to the key "keyvalue":
"somekey": { "id" : "" }
so my json looks like this:
{"keyvalue": {"head": {"id": ""},"column": {"id": ""},"degrees": {"id": ""}, "somekey": { "id" : "" }}}
i tried this:
SELECT JSON_MODIFY('{"keyvalue": {"head": {"id": ""},"column": {"id": ""},"degrees": {"id": ""}}}', 'append $', json_query(N' {"somekey": {"id" : ""}}'))
FROM PL_Table
WHERE PL_Id = 6;
but nothing changed
UPDATE
i have this now:
update PL_PageLayout
set PL_Json = json_modify('{
"keyvalue": {
"obj1": {
"id": ""
},
"obj2": {
"id": ""
},
"obj3": {
"id": ""
}
}
}', 'append $.keyvalue.content', '{"id" : "ddd"}')
FROM PL_PageLayout
WHERE PL_Id = 6;
Output is:
{"keyvalue": {"obj1": {"id": ""},"obj2": {"id": ""},"obj3": {"id": ""},"content":["{\"id\" : \"ddd\"}"]}}
but the
"content":["{\"id\" : \"ddd\"}"]
needs to be
"content":{\"id\" : \"ddd\"}

The reason for this result is that with append optional modifier, the new value is appended to the array referenced by the path. You also need to use JSON_QUERY() to get a properly formatted JSON, because JSON_MODIFY escapes all special characters in the new value if the type of the value is varchar or nvarchar.
You may try with the following approach, without using append:
DECLARE #json nvarchar(max) = N'{"keyvalue": {"head": {"id": ""},"column": {"id": ""},"degrees": {"id": ""}}}'
SELECT JSON_MODIFY(
#json,
'$.keyvalue.somekey',
JSON_QUERY(N'{"id" : ""}')
)
Result:
{"keyvalue": {"head": {"id": ""},"column": {"id": ""},"degrees": {"id": ""},"somekey":{"id" : ""}}}

Related

How do i get a specific data from responseBody on postman

I'm trying to set an environment variable using the following:
var data = JSON.parse(responseBody);
pm.environment.set("petId", data.id);
And this is what is in my response:
{
"id": 9222999990497629102,
"category": {
"id": 0,
"name": "dog"
},
"name": "Brutus",
"photoUrls": [
"http://placeimg.com/640/480"
],
"tags": [
{
"id": 0,
"name": "string"
}
],
"status": "available"
}
But somehow my environment looks like this:
"petId": "9222999990497629000"
I don't where from where I'm getting these last zeros on my variable.
pm.environment.set("petId", JSON.parse(pm.response.text().replace(/"id":[\s]*([\d]+),/,'"id":"$1",')).id);
As the id is a big int greator than MAX_SAFE_Integer , the response will be rounded when parsed as JSON. It is a javascript behavior.
You can enclose it with double quotes. After that extract that id.
now if you want to convert id to number use BigInt
let id = JSON.parse(pm.response.text().replace(/"id":[\s]*([\d]+),/,'"id":"$1",')).id
id = BigInt(id)
console.log(id)
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt

Accessing an array object from JSON by index-variable

I want to access over an array object in JSON by index with a variable. Consider the following code:
declare #pjson nvarchar(max)='{
"store":{
"storeId": 100,
"name": "TEST",
"lastUpdatedBy": "MULE",
"location": {
declare #pjson nvarchar(max)='{
"store":{
"storeId": 100,
"name": "TEST",
"lastUpdatedBy": "MULE",
"location": {
"addresses": [
{
"addressType": "MAIN",
"name": "Name1",
"name2": "Name2",
"address": "Address1",
"address2": "Address2",
"city": "City",
"lastUpdateBy": "MULE"
},
{
"addressType": "SECONDARY",
"name": "Name1",
"name2": "Name2",
"address": "Address1",
"address2": "Address2",
"city": "City",
"lastUpdateBy": "MULE"
},
{
"addressType": "BILLING",
"name": "Name1",
"name2": "Name2",
"address": "Address1",
"address2": "Address2",
"city": "City",
"lastUpdateBy": "MULE"
}
]
}
}
}'
Declare #counter1 INT = 0;
Print JSON_VALUE(#pjson,N'lax $.store.location.addresses[#counter1].addressType')
I get an error:
JSON path is not properly formatted. Unexpected character '#' is found
at position 31.
If I try directly by passing number as
Declare #counter1 INT = 0;
Print JSON_VALUE(#pjson,N'lax $.store.location.addresses[0].addressType')
I get the expected result
MAIN
Is there something that I am missing while passing the variable?
I don't think that you can use a T-SQL variable directly as part of the path parameter in the JSON_VALUE() call, but you may try one of the following approaches:
Concatenate the #counter variable in the path parameter (SQL Server 2017 is needed).
Parse the JSON with OPENJSON() and the appropriate WHERE clause.
JSON:
DECLARE #counter INT = 0;
DECLARE #pjson nvarchar(max) = N'{
"store":{
"storeId":100,
"name":"TEST",
"lastUpdatedBy":"MULE",
"location":{
"addresses":[
{
"addressType":"MAIN",
"name":"Name1",
"name2":"Name2",
"address":"Address1",
"address2":"Address2",
"city":"City",
"lastUpdateBy":"MULE"
},
{
"addressType":"SECONDARY",
"name":"Name1",
"name2":"Name2",
"address":"Address1",
"address2":"Address2",
"city":"City",
"lastUpdateBy":"MULE"
},
{
"addressType":"BILLING",
"name":"Name1",
"name2":"Name2",
"address":"Address1",
"address2":"Address2",
"city":"City",
"lastUpdateBy":"MULE"
}
]
}
}
}'
Statement with variable concatenation:
SELECT JSON_VALUE(
#pjson,
CONCAT(N'lax $.store.location.addresses[', #counter, N'].addressType')
)
Statement with OPENJSON():
SELECT JSON_VALUE([value], '$.addressType')
FROM OPENJSON(#pjson, 'lax $.store.location.addresses')
WHERE CONVERT(int, [key]) = #counter
Result:
(No column name)
----------------
MAIN
Try following:
DECLARE #pJson NVARCHAR(4000)
-- ...
DECLARE #Counter INT = 0
DECLARE #PathString NVARCHAR(1000)
SET #PathString = N'lax $.store.location.addresses[' + CAST(#Counter AS NVARCHAR(50)) + N'].addressType'
PRINT JSON_VALUE(#Pjson,#PathString)

How to properly unpack a JSON array in SQL Server

I'm making a foray into JSON, I'd like to add a user to multiple groups: insert an JSON array into a table.
Ideally, the JSON would look like this:
'{
"Email": "WMogh#starfleet.gov",
"Prefix":null,
"FirstName": "Worf",
"MiddleInitial": "",
"LastName": "Mogh",
"Suffix": "Son Of",
"Title" :"Commander",
"Groups": [{"0", "1", "5"}]
"Better_Groups": [{"ID":"0", "ID":"1", "ID":"5"}]
}'
Currently, I can do it with JSON like this:
'{
"Email": "WMogh#starfleet.gov",
"Prefix":null,
"FirstName": "Worf",
"MiddleInitial": "",
"LastName": "Mogh",
"Suffix": "Son Of",
"Title" :"Commander",
"Groups": "1,2,3,4"
}'
then "unpack" it with the following ditty:
declare #groups varchar(1000)
select #groups = Groups from openjson(#json)
WITH
(
Groups nvarchar(100) '$.Groups'
)
print #groups
select value from string_split(#groups, ',')
which returns a nice little table like so:
Value
1
2
3
4
Problem This is bad JSON and the Web developer will make fun of me.
Question How do you propely unpack a JSON array in SQL Server?
update:
The final JSON used looks like so:
#json =
'{
"Email": "WMogh#starfleet.gov",
"Prefix":null,
"FirstName": "Worf",
"MiddleInitial": "",
"LastName": "Mogh",
"Suffix": "Son Of",
"Title" :"Commander",
"Groups": "1,2,3,4",
"Better_Groups": ["0", "1", "5"]
}'
Assuming that "groups" element is an array:
DECLARE #json NVARCHAR(MAX) =
N'{
"Email": "WMogh#starfleet.gov",
"Prefix":null,
"FirstName": "Worf",
"MiddleInitial": "",
"LastName": "Mogh",
"Suffix": "Son Of",
"Title" :"Commander",
"Better_Groups": ["0", "1", "5"]
}';
SELECT s.value
FROM OPENJSON(JSON_QUERY(#json, '$.Better_Groups')) s;
db<>fiddle demo

Add an element at the beginning of a JSON using JSON_MODIFY

I am trying to build a JSON from the following table
name | flag
------+------
foo | fail
bar | pass
using the query,
DECLARE #JSONDATA nvarchar(MAX) = (SELECT [name], [flag]
FROM test
FOR JSON AUTO, ROOT('students'))
SET #JSONDATA = JSON_MODIFY(#JSONDATA, '$.class','10')
The generated JSON here is
{
"students": [
{
"name": "foo",
"flag": "fail"
},
{
"name": "bar",
"flag": "pass"
}
],
"class": "10"
}
I need to the class element at the very first node of the JSON. Is there any way, using JSON_MODIFY ?
Fiddle
At a loss forcing a sequence via modify.
Perhaps an alternative
Select class=10
,students = (SELECT [name], [flag] FROM test FOR JSON AUTO)
For JSON path, without_array_wrapper
Returns
{
"class": 10,
"students": [{
"name": "foo",
"flag": "fail"
}, {
"name": "bar",
"flag": "pass"
}]
}
EDIT- Updated SELECT as suggested by GSerg

How to get value from JsValue?

For Example:
My Db stores following Json. Form Following json I need to extract the value of particular field.
"student": [
{
"name": "Xyz",
"college": "abc",
"student_id":{
"$oid": "59a9314f6d0000920962e247"
}},
{
"name": "DDD",
"college": "opop",
"student_id":{
"$oid": "59a9314f6d0000920962e257"
}}
]
How can I pick only the value of "$oid" and save json in following way:
"student": [
{
"name": "Xyz",
"college": "abc",
"student_id":
"59a9314f6d0000920962e247"
},
{
"name": "DDD",
"college": "opop",
"student_id":
"59a9314f6d0000920962e257"
}
]
In my scenario, I'm reading it from client side as -
String Json = null;
JsonNode body = request().body().asJson();
Json = body.toString();
Logger.info(Json);
String role = body.get("role").get("role").asText();
users.firstName = body.get("firstName").asText();
users.lastName = body.get("lastName").asText();
You need to change the definition of JsonNode body = request().body().asJson(); and the other code as per your scenario to get it from db.
You will need to replace "student_id" jsValue with string value as below:
val original: JsValue = Json.parse(
""" {"student": [
{
"name": "Xyz",
"college": "abc",
"student_id":{
"$oid": "59a9314f6d0000920962e247"
}},
{
"name": "DDD",
"college": "opop",
"student_id":{
"$oid": "59a9314f6d0000920962e257"
}}
]}""")
val changed = original.as[JsObject] ++ Json.obj(
"student" -> Json.arr {
original.transform((__ \ 'student)
.json.pick[JsArray])
.getOrElse(Json.arr())
.value.map(e => {
val value = e.transform((__ \ 'student_id \ '$oid).json.pick[JsString]).get
e.as[JsObject] ++ Json.obj("student_id" -> value)
})
})
println(Json.stringify(changed))
//Result:
{"student":[[{"name":"Xyz","college":"abc","student_id":"59a9314f6d0000920962e247"},{"name":"DDD","college":"opop","student_id":"59a9314f6d0000920962e257"}]]}