SQL Server中的OPENJSON动态使用with语句

时间:2018-02-07 05:35:04

标签: json sql-server tsql

我需要选择存储为文本的json列并将其解析为结果集。为此我写了一个工作正常的存储过程。

SELECT --count (*) -use this to get count of records
ID, COLUMN1, COLUMN2,CREATION_DATE --required columns
FROM
MY_TABLE
WHERE
ROWID IN( 
        select duplicate_rowid 
          from (select rowid as duplicate_rowid
                      ,row_number() over(  
                         partition by COLUMN1, COLUMN2      --  criterion 1
                             ORDER BY CREATION_DATE ASC   -- criterion 2
                                     ,ID   ASC          -- criterion 3

                      ) AS RNK
                  from MY_TABLE
                )
         WHERE (RNK > 1 and COLUMN1 IS NOT NULL and COLUMN2 IS NOT NULL)
);

现在我有一个要求,其中我可以动态地在语句中分配字段名称,而不是专门为每个语句分配。

请帮忙。

2 个答案:

答案 0 :(得分:1)

只要您的JSON数据只包含具有简单数据类型的类似行(没有对象,没有子数组),您就可以构造动态SQL来创建表并在其中插入值,如下所示:

DECLARE @json NVARCHAR(MAX)

SET @json='[
    { "name":"John", "age":31, "city":"New York" },
    { "name":"Mary", "age":29, "city":"New York" }
]'

DECLARE @FirstRow NVARCHAR(MAX)=(SELECT TOP 1 Value FROM OPENJSON(@json))

DECLARE @Columns TABLE (
    Position INT IDENTITY PRIMARY KEY,
    ColumnName sysname NOT NULL UNIQUE,
    JSONDataType INT NOT NULL,
    SQLDataType VARCHAR(30) NOT NULL
)

INSERT INTO @Columns (ColumnName, JSONDataType, SQLDataType)
SELECT [Key], Type, 
    CASE Type 
        WHEN 1 THEN 'nvarchar(1000)'
        WHEN 2 THEN 'float'
        WHEN 3 THEN 'bit'
    END
FROM OPENJSON(@FirstRow) 

DECLARE @SQL NVARCHAR(MAX)

SET @SQL='('+(
    SELECT CHAR(13)+CHAR(10)+CHAR(9)+ColumnName+' '+c.SQLDataType
        +CASE WHEN c.Position<COUNT(*) OVER () THEN ',' ELSE '' END
    FROM @Columns c
    ORDER BY c.Position
    FOR XML PATH(''), TYPE
).value('.','nvarchar(max)')
+CHAR(13)+CHAR(10)+')'

SET @SQL='CREATE TABLE #Temp '+@SQL+CHAR(13)+CHAR(10)
+'INSERT INTO #Temp SELECT * FROM OPENJSON(@json) WITH'+@SQL
+CHAR(13)+CHAR(10)+'SELECT * FROM #Temp'

PRINT @SQL
EXEC sp_executesql @SQL,N'@json NVARCHAR(MAX)', @json

答案 1 :(得分:0)

对于SQL 2017及更高版本:

DECLARE @cols nvarchar(max),
        @query nvarchar(max)
        
SELECT @cols = STRING_AGG([Key], ',')
FROM (
    SELECT jc.[Key]
    FROM ..YourTableWithAJsonColumn yt
    CROSS APPLY OPENJSON(yt.YourJsonColumn) jc
    GROUP BY jc.[Key]
) j

SET @query = N'SELECT SomeNonJsonColumn, ' + @cols + N'
                FROM
                (
                    SELECT yt.SomeNonJsonColumn,
                           jc.[Key],
                           jc.[Value]
                    FROM ..YourTableWithAJsonColumn yt
                    CROSS APPLY OPENJSON(yt.YourJsonColumn) jc
                ) x
                PIVOT
                (
                    MAX([Value])
                    FOR [Key] in (' + @cols + N'
                ) p'
                
EXEC sp_executesql @query