【问题标题】:parsing JSON column in SQL Server在 SQL Server 中解析 JSON 列
【发布时间】:2018-04-23 00:26:30
【问题描述】:

我有一个 JSON 字符串存储在 SQL Server 表列中。该列名为 MSSG_RECIPS 并包含一个长文本字符串,例如:

`{"type":"email","recipient":"\"Artzer, Daniel J\" <DJArtzer@emailaddr.com>","sentTS":"2017-11-08T20:58:14.600Z"},{"type":"email","recipient":"\"Friedman, Brian\" <BFriedman@emailaddr.com>","sentTS":"2017-11-08T20:58:14.600Z"},{"type":"email","recipient":"\"Higgins, Laura L\" <LLHiggins@emailaddr.com>","sentTS":"2017-11-08T20:58:14.600Z"},{"type":"email","recipient":"\"Landenberger, Dan R\" <DRLandenberger@emailaddr.com>","sentTS":"2017-11-08T20:58:14.600Z"},{"type":"email","recipient":"\"Leitl, Scott\" <SLeitl@emailaddr.com>","sentTS":"2017-11-08T20:58:14.600Z"},{"type":"email","recipient":"\"Mendoza, Mario\" <MMendoza@emailaddr.com>","sentTS":"2017-11-08T20:58:14.600Z"}`

这个示例字符串说明了我的 JSON 格式,每个元素都以逗号分隔。

我能够解析这两种方式。一,使用 JSON_VALUE,我可以将属性检索为单独的列:

select
 JSON_VALUE(mssg_recips, '$.type'),
 JSON_VALUE(mssg_recips, '$.recipient'),
 JSON_VALUE(mssg_recips, '$.sentTS'),
 DOC_ID
from MY_JSON_TAB

但是,这只会返回 JSON 的第一个元素。

我尝试的另一种方法是:

select doc_id, value as EMAIL_RECIP
from MY_JSON_TAB
Cross Apply OPENJSON(MSSG_RECIPS)

这会将记录作为行而不是列返回,但同样只返回第一个元素。

可以说,我如何向下遍历以检索第二个、第三个等元素?

【问题讨论】:

    标签: json sql-server


    【解决方案1】:

    JSON_VALUE 返回单个标量值。对于嵌套 JSON 对象的数组,您可以使用 JSON_QUERY

    当使用CROSS APPLY OPENJSON() WITH( ...) 时,您需要指定要绘制的 JSON 数组的属性,例如

    select id, recipient, sentTS
    from my_json_tab
    CROSS APPLY OPENJSON(my_json) WITH(
           recipient varchar(200)
         , sentTS varchar(60)
         ) as my_json_array
    
    +----+-------------------------------------------+--------------------------+
    | id |                 recipient                 |          sentTS          |
    +----+-------------------------------------------+--------------------------+
    |  1 | "AAAA, Daniel J" <DJArtzer@emailaddr.com> | 2017-11-08T20:58:14.600Z |
    |  1 | "BBBB, Brian" <BFriedman@emailaddr.com>   | 2017-11-08T20:58:14.600Z |
    |  1 | "CCCC, Laura L" <LLHiggins@emailaddr.com> | 2017-11-08T20:58:14.600Z |
    |  2 | "xxxx, Daniel J" <DJArtzer@emailaddr.com> | 2017-11-08T20:58:14.600Z |
    +----+-------------------------------------------+--------------------------+
    

    注意:存储多元素 JSON 时,您需要将整个 JSON 包含在 [ ]

    在示例结果中 ID=1 有 [ json-here ] 但 id=2 没有,请注意结果的差异。返回 ID=1 的所有元素,但对于 id=2 则不是这样。

    请参阅此dbfiddle,了解上述示例的现场演示。

    OPENJSON 是一个表值函数,它解析 JSON 文本并返回 JSON 输入中的对象和属性作为行和列。在 换句话说,OPENJSON 提供了一个 JSON 文档的行集视图。你 可以显式指定行集中的列和 JSON 属性 用于填充列的路径。由于 OPENJSON 返回一组 行,您可以在 Transact-SQL 的 FROM 子句中使用 OPENJSON 就像您可以使用任何其他表、视图或表值一样的语句 功能。 https://docs.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql

    【讨论】:

    • 很明显,我还是做错了。对每条记录应用 ISJSON 会为所有非空条目返回 1。到目前为止,一切都很好。但是,JSON_QUERY 仍然返回所有 NULL:select distinct PAYLOAD_LINE_SEG, JSON_QUERY(PAYLOAD_LINE_SEG,'$.pipeDiameter') as pipe_info from SYSTEM_BLOWDOWNS 返回:[{"lineName":"AQ46-5","pipeDiameter":"10","pipeLength ":"15620","pressure":"75","duration":"no","volume":"158"}] NULL 我错过了什么?
    • 您的问题现在解决了吗?你对这个答案还有疑问吗?要接受答案“Click the Tick”了解更多信息,请参阅help/accepting
    • 不,我的问题还没有完全解决。我试图从我的 JSON Table 列中提供一个示例,以及我之前评论中的 JSON_QUERY 语法。我似乎仍然无法让 JSON_QUERY 工作,我不明白为什么不这样做。谢谢!
    • 我赞成你的回答。这正是我想要弄清楚的,谢谢你的小提琴!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    • 2021-08-03
    • 2020-02-09
    • 1970-01-01
    相关资源
    最近更新 更多