【问题标题】:Using OPENJSON when the source is not formatted as a set当源未格式化为集合时使用 OPENJSON
【发布时间】:2016-11-12 05:33:50
【问题描述】:

我有一个非常大的源 JSON 文件,其中包含大量未格式化为集合的实体;每个实体之间没有封装方括号和逗号分隔符。所以想象一下,我有 '{}{}' 而不是 '[{},{}]'。我正在尝试使用 OPENJSON 查询它,但在当前结构中我只得到第一条记录。

这就是我正在做的事情:

DECLARE @json VARCHAR(MAX)
SET @json =   
 N'  
    {  
    "Id":1
    } 
    {  
    "Id":2
    }  
'  

SELECT * FROM  
OPENJSON (@json)  
WITH (Id INT)

我得到一个记录 1 的结果。有没有一种方法可以查询结构,还是我非常愿意尝试重新格式化源?

【问题讨论】:

  • 问题在于这实际上不是 JSON。它很接近,但并不完全。我建议先对其进行一些重新格式化,例如添加方括号,然后将每个 { 替换为 ,{ (然后使用 STUFF 删除第二个您将使用流氓逗号的字符。
  • 顺便说一句,我认为@json 应该是NVARCHAR(MAX) ;)。

标签: json tsql sql-server-2016


【解决方案1】:

根据 Rob 的建议,您需要进行一些预格式化。

根据他的建议...如果“json”如您所描述的那样,这将起作用。我不希望它在大量文本中表现得那么好。如果您的 JSON 比这更复杂并且包含嵌套实体,我会跳过 T-SQL 并使用 C# 或 PowerShell

DECLARE @json VARCHAR(MAX)
SET @json =   
 N'  
    {  
    "Id":1
    } 
    {  
    "Id":2
    }  
'  

SELECT * FROM  
OPENJSON (
    (SELECT '[' + STUFF(REPLACE(@json, '{', ',{'),  CHARINDEX('{', @json), 1, '') + ']')
    )
WITH (Id INT)

如果您可以在导入数据库时​​进行预格式化,那么总体上可能是更好的方法

【讨论】:

    【解决方案2】:

    您的问题看起来类似于this thread 中讨论的问题,因此也许同样的解决方案也适用于您的情况(我会使用 JSON.NET 反序列化您的“类 json 数据”,如那里所述,然后使用它直接或再次序列化后使用OPENJSON)

    【讨论】:

      【解决方案3】:

      OPENJSON 需要有效的 JSON。您可以使用 ISJSON 函数检查该值是否有效。

      我们遇到了类似的问题,因为我们有一个有效的 JSON 字符串隐藏在一个更大的字符串中,这意味着整个字符串不是有效的 JSON。我们必须在其中找到并提取有效的 JSON。因此,我们创建了一个计算列来执行此操作。然后,我们的 JSON 流程使用 OPENJSON 从计算列中提取有效的 JSON。你只需要权衡是否坚持。

      【讨论】:

        猜你喜欢
        • 2015-09-02
        • 1970-01-01
        • 2017-03-23
        • 2013-01-16
        • 2016-05-11
        • 2020-09-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多