json - 从 SQL Server 中的 JSON 获取键的名称

标签 json sql-server sql-server-json

我有以下 JSON。

[
  {
    "attributes": {
        "2003": "Some text",
        "2004": 0,
        "2006": 0,
        "2008": 0,
        "2011": 0,
        "2120": 0
    },
    "path": "/Path1",
    "changeDate": "2019-11-11T13:56:37.987Z",
    "guid": "00000000-0000-0000-0000-000000000000",
    "version": 0,
    "timestamp": "2019-11-11T14:21:14.86427Z"
  },
  {
    "attributes": {
        "2121": 0,
        "2297": 0,
        "2298": 0,
        "2299": 0,
        "2805": 0,
        "8501": 0,
        "12004": 0,
        "13266": 0,
        "13282": 0

    },
    "path": "P:/Path2/SubPath",
    "changeDate": "2019-11-11T13:55:35.943Z",
    "guid": "705b30ab-53b0-42ee-bb98-6d80daae2e18",
    "version": 1,
    "timestamp": "2019-11-11T09:08:54.417Z"
  },
  {
    "attributes": {},
    "path": "PP:/OneMorePath",
    "changeDate": "2019-11-11T14:20:49.5Z",
    "guid": "b9aac8f3-1f2a-4b52-b8d8-af6b654d3f0f",
    "version": 41,
    "timestamp": "2019-11-11T13:26:24.723Z"
  }
]

为此,我有两个 SQL Server 表。
CREATE TABLE [dbo].[Foo]
(
    [Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT(NEWID()),
    [Path] NVARCHAR(128) NOT NULL,
    [ChangeDate] DATETIME NOT NULL,
    [Guid] UNIQUEIDENTIFIER NOT NULL,
    [Version] INT NOT NULL,
    [Timestamp] DATETIME NOT NULL
)

CREATE TABLE [dbo].[FooAttributes]
(
    [Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT(NEWID()),
    [IdFoo] UNIQUEIDENTIFIER NOT NULL,
    [Key] INT NOT NULL,
    [Value] NVARCHAR(255) NOT NULL
)

对于 header 数据,我可以在 SQL Server 中查询它。
SELECT *
FROM OPENJSON(@Json)
      WITH (
        [Path] NVARCHAR(128) 'strict $.path',
        [ChangeDate] DATETIME2 '$.changeDate',
        [Guid] UNIQUEIDENTIFIER '$.guid',
        [Version] INT '$.version',
        [Timestamp] DATETIME2 '$.timestamp'
      )

为此,我得到了这个结果。
Path                               | ChangeDate                  | Guid                                 | Version | Timestamp
------------------------------------------------------------------------------------------------------------------------------------------------
/Path1                             | 2019-11-11 13:56:37.9870000 | 00000000-0000-0000-0000-000000000000 | 0       | 2019-11-11 14:21:14.8642700
P:/Path2/SubPath                   | 2019-11-11 13:55:35.9430000 | 705B30AB-53B0-42EE-BB98-6D80DAAE2E18 | 1       | 2019-11-11 09:08:54.4170000
PP:/OneMorePath                    | 2019-11-11 14:20:49.5000000 | B9AAC8F3-1F2A-4B52-B8D8-AF6B654D3F0F | 41      | 2019-11-11 13:26:24.7230000

还行吧。但是我找不到任何可能性来查询属性以获得如下所示的类型,因为这不是键/值对数组,而是带有值的字段。
IdFoo    | AttributeName | AttributeValue
---------------------------------------
<IdFoo1> | 2003          | Some text
<IdFoo1> | 2004          | 0
<IdFoo1> | 2006          | 0
<IdFoo1> | 2008          | 0
<IdFoo1> | 2011          | 0
<IdFoo1> | 2120          | 0
<IdFoo2> | 2121          | 0
<IdFoo2> | 2297          | 0
<IdFoo2> | 2298          | 0
<IdFoo2> | 2299          | 0
<IdFoo2> | 2805          | 0
<IdFoo2> | 8501          | 0
<IdFoo2> | 12004         | 0
<IdFoo2> | 13266         | 0
<IdFoo2> | 13282         | 0

SQL Server 2016 中是否有可能根据需要获得此子结构?

最佳答案

使用 As JsonCross apply和另一个 OpenJson可以给你想要的结果:

SELECT [Guid],  [key], [value]
FROM OPENJSON(@Json)
      WITH (
        [Guid] UNIQUEIDENTIFIER '$.guid',
        [Attributes] NVARCHAR(max) '$.attributes' As Json
      )
CROSS APPLY OPENJSON(Attributes)    

请注意 keynvarchar(4000)valuenvarchar(max) .

DbFiddle<>UK 上查看现场演示

关于json - 从 SQL Server 中的 JSON 获取键的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58815703/

相关文章:

sql - 如何使SQL表的字段值成为SQL中JSON对象的键?

c# - SqlConnection 在 .NET Core 3.1 上打开失败,在 4.6.1 Framework 上打开成功

C# 哈希字节到 Java -- 将 SQL Server HashByte 转换为 Java

javascript - 显示 USGS 地震 JSON 数据的元数据

json - 如何使用 Bash 在单引号内回显变量?

php - 如何使用 Laravel 5.* 将二进制数据插入 SQL

sql-server - SQL Server FOR JSON路径嵌套数组

JSON 文本格式不正确。在位置 0 发现意外字符 'N'

java - 如何迭代由 GSON 生成的 JAVA 对象列表

javascript - 动态构建时无法访问 JSON 对象的属性,但静态构建时可以