This is my query:
SELECT
JSON_QUERY(MyStringColumnWithJson, '$.Images') AS images
FROM MyTable
which returns a single field with the JSON data shown here below:
"{
"Images":
[
{"Name":"test1.jpeg","Description":"originalName1.jpeg"},
{"Name":"test2.jpeg","Description":"originalName2.jpeg"},
{"Name":"test3.jpeg","Description":"originalName3.jpeg"}
]
}"
How can I read the images result row by row into a temporary table structure?
Use OPENJSON which returns a data set, not JSON_VALUE, which returns a scalar value. For example:
DECLARE #JSON nvarchar(MAX) = N'{
"Images":
[
{"Name":"test1.jpeg","Description":"originalName1.jpeg"},
{"Name":"test2.jpeg","Description":"originalName2.jpeg"},
{"Name":"test3.jpeg","Description":"originalName3.jpeg"}
]
}';
SELECT *
FROM OPENJSON(#JSON, '$.Images')
WITH (Name nvarchar(128),
Description nvarchar(128))OJ;
SELECT I.[Name],
I.Description
FROM MyTable MT
CROSS APPLY OPENJSON(MT.YourJsonColumn, '$.Images')
WITH (Name nvarchar(128),
Description nvarchar(128)) I;
I have the following t-sql query that returns json:
SELECT
CF.Name
, UCF.Value
FROM dbo.ClaimsCustomFields CF
LEFT JOIN dbo.UserCustomFields UCF
ON UCF.FieldId = CF.Id
WHERE CF.CustomerId = 2653
FOR JSON PATH;
The output of this query is next:
[
{
"Name":"zipCode",
"Value":"zip zip zipC zipCod"
},
{
"Name":"time111zone",
"Value":"UTC +2"
},
{
"Name":"tttt",
"Value":"Company organization tessss"
}
]
But I want to get the result in the following format:
[
{
"zipCode":"zip zip zipC zipCod"
},
{
"time111zone":"UTC +2"
},
{
"tttt":"Company organization tessss"
}
]
Is it possible to achive this with FOR JSON statement?
You basically want to generate a dynamic json, so you can try to use dynamic TSQL taking advantage of SQL Server 2017 new function STRING_AGG (more info here):
--this table contains your sample data
declare #tmp table([Name] varchar(50),[Value] varchar(50))
--this variable will contain the dynamic tsql command
declare #sql nvarchar(max)
--this temp table will hold the dynamically generated json fragments
if object_id('#tmp') is null
create table #tmp (js varchar(max))
--fill table with test data
insert into #tmp values
('zipCode' ,'zip zip zipC zipCod'),
('time111zone' ,'UTC +2'),
('tttt' ,'Company organization tessss')
--generate a TSQL command that inserts each single JSON fragment into a temp table
select #sql = string_agg('insert into #tmp(js) values((select ''' + [Value] +''' as '''
+ [Name]+''' for json path , WITHOUT_ARRAY_WRAPPER))', ';')
from #tmp
--execute the dynamic TSQL command that fills the temp table with JSON fragments
exec(#sql)
--concatenate all the JSON fragments adding square brackets
select '[' + string_agg(js,',') + ']' as result from #tmp
Results:
[{"zipCode":"zip zip zipC zipCod"},{"time111zone":"UTC +2"},{"tttt":"Company organization tessss"}]
How can I read value from json file in that field name contains space using OPENJSON in Sql Server 2016. See the below code:
DECLARE #json NVARCHAR(MAX)
SET #json = N'{ "full name" : "Jayesh Tank"}';
SELECT * FROM OPENJSON(#json) WITH ( [name] [varchar](60) '$.full name')
Also another sample code in that space is after field name.
SET #json = N'{ "name " : "abc"}';
SELECT * FROM OPENJSON(#json) WITH ( [name] [varchar](60) '$.name')
'$.name' will return null.Is there way to read this value?
Generally it is a bad idea to use spaces in the attribute name.
I would leave out the [ ] from your OPENJSON name and varchar(60) - source MSDN OPENJSON.
Now to actually answer your question:
You need to format your attribute with double quotes in the WITH clause:
#DECLARE #json NVARCHAR(MAX);
SET #json=N'{ "full name" : "Jayesh Tank"}';
SELECT * FROM OPENJSON(#json) WITH (name varchar(60) '$."full name"')
for the second one:
SET #json = N'{ "name " : "abc"}';
SELECT * FROM OPENJSON(#json) WITH ( name varchar(60)'$."name "')
JSON_VALUE(c.value,'$.Serial Number') as [Serial Number] is throwing an error with a space. How do I resolve the space in the field name using JSON_VALUE .
by itself '$.Full Name' is not a valid json, but adding '$."Full Name"' the json becomes valid
I have some json that I would like to parse in SQL Server 2016. There is a hierarchy structure of Projects->Structures->Properties. I would like to write a query that parses the whole hierarchy but I don't want to specify any elements by index number ie I don't want to do anything like this:
openjson (#json, '$[0]')
or
openjson (#json, '$.structures[0]')
I had this idea that I could read the values of the top level project objects along with the json string that represents the structures below it, which could then be parsed separately. The problem is that the following code does not work:
declare #json nvarchar(max)
set #json = '
[
{
"IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47",
"Name":"Test Project",
"structures":[
{
"IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F",
"IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47",
"Name":"Test Structure",
"BaseStructure":"Base Structure",
"DatabaseSchema":"dbo",
"properties":[
{
"IdProperty":"618DC40B-4D04-4BF8-B1E6-12E13DDE86F4",
"IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F",
"Name":"Test Property 2",
"DataType":1,
"Precision":0,
"Scale":0,
"IsNullable":false,
"ObjectName":"Test Object",
"DefaultType":1,
"DefaultValue":""
},
{
"IdProperty":"FFF433EC-0BB5-41CD-8A71-B5F09B97C5FC",
"IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F",
"Name":"Test Property 1",
"DataType":1,
"Precision":0,
"Scale":0,
"IsNullable":false,
"ObjectName":"Test Object",
"DefaultType":1,
"DefaultValue":""
}
]
}
]
}
]';
select IdProject, Name, structures
from openjson (#json)
with
(
IdProject uniqueidentifier,
Name nvarchar(100),
structures nvarchar(max)
) as Projects
IdProject and Name get returned no problem but for some reason I cannot get the nested json held in 'structures'. Instead of the json content it just returns NULL:
Does anyone know if this is possible and if so, what am I doing wrong?
Using CROSS APPLY:
declare #json nvarchar(max)
set #json = '
[
{
"IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47",
"Name":"Test Project",
"structures":[
{
"IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F",
"IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47",
"Name":"Test Structure",
"BaseStructure":"Base Structure",
"DatabaseSchema":"dbo",
"properties":[
{
"IdProperty":"618DC40B-4D04-4BF8-B1E6-12E13DDE86F4",
"IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F",
"Name":"Test Property 2",
"DataType":1,
"Precision":0,
"Scale":0,
"IsNullable":false,
"ObjectName":"Test Object",
"DefaultType":1,
"DefaultValue":""
},
{
"IdProperty":"FFF433EC-0BB5-41CD-8A71-B5F09B97C5FC",
"IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F",
"Name":"Test Property 1",
"DataType":1,
"Precision":0,
"Scale":0,
"IsNullable":false,
"ObjectName":"Test Object",
"DefaultType":1,
"DefaultValue":""
}
]
}
]
}
]';
select
Projects.IdProject, Projects.Name as NameProject,
Structures.IdStructure, Structures.Name as NameStructure, Structures.BaseStructure, Structures.DatabaseSchema,
Properties.*
from openjson (#json)
with
(
IdProject uniqueidentifier,
Name nvarchar(100),
structures nvarchar(max) as json
)
as Projects
cross apply openjson (Projects.structures)
with
(
IdStructure uniqueidentifier,
Name nvarchar(100),
BaseStructure nvarchar(100),
DatabaseSchema sysname,
properties nvarchar(max) as json
) as Structures
cross apply openjson (Structures.properties)
with
(
IdProperty uniqueidentifier,
NamePreoperty nvarchar(100) '$.Name',
DataType int,
[Precision] int,
[Scale] int,
IsNullable bit,
ObjectName nvarchar(100),
DefaultType int,
DefaultValue nvarchar(100)
)
as Properties
If you reference JSON object or array you need to specify AS JSON clause:
select IdProject, Name, structures
from openjson (#json)
with
(
IdProject uniqueidentifier,
Name nvarchar(100),
structures nvarchar(max) AS JSON
) as Projects
See FAQ: https://learn.microsoft.com/en-us/sql/relational-databases/json/solve-common-issues-with-json-in-sql-server?view=sql-server-ver15#return-a-nested-json-sub-object-from-json-text-with-openjson
If you want to apply OPENJSON on the returned structures array, you can use something like following code:
select IdProject, Name, structures
from openjson (#json)
with
(
IdProject uniqueidentifier,
Name nvarchar(100),
structures nvarchar(max) AS JSON
) as Projects
CROSS APPLY OPENJSON (structures) WITH (......)
Typical! I found the answer just after posting the question. You need to use the 'as json' key word when specifying the columns to return:
select IdProject, Name, structures
from openjson (#json)
with
(
IdProject uniqueidentifier,
Name nvarchar(100),
structures nvarchar(max) as json
) as Projects
For example:
SET #key = '["a","b"]';
SELECT JSON_SEARCH(#key, 'one', 'b');
...will return the path:
"$[1]"
Insert this as the path in JSON_EXTRACT like:
SET #value = '["1","2"]';
SELECT JSON_EXTRACT(#value, "$[1]");
...this will return the value:
"2"
But if I write following:
SET #key = '["a","b"]';
SET #value = '["1","2"]';
SET #path = (SELECT JSON_SEARCH(#key, 'one', 'b'));
SELECT JSON_EXTRACT(#value, #path);
...this will drop an error:
SQL Fehler (3143): Invalid JSON path expression. The error is around character position 1 in '"$[1]"'.
Trimming the double quotes works, but I don't like this solution:
SELECT JSON_EXTRACT(#value, TRIM(BOTH '"' FROM #path));
Is there an other way or am I missing something?
JSON_PATH returns a JSON object (a JSON string) that needs to be unquoted when used as string:
SELECT JSON_EXTRACT(#value, JSON_UNQUOTE(#path));
"2"