在TSQL中解析JSON

R0b*_*n1k 108 t-sql sql-server json

是否可以在TSQL中解析JSON?我不是要创建一个JSON字符串,我的意思是解析作为参数传入的json字符串.

Phi*_*tor 227

我似乎有一个巨大的受虐狂,因为我写了一个JSON解析器.它将JSON文档转换为SQL Adjacency列表,该表很容易用于更新数据表.实际上,我做得更糟,因为我已经完成了代码来执行反向过程,即从层次结构表转到JSON字符串

文章和代码在这里:在SQL服务器中使用Json字符串.

Select * from parseJSON('{
  "Person":
  {
     "firstName": "John",
     "lastName": "Smith",
     "age": 25,
     "Address":
     {
        "streetAddress":"21 2nd Street",
        "city":"New York",
        "state":"NY",
        "postalCode":"10021"
     },
     "PhoneNumbers":
     {
        "home":"212 555-1234",
        "fax":"646 555-4567"
     }
  }
}
')
Run Code Online (Sandbox Code Playgroud)

要得到:

在此输入图像描述


gbn*_*gbn 58

更新:从SQL Server 2016开始,现在可以在TSQL中解析JSON.

在本地,没有支持.你必须使用CLR.就这么简单,除非你有一个巨大的自虐条纹,并希望在SQL中编写一个JSON解析器

通常,民众要求DB提供JSON输出,互联网上也有例子.但进入DB?

  • JSON是一个非常简单的协议,所以它真的不需要大量的受虐狂.一旦拥有它,就可以使用一个例程来处理所有JSON.无论如何,我已经在这里为你做了http://www.simple-talk.com/sql/t-sql-programming/consuming-json-strings-in-sql-server/ (58认同)
  • Phil Factor:我多年来一直在读你的文章.如果你今天没有写过这篇文章*我可能在6个月之前引用它时我回答了... (10认同)
  • 在新的SQL Server 2016中有一个内置的解析JSON文本的支持. (9认同)

Irv*_*nin 24

最后,SQL Server 2016将添加Native JSON支持!!

参考:

SQL Server 2016中的其他功能包括:

  • 行级安全性和动态数据屏蔽的附加安全性增强功能可以使用Always
    Encrypted完善我们的安全性投资.
  • 通过多个同步副本和辅助负载
    平衡,AlwaysOn的改进可实现更强大的可用性和灾难恢复.
  • 本机JSON支持,可为您的多种数据提供更好的性能和支持.
  • SQL Server企业信息管理(EIM)工具和Analysis Services在性能,可用性和可伸缩性方面进行了升级.
  • 更快的混合备份,高可用性和灾难恢复方案,可将您的本地数据库备份和还原到Azure
    ,并将您的SQL Server AlwaysOn辅助数据放入Azure.

Announcment:http://blogs.technet.com/b/dataplatforminsider/archive/2015/05/04/sql-server-2016-public-preview-coming-this-summer.aspx

功能博客文章:http://blogs.msdn.com/b/jocapc/archive/2015/05/16/json-support-in-sql-server-2016.aspx

  • 可能SQL Server 2016 CTP 3将使用OpenJSON语法支持JSON到SQL Server:http://www.kodyaz.com/t-sql/sql-server-2016-openjson-error.aspx (2认同)

Mai*_*mad 8

SQL Server 2016 支持json data使用OPENJSON. 您可以使用OPENJSON映射json data到行和列。

您的 json Data

[
 { "id" : 2,"name": "John"},
 { "id" : 5,"name": "John"}
]
Run Code Online (Sandbox Code Playgroud)

以下是如何在 sql 中处理 json

//@pJson is json data passed from code.  

INSERT INTO YourTable (id, Name)
 SELECT id, name
 FROM OPENJSON(@pJson)
 WITH (id int,
       name nvarchar(max))
Run Code Online (Sandbox Code Playgroud)

是一篇详细的文章,涵盖了这个主题。


小智 5

我也有一个巨大的自虐倾向,因为我已经编写了另一个 JSON 解析器。这使用了一种程序方法。它使用一个类似的 SQL 层次列表表来存储解析的数据。包裹中还有:

  • 逆向过程:从层次结构到 JSON
  • 查询函数:从 JSON 对象中获取特定值

请随意使用并玩得开心

http://www.codeproject.com/Articles/1000953/JSON-for-Sql-Server-Part


