协助解析JSON的

时间:2016-07-05 17:06:02

标签: sql sql-server json pivot

我有一个名为QueueItems的数据库表,其中包含以下字段:

enter image description here

SpecificData包含JSON数据,因此我们使用了互联网上众所周知的parseJSON SQL函数。

下面是JSON的一个例子:

{"DynamicProperties":{"IdentificationIndex":"CK","PaymentMethod":"C","Variants1":"010 ZERO BAL,716 ZERO BAL,717 ZERO BAL","Variants2":"CHECK_010,CHECK_716,CHECK_717","CustomerCode":"NO","FreeSelectionField":"NO","FreeSelectionValue":"NO","Variants1Line":"RFFOAVIS","Variants2Line":"ZRFFOUS_C","VendorFrom":"1","VendorTo":"999999999","DueDateCheck":"Yes","PaymentMethodSel":"Yes","PaymentMethodSelOnFail":"No","LineItemsOfPayDocs":"Yes","StartImmediately":"Yes","CreatePaymentMedium":"No","ExportFormat":"HTML Format","ExcludeValues":"Yes"}}

当我运行SQL函数parseJSON时,它以这种格式返回数据:

enter image description here

现在,我想写的查询是:

SELECT QueueItemID,QueueItemStatus,StartProcessing,EndProcessing,[THEN追加parseJSON中的每一列,但这需要先转置]

到目前为止,我已设法使用以下方法将JSON转换为具有单行的列:

DECLARE
        @Cols AS VARCHAR(MAX) = ''
        ,@Query AS NVARCHAR(MAX) = ''
        ,@ParamDef AS NVARCHAR(MAX)
        ,@Json AS VARCHAR(MAX) = '{"DynamicProperties":{"IdentificationIndex":"CK","PaymentMethod":"C","Variants1":"010 ZERO BAL,716 ZERO BAL,717 ZERO BAL","Variants2":"CHECK_010,CHECK_716,CHECK_717","CustomerCode":"NO","FreeSelectionField":"NO","FreeSelectionValue":"NO","Variants1Line":"RFFOAVIS","Variants2Line":"ZRFFOUS_C","VendorFrom":"1","VendorTo":"999999999","DueDateCheck":"Yes","PaymentMethodSel":"Yes","PaymentMethodSelOnFail":"No","LineItemsOfPayDocs":"Yes","StartImmediately":"Yes","CreatePaymentMedium":"No","ExportFormat":"HTML Format","ExcludeValues":"Yes"}}'



SELECT
    @Cols += ',' + Name
FROM
    parseJson(@Json) 
WHERE
    Name NOT IN ('DynamicProperties', '-')


SET @Cols = SUBSTRING(@Cols,2,LEN(@Cols))


SET @Query = N'SELECT *
FROM 
(
    SELECT [StringValue], [Name] 
    FROM parseJson(''' + @Json + ''')

) [d] 
PIVOT 
(
    MAX([StringValue]) 
    FOR [Name] IN (' + @Cols + ')
) [piv]'


EXECUTE (@Query)

enter image description here

正如您所看到的,JSON可能包含任何数据,因此我将列名称动态插入到PIVOT语句FOR IN中。

现在将此数据作为附加列加入到我的主查询中 SELECT QueueItemId .. FROM QueueItems 我原本打算将此代码放在UDF中并将其作为主查询/存储的一部分进行调用程序,但我有两个问题:

1)sp_executesql或EXEC语句 - UDF中不允许使用 2)要从UDF返回一个表,我需要定义字段......这些字段是动态的......我可以通过将XML传回我的存储过程来实现这一点,但我仍然有第一个问题。

所以问题是: 1)有没有更好的方法或写这个然后使用UDF? 2)有没有其他方法或转换parseJSON的输出? 3)是否有其他方式使用PIVOT但不必指定列?

非常感谢任何帮助。

编辑对AL ALI的响应 我知道语法错误而且它不起作用,但查询看起来像这样:

DECLARE @Cols AS VARCHAR(MAX) = ''
        ,@Query AS NVARCHAR(MAX) = ''

SELECT
    QI.QueueItemID,
    QI.QueueItemStatus,
    QI.StartProcessing,
    QI.EndProcessing,
    SD.*
FROM QueueItems AS QI
LEFT JOIN 
(
    SELECT
        @Cols += ',' + Name
    FROM
        parseJson(QI.SpecificData) 
    WHERE
        Name NOT IN ('DynamicProperties', '-')


    SET @Cols = SUBSTRING(@Cols,2,LEN(@Cols))


    SET @Query = N'SELECT *
    FROM 
    (
        SELECT [StringValue], [Name] 
        FROM parseJson(''' + QI.SpecificData + ''')

    ) [d] 
    PIVOT 
    (
        MAX([StringValue]) 
        FOR [Name] IN (' + @Cols + ')
    ) [piv]'


    EXECUTE (@Query)
) AS SD

结果将是QueueItems中的列,左侧是已解析的JSON字符串中的列。

QueueItemID,StartProcessing,EndProcessing,IndentificationIndex,PaymentMethod等......

0 个答案:

没有答案