将JSON转换为SQL Server 2016中的表

时间:2018-07-16 07:08:59

标签: json sql-server-2016

我正在处理一个Web项目,其中客户端应用程序通过JSON与DB通信。

最初的实现是在SQL Server 2012上进行的(不支持JSON,因此我们实现了一个用于处理解析的存储功能),现在我们将移至2016年(支持JSON)。

到目前为止,我们正在将处理时间减少很多(在某些情况下,速度要快200倍!)。

有些交互包含需要转换为表的数组。为此,OPENJSON函数执行 ALMOST 我们所需的操作。

在某些(基于数组)情况下,数组中的记录具有一个或多个字段,这些字段也是对象(在这种情况下,也是数组),例如:

    [{
        "Formal_Round_Method": "Floor",
        "Public_Round_Method": "Closest",
        "Formal_Precision": "3",
        "Public_Precision": "3",
        "Formal_Significant_Digits": "3",
        "Public_Significant_Digits": "3",
        "General_Comment": [{
            "Timestamp": "2018-07-16 09:19",
            "From": "1",
            "Type": "Routine_Report",
            "Body": "[To + Media + What]: Comment 1",
            "$$hashKey": "object:1848"
        }, {
            "Timestamp": "2018-07-16 09:19",
            "From": "1",
            "Type": "User_Comment",
            "Body": "[]: Comment 2",
            "$$hashKey": "object:1857"
        }, {
            "Timestamp": "2018-07-16 09:19",
            "From": "1",
            "Type": "Routine_Report",
            "Body": "[To + Media + What]: Comment 3",
            "$$hashKey": "object:1862"
        }]
    }, {
        "Formal_Round_Method": "Floor",
        "Public_Round_Method": "Closest",
        "Formal_Precision": "3",
        "Public_Precision": "3",
        "Formal_Significant_Digits": "3",
        "Public_Significant_Digits": "3",
        "General_Comment": []

    }]

在这里,General_Comment也是一个数组。

运行命令时:

SELECT *
  FROM OPENJSON(@_l_Table_Data)
  WITH (    Formal_Round_Method                 NVARCHAR(16)    '$.Formal_Round_Method'               ,
            Public_Round_Method                 NVARCHAR(16)    '$.Public_Round_Method'               ,
            Formal_Precision                    INT             '$.Formal_Precision'                  ,
            Public_Precision                    INT             '$.Public_Precision'                  ,
            Formal_Significant_Digits           INT             '$.Formal_Significant_Digits'         ,
            Public_Significant_Digits           INT             '$.Public_Significant_Digits'         ,
            General_Comment                     NVARCHAR(4000)  '$.General_Comment'                   
        ) ;

[{@_l_Table_Data是一个保存JSON字符串的变量]

即使其中有is数据(至少在数组的第一个元素中),我们仍在获取列General_Comment = NULL

我想我应该对可能包含 OBJECTS (而不是 SIMPLE VALUES (简单值))的那些列使用不同的语法,但是我不知道该语法应该是什么。

1 个答案:

答案 0 :(得分:2)

我找到了一个实际上可以解决问题的Microsoft页面。

这是查询的外观:

    StringBuilder lsbToMsb=new StringBuilder();

    for(int i=input.length();i>0;i-=2)
    {
        lsbMsb.append(lsbToMsb.substring(i-2,i));
    }


    String lsbMsb=lsbMsb.toString();

因此,您需要在列定义的末尾添加SELECT * FROM OPENJSON(@_l_Table_Data) WITH ( Formal_Round_Method NVARCHAR(16) '$.Formal_Round_Method' , Public_Round_Method NVARCHAR(16) '$.Public_Round_Method' , Formal_Precision INT '$.Formal_Precision' , Public_Precision INT '$.Public_Precision' , Formal_Significant_Digits INT '$.Formal_Significant_Digits' , Public_Significant_Digits INT '$.Public_Significant_Digits' , General_Comment NVARCHAR(MAX) '$.General_Comment' AS JSON ) ; ,并且(上帝知道为什么)类型必须AS JSON

确实很简单!