T-SQL - JSON_QUERY : select json properties with special characters in the property name - json

I'm facing some issues while trying to select a value from a JSON column.
The json is:
{
"$type":"myNameSpace.myClass, myDll"
}
And I'm trying to query it with something like
SELECT myIdColumnName, myJsonColumnName, JSON_QUERY(myJsonColumnName, '$.$type') as mType
the problem is that the path '$.$type' is invalid, the italian error is:
Il formato del percorso JSON non è corretto. È stato trovato il carattere imprevisto '$' nella posizione 2.
which basically tells that the parser does not expect "$" after ".".
I already tried using '$.type' and '$."$type"' but it in both cases I get null as mType.
Could you tell me the right syntax for this query?
Thank you

When you want to extract JSON object or scalar value and your path begins with a dollar sign $, you need to surround it with quotes ". Function JSON_QUERY extracts an object or an array from a JSON string, so JSON_VALUE is more appropriate here when you want to extract a scalar value from JSON text.
Example:
DECLARE #json nvarchar(max) = N'{
"$type":"myNameSpace.myClass, myDll"
}'
SELECT JSON_VALUE(#json, '$."$type"')
Output:
--------------------------
(No column name)
--------------------------
myNameSpace.myClass, myDll

Related

Get value from JSON object having special character in key using SQL query

I have an outlet_details table having two columns(id and extended_attributes as a JSON object).
extended_attributes have values like
{
"parent-0-0-id": "DS-606",
"parent-0-1-id": "SD066",
"secondaryOutletCode": "MG_918"
}
I want to get parent-0-0-id's value, but when I'm trying to hit
SELECT extended_attributes->>'$.parent-0-0-id' AS 'parent00id' FROM outlet_details;
I'm getting an:
invalid JSON path expression error(3143).
You could just enclose the column name under quotes to separate out the name from escape characters.
SELECT extended_attributes->>"$.\"parent-0-0-id\"" AS 'parent00id' FROM outlet_details; should work

Parse JSON data in T-SQL [duplicate]

This is driving me nuts, and I don't understand what's wrong with my approach.
I generate a JSON object in SQL like this:
select #output = (
select distinct lngEmpNo, txtFullName
from tblSecret
for json path, root('result'), include_null_values
)
I get a result like this:
{"result":[{"lngEmpNo":696969,"txtFullName":"Clinton, Bill"}]}
ISJSON() confirms that it's valid JSON, and JSON_QUERY(#OUTPUT, '$.result') will return the array [] portion of the JSON object... cool!
BUT, I'm trying to use JSON_QUERY to extract a specific value:
This gets me a NULL value. Why??????? I've tried it with the [0], without the [0], and of course, txtFullName[0]
SELECT JSON_QUERY(#jsonResponse, '$.result[0].txtFullName');
I prefixed with strict, SELECT JSON_QUERY(#jsonResponse, 'strict $.result[0].txtFullName');, and it tells me this:
Msg 13607, Level 16, State 4, Line 29
JSON path is not properly formatted. Unexpected character 't' is found at
position 18.
What am I doing wrong? What is wrong with my structure?
JSON_QUERY will only extract an object or an array. You are trying to extract a single value so, you need to use JSON_VALUE. For example:
SELECT JSON_VALUE(#jsonResponse, '$.result[0].txtFullName');

I need to replace the character \\ of a string and read with JSON_EXTRACT

When saving the JSON object in Mysql with JSON.stringify it puts the character "\" in the string. I am building a VIEW and I need to separate the data with json_extract, for that I used the MySql REPLACE command but the return is null.
EDITED
JSON IN FIELD "DADOS" (LONGTEXT)
{
"pessoal":"[{\"nome\":\"Marie Luiza Novaes\",\"nascimento\":\"1994-06-20\",\"civil\":\"Casado(a)\",\"sexo\":\"F\",\"rg\":\"469326293\",\"cpf\":\"06649073504\"}]",
"contato":[],
"interesse":[],
"adicional":[],
"profissional":[],
"academico":[],
"anotacoes":[],
"extras":"[]"
}
1 - GET NOME
SELECT
json_extract (REPLACE(dados,'\\"','"'), '$.pessoal[0].nome') dados
FROM
cadastro
2 - GET NOME
SELECT
json_extract (REPLACE(dados,'\\',''), '$.pessoal[0].nome') dados
FROM
cadastro
TEST
I see multiple problems with your current approach. First, the JSON literal text in your column appears to be somewhat malformed. The JSON array does not take double quotes, because it is part of the JSON structure. Second, the JSON path syntax you are using is also off. The following exact setup is working for me:
WITH cadastro AS (
SELECT '{"pessoal":[{"nome":"Marie Luiza Novaes","nascimento":"1994-06-20","civil":"Casado(a)","sexo":"F","rg":"469326293","cpf":"06649073504"}],
"contato":[],
"interesse":[],
"adicional":[],
"profissional":[],
"academico":[],
"anotacoes":[],
"extras":[]}' AS dados
)
SELECT
JSON_EXTRACT(dados, '$.pessoal[0].nome') dados
FROM cadastro;
Demo
The output from this query is "Marie Luiza Novaes".

JSON_QUERY unable to handle NULL

I have a table. Few columns are of String, Integer type. And few are JSON type. I am writing a query to form each row as a json object. I have issues with JSON_QUERY(jsondataColumnName). If the column is populated NULL JSON_QUERY fails.
I have already written query below.
select
(
SELECT [customerReferenceNumber] as customerReferenceNumber
,[customerType] as customerType
,[personReferenceNumber] as personReferenceNumber
,[organisationReferenceNumber] as organisationReferenceNumber
,json_query(isnull(product,'')) as product
,json_query(isnull([address],'')) as address
FROM [dbo].[customer]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER) AS customer
from [dbo].[customer] P
Msg 13609, Level 16, State 1, Line 2
JSON text is not properly formatted. Unexpected character '.' is found at position 0.
By default, for JSON don't work with NULL VALUES. Use INCLUDE_NULL_VALUES to handle.
As Example: JSON PATH, WITHOUT_ARRAY_WRAPPER, INCLUDE_NULL_VALUES) AS customer
As reference:
https://learn.microsoft.com/en-us/sql/relational-databases/json/include-null-values-in-json-include-null-values-option?view=sql-server-ver15

Parse unknown JSON path in TSQL with openjson and/or json_value

I have a incoming data structure that looks like this:
declare #json nvarchar(max) = '{
"action": "edit",
"data": {
"2077-09-02": {
"Description": "some stuff",
"EffectDate": "2077-1-1"
}
}
}';
To give you a long story short, I think TSQL hates this json structure, because no matter what I have tried, I can't get to any values other than "action".
The {data} object contains another object, {2077-09-02}. "2077-09-02" will always be different. I can't rely on what that date will be.
This works:
select json_value(#json, '$.action');
None of this works when trying to get to the other values.
select json_value(#json, '$.data'); --returns null
select json_value(#json, '$.data[0]'); --returns null
select json_value(#json, 'lax $.data.[2077-09-02].Description');
--JSON path is not properly formatted. Unexpected character '[' is found at position 11.
select json_value(#json, 'lax $.data.2077-09-02.Description');
--JSON path is not properly formatted. Unexpected character '2' is found at position 11.
How do I get to the other values? Is the JSON not perfect enough for TSQL?
It is never a good idea to use the declarative part of a text based container as data. The "2077-09-02" is a valid json key, but hard to query.
You can try this:
declare #json nvarchar(max) = '{
"action": "edit",
"data": {
"2077-09-02": {
"Description": "some stuff",
"EffectDate": "2077-1-1"
}
}
}';
SELECT A.[action]
,B.[key] AS DateValue
,C.*
FROM OPENJSON(#json)
WITH([action] NVARCHAR(100)
,[data] NVARCHAR(MAX) AS JSON) A
CROSS APPLY OPENJSON(A.[data]) B
CROSS APPLY OPENJSON(B.[value])
WITH (Description NVARCHAR(100)
,EffectDate DATE) C;
The result
action DateValue Description EffectDate
edit 2077-09-02 some stuff 2077-01-01
The idea:
The first OPENJSON will return the action and the data.
I use a WITH clause to tell the engine, that action is a simple value, while data is nested JSON
The next OPENJSON dives into data
We can now use B.[key] to get the json key's value
Now we need another OPENJSON to dive into the columns within data.
However: If this JSON is under your control I'd suggest to change its structure.
Use double quotes instead of []. JSON Path uses JavaScript's conventions where a string is surrounded by double quotes. The documentation's example contains this path $."first name".
In this case :
select json_value(#json,'$.data."2077-09-02".Description');
Returns :
some stuff
As for the other calls, JSON_VALUE can only return scalar values, not objects. You need to use JSON_QUERY to extract JSON objects, eg :
select json_query(#json,'$.data."2077-09-02"');
Returns :
{
"Description": "some stuff",
"EffectDate": "2077-1-1"
}