I am passing up JSON as a parameter to a SQL stored proc. I use a function that takes a JSON dictionary and creates a table with key value pairs (two columns) that I then use with a COALESCE
to create dynamic sql for an INSERT
statement. This works fine for a single dictionary, but I need to also be able to send up JSON string that contains an array of dictionaries. Right now, my parse function gives me this table variable:
What I need is a table variable like this:
I can get the column names from the first table with this:
SELECT DISTINCT element name from @JSONTable
I should mention that these elementname's can and will change. I will not know the number of distinct elementname values.
UPDATE - Using Umair's answer, I am getting close:
DECLARE @JSONString AS VARCHAR(MAX)
SET @JSONString = '[{"ravid":3,"ravversion":2,"taskid":3},{"ravid":4,"ravversion":7,"taskid":99}]'
IF OBJECT_ID('tempdb..#JSONTable') IS NOT NULL
DROP TABLE #JSONTable
CREATE TABLE #JSONTable
(
elementname VARCHAR(500) ,
elementvalue VARCHAR(500)
)
INSERT INTO #JSONTable
( elementname ,
elementvalue
)
SELECT NAME ,
StringValue
FROM dbo.parseJSON(@JSONString)
WHERE LEN(StringValue) > 0 AND NAME IS NOT NULL
--declare a csv variable with all the distinct elements
DECLARE @csv NVARCHAR(max) = STUFF(
(
SELECT ',' + elementname
FROM (
SELECT DISTINCT elementname
FROM #JSONTable
) AS e
FOR XML PATH(''), TYPE
).value('.', 'nvarchar(max)'),
1,
1,
''
);
DECLARE @sql NVARCHAR(MAX) = '
SELECT *
FROM (
SELECT *, Row = ROW_NUMBER() OVER (PARTITION BY elementname ORDER BY elementname)
FROM #JSONTable
) AS t
PIVOT (
MAX(elementvalue)
FOR elementname IN (' + @csv + ')
) AS p
'
EXEC sp_executesql @sql
But the dictionary values don't correspond to the key. Here is the results of Umair's current answer:
How about
--declare a csv variable with all the distinct elements
DECLARE @csv NVARCHAR(max) = STUFF(
(
SELECT ',' + elementname
FROM (
SELECT DISTINCT elementname
FROM #JSONTable
) AS e
FOR XML PATH(''), TYPE
).value('.', 'nvarchar(max)'),
1,
1,
''
);
DECLARE @sql NVARCHAR(MAX) = '
SELECT *
FROM (
SELECT *, Row = ROW_NUMBER() OVER (PARTITION BY elementname ORDER BY elementvalue)
FROM #JSONTable
) AS t
PIVOT (
MAX(elementvalue)
FOR elementname IN (' + @csv + ')
) AS p
'
EXEC sp_executesql @sql
ie dynamic pivoting :)
Edit:
Since you do not want to aggregate by anything in the pivot, I added a row number function to assign each distinct elementname a sequentially increasing id (based on element value). This will essentially group the pivot by this row column, producing all the required rows.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.