Vit*_*sov 5

不久前,我开发了自己的 SQL Server 2016+ JSON 解析器。我在所有项目中都使用它 - 性能非常好。我希望它也能帮助别人。

函数的完整代码:

ALTER FUNCTION [dbo].[SmartParseJSON] (@json NVARCHAR(MAX))
RETURNS @Parsed TABLE (Parent NVARCHAR(MAX),Path NVARCHAR(MAX),Level INT,Param NVARCHAR(4000),Type NVARCHAR(255),Value NVARCHAR(MAX),GenericPath NVARCHAR(MAX))
AS
BEGIN
    -- Author: Vitaly Borisov
    -- Create date: 2018-03-23
    ;WITH crData AS (
        SELECT CAST(NULL AS NVARCHAR(4000)) COLLATE DATABASE_DEFAULT AS [Parent]
            ,j.[Key] AS [Param],j.Value,j.Type
            ,j.[Key] AS [Path],0 AS [Level]
            ,j.[Key] AS [GenericPath]
        FROM OPENJSON(@json) j
        UNION ALL
        SELECT CAST(d.Path AS NVARCHAR(4000)) COLLATE DATABASE_DEFAULT AS [Parent]
            ,j.[Key] AS [Param],j.Value,j.Type 
            ,d.Path + CASE d.Type WHEN 5 THEN '.' WHEN 4 THEN '[' ELSE '' END + j.[Key] + CASE d.Type WHEN 4 THEN ']' ELSE '' END AS [Path]
            ,d.Level+1
            ,d.GenericPath + CASE d.Type WHEN 5 THEN '.' + j.[Key] ELSE '' END AS [GenericPath]
        FROM crData d 
        CROSS APPLY OPENJSON(d.Value) j
        WHERE ISJSON(d.Value) = 1
    )
    INSERT INTO @Parsed(Parent, Path, Level, Param, Type, Value, GenericPath)
    SELECT d.Parent,d.Path,d.Level,d.Param
        ,CASE d.Type 
            WHEN 1 THEN CASE WHEN TRY_CONVERT(UNIQUEIDENTIFIER,d.Value) IS NOT NULL THEN 'UNIQUEIDENTIFIER' ELSE 'NVARCHAR(MAX)' END 
            WHEN 2 THEN 'INT' 
            WHEN 3 THEN 'BIT' 
            WHEN 4 THEN 'Array' 
            WHEN 5 THEN 'Object' 
                ELSE 'NVARCHAR(MAX)'
         END AS [Type]
        ,CASE 
            WHEN d.Type = 3 AND d.Value = 'true' THEN '1'
            WHEN d.Type = 3 AND d.Value = 'false' THEN '0'
                ELSE d.Value
         END AS [Value]
        ,d.GenericPath
    FROM crData d
    OPTION(MAXRECURSION 1000) /*Limit to 1000 levels deep*/
    ;
    RETURN;
END
GO
Run Code Online (Sandbox Code Playgroud)

使用示例:

DECLARE @json NVARCHAR(MAX) = '{"Objects":[{"SomeKeyID":1,"Value":3}],"SomeParam":"Lalala"}';
SELECT j.Parent, j.Path, j.Level, j.Param, j.Type, j.Value, j.GenericPath 
FROM dbo.SmartParseJSON(@json) j;
Run Code Online (Sandbox Code Playgroud)

多级使用示例:

DECLARE @json NVARCHAR(MAX) = '{"Objects":[{"SomeKeyID":1,"Value":3}],"SomeParam":"Lalala"}';
DROP TABLE IF EXISTS #ParsedData;
SELECT j.Parent, j.Path, j.Level, j.Param, j.Type, j.Value, j.GenericPath 
INTO #ParsedData
FROM dbo.SmartParseJSON(@json) j;

SELECT COALESCE(p2.GenericPath,p.GenericPath) AS [GenericPath]
    ,COALESCE(p2.Param,p.Param) AS [Param]
    ,COALESCE(p2.Value,p.Value) AS [Value]
FROM #ParsedData p
LEFT JOIN #ParsedData p1 ON p1.Parent = p.Path AND p1.Level = 1
LEFT JOIN #ParsedData p2 ON p2.Parent = p1.Path AND p2.Level = 2
WHERE p.Level = 0
;
DROP TABLE IF EXISTS #ParsedData;
Run Code Online (Sandbox Code Playgroud)