SQL - openjson to extract key from json - sql

Below #json contains 3 data object within an array. After using OPENJSON to extract these objects to a Table variable, please see the output attached.
DECLARE #json NVARCHAR(MAX);
SET #json = N'[{"Container":"MSKU2913236","Seal":"ML-TH4773979","Size":"20","Temperature":"-20","TareWeight":"3.132","CreatedDate":"02-02-2018 00:00:00","Comment":null,"NetWeight":"21.445","TempRec#":null},{"Container":"MSKU3432702","Seal":"ML-TH4773972","Size":"20","Temperature":"-40","TareWeight":"2.872","CreatedDate":"02-02-2018 00:00:00","Comment":null,"NetWeight":"23.932","TempRec#":"TR12345"},{"Container":"MSKU4043053","Seal":"ML-TH4773973","Size":"20","Temperature":"-20","TareWeight":"2.995","CreatedDate":"02-02-2018 00:00:00","Comment":null,"NetWeight":"22.4","TempRec#":null}]';
DECLARE #ContainerTable TABLE(
[Key] NVARCHAR(100),
[Data] NVARCHAR(MAX)
);
INSERT INTO #ContainerTable
SELECT [key], [value] FROM OPENJSON(#json)
SELECT * FROM #ContainerTable
Output
Objective is to replace the Key column values with the Container property value from json in the Data column for all 3 rows.
Expected Output
Note: Expected output is hard coded and it only shows the one row but same is required for all rows.

You could use JSON_VALUE:
INSERT INTO #ContainerTable([Key], [Data])
SELECT JSON_VALUE([value],'$.Container'), [value]
FROM OPENJSON(#json);
DBFiddle Demo

Related

Select specific value from JSON list with SQL

Suppose I have a table column with person data organized as a JSON array, with categories and names.
In SQL, I can then easily select the data for a specific element in the array:
SELECT JSON_VALUE('{ "Persons": [{"PersonCat":"1","Name":"John"},{"PersonCat":"2","Name":"Henry"}]}','$.Persons[0].Name') AS SelectedPerson
I will then get "John".
But what if I want the person with "PersonCat" = 2? And null if PersonCat does not exist in the list?
I'm not sure it is possible to do this with the JSON_VALUE method, but it is possible using OPENJSON
DECLARE #json nvarchar(max)
SET #json = '{ "Persons": [{"PersonCat":"1","Name":"John"},{"PersonCat":"2","Name":"Henry"},{"Name":"Bob"}]}'
SELECT[PersonCat], [Name]
FROM OPENJSON(#json, '$.Persons')
WITH (
PersonCat NVARCHAR(512) '$.PersonCat',
[Name] NVARCHAR(512) '$.Name'
)
You can then add a WHERE clause to the SELECT to find the relevant PersonCat value (note: where the PersonCat property is missing from the array entry, the PersonCat column will be NULL)

How to pass a list of strings as a parameter in a stored procedure in SQL?

How to pass a list of strings as a parameter in a stored procedure in SQL?
Like for example if I have a stored procedure proc_aggregation that takes two parameters #Prod_Desc of varchar data type and another parameter #Prod_Code as a list of strings (Eg : #Prod_Code = ('12012', '12011', '12014')).
You will have to use table valued parameters
Define new type as follows
CREATE TYPE Prod_Code AS TABLE ( ProductCode varchar );
then use this type in your stored procedure
create procedure [dbo].[proc_aggregation]
#Prod_Code Prod_Code READONLY,
#Prod_Desc varchar (30)
as
......
Now before calling the stored procedure fill the table
declare #PC Prod_Code;
insert #PC VALUES ('12012'), ('12011'), ('12014')
Now Call the sp like this
EXEC dbo.proc_aggregation #PC, #Prod_Desc;
You can pass this data as varchar(max) parameter and then parse this string using string_split
Declare #Prod_Code VarChar(max) = '12012,12011,12014'
Select value As [Values]
From String_Split(#Prod_Code, ',')
or pass this data as a json array and parse this text using OPENJSON
Declare #Prod_Code VarChar(max) = '[12012, 12011, 12014]'
Select value As [Values]
From OPENJSON(#Prod_Code)
Values
12012
12011
12014
As an interesting fact, let'us compare performances of the different solutions... STRING, JSON, XML.
SET NOCOUNT ON;
GO
CREATE TABLE #test_list (id int identity primary key, style varchar(16), VAL VARCHAR(64), DT DATETIME2)
GO
-- JSON test
INSERT INTO #test_list VALUES ('JSON', '[12012, 12011, 12014]', SYSDATETIME());
GO
Select value As [Values]
From OPENJSON((SELECT VAL FROM #test_list WHERE style = 'JSON'));
GO 10000
-- STRING test
INSERT INTO #test_list VALUES ('STRING', '12012,12011,12014', SYSDATETIME());
GO
Select value As [Values]
From String_Split((SELECT VAL FROM #test_list WHERE style = 'STRING'), ',')
GO 10000
-- XML test
INSERT INTO #test_list VALUES ('XML', '<i v="12012" /><i v="12011" /><i v="12014" />', SYSDATETIME());
GO
WITH TX AS
(SELECT CAST(VAL AS xml) AS x
FROM #test_list AS i
WHERE style = 'XML')
Select y.value('(#v)[1]', 'varchar(16)')
From TX
CROSS APPLY x.nodes('/i') AS T(y);
GO 10000
-- final
INSERT INTO #test_list VALUES ('END', NULL, SYSDATETIME());
Executing the test without any dataset returned... (SSMS menu : Query/Options/Results/Grid/Ignore results after execution...)
Computing the execution time, is done by this query :
SELECT begins.style,
DATEDIFF(millisecond, begins.DT, ends.DT) AS DurationMS
FROM #test_list AS begins
JOIN #test_list AS ends ON begins.id = ends.id - 1
ORDER BY 2;
It is clear that string solution wins :
style DurationMS
---------------- -----------
STRING 2977
JSON 3358
XML 4242

Insert data into a table using OPENJson

I have the following Json that needs to be inserted into a table
{"errorMessage":"","requestOutput":{ "REQUEST_ID" : 100910, "STATUS_CODE" : "P", "PHASE_CODE" :
"N", "COMPLETION_TEXT" : null }}
This is the query i am using to process the json and insert into the table
INSERT INTO dbo.tblRequest_Details([RequestId]
,[Error_Message]
,[Status_Code]
,[Phase_Code]
,[Completion_Text])
SELECT [RequestId]
,[Error_Message]
,[Status_Code]
,[Phase_Code]
,[Completion_Text]
FROM OPENJSON((select * from #json2), N'$.requestOutput')
WITH (
[RequestId] nvarchar(max) N'$.REQUEST_ID',
[Status_Code] nvarchar(max) N'$.STATUS_CODE',
[Phase_Code] nvarchar(max) N'$.PHASE_CODE',
[Completion_Text] nvarchar(max) N'$.COMPLETION_TEXT')
CROSS APPLY OPENJSON((select * from #json2), N'$.errorMessage')
WITH( [Error_Message] nvarchar(max) N'$.errorMessage'
)
But for some reason, data does not get inserted into the table.
What am I doing wrong?
Thanks
Turns out there was an error with the errorMessage field so I removed the cross apply. Instead assigned the value of errorMessage to a variable and used that instead.

Parse JSON in SQL

I'm looking to parse a single return in JSON into multiple rows.
The string is this -
{"policy_ids":["INZP2981-11000002","INZP-00001786","0AAAA01PC06"]}
I want to just parse this so that it is a row for each policy_ids. I've tried using OpenJSON WITH however I keep returning NULL values.
DECLARE #json NVARCHAR(MAX) ;
SET #json = N'{"policy_ids":["INZP2981-11000002","INZP-00001786","0AAAA01PC06"]}' ;
SELECT
*
FROM
OPENJSON(#json)
WITH (
policy_ids varchar(200) '$.policy_ids'
)
Help is appreciated.
You need a different statement to parse the $.policy_ids JSON array. You may try tou use OPENJSON() with default schema (without the WITH clause). In this case the result is a table with columns key, value and type and the value column returns the value of each item in the input array.
DECLARE #json NVARCHAR(MAX) ;
SET #json = N'{"policy_ids":["INZP2981-11000002","INZP-00001786","0AAAA01PC06"]}' ;
SELECT [value] AS policy_id
FROM OPENJSON(#json, '$.policy_ids')
Result:
policy_id
-----------------
INZP2981-11000002
INZP-00001786
0AAAA01PC06
If you want to use an explicit schema, the statement is:
SELECT *
FROM OPENJSON(#json, '$.policy_ids') WITH (
policy_id varchar(200) '$'
)

SQL 2017 : Need to convert json with column name as a value and actual value is value of another one

HI I need to convert Json stored in 1 of the columns in a table to flat tables with specific fields.
Note : Column names are not always ""Request type,Country...".Columsn are dynamic and should be picked from value in "Name"
Below is the json from 1 row.
{"JobID":1,"ItemID":1,"Attributes":[{"ID":1,"Name":"Request Type","Value":"1","ValueString":"Buy"},{"ID":3,"Name":"Country","Value":"2","ValueString":"USA"},{"ID":5,"Name":"Number","Value":"1","ValueString":"1"}]}
I need this to be converted as in attached format
As a starter you should check OPENJSON:
DECLARE #j NVARCHAR(MAX) = '{"JobID":1,"ItemID":1,"Attributes":[{"ID":1,"Name":"Request Type","Value":"1","ValueString":"Buy"},{"ID":3,"Name":"Country","Value":"2","ValueString":"USA"},{"ID":5,"Name":"Number","Value":"1","ValueString":"1"}]}'
And query:
SELECT *
FROM OPENJSON(#j)
WITH (JobID INT '$.JobID',
ItemId INT '$.ItemID',
[Request_Type] NVARCHAR(100) '$.Attributes[0].ValueString',
Country NVARCHAR(100) '$.Attributes[1].ValueString',
[Number] NVARCHAR(100) '$.Attributes[2].ValueString'
);
DBFiddle Demo