如何反转SQL Server中的OPENJSON()函数?

Mar*_*sen 5 sql-server json

sql-server OPENJSON() 函数可以获取 json 数组并将其转换为带有键值对的 sql 表,例如:

\n\n
DECLARE @json NVARCHAR(MAX);\nSET @json = \'{\n    "key1": "val1",\n    "key2": "val2",\n    "key3": "val3"\n    }\';\n\nSELECT * FROM OPENJSON(@json, \'$\')\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果:

\n\n
key     value   type\n--------------------\nkey1    val1    1\nkey2    val2    1\nkey3    val3    1\n
Run Code Online (Sandbox Code Playgroud)\n\n

将此键/值表转换回 json 数组的最佳通用方法是什么?

\n\n

为什么?如果我们可以使用单个函数来完成此操作,它将打开一系列 json 修改,否则在 sql server 上是不可能的,例如:

\n\n
    \n
  • 重新排序元素
  • \n
  • 重命名属性(键名)
  • \n
  • 将 json 数组拆分为更小的数组/合并 json 数组
  • \n
  • 比较 json 数组(两个 json 中都存在哪些键/值元素?有什么区别?)
  • \n
  • 清理 json(删除语法空格/换行符以压缩它)
  • \n
\n\n

现在,我可以开始执行简单的 CONCAT(\'"\',[key],\'":"\',[value]),然后执行逗号列表聚合。但是如果我想要一个代码,既易于在我的代码库中应用,又适用于所有数据类型,这不是一个简单的任务。通过查看json 格式定义,转换应考虑 a) 6 种不同的数据类型,b) 转义字符,c) SQL NULL/json null 处理,d) 我可能忽略了,即至少应该支持以下示例:

\n\n
DECLARE @test_json NVARCHAR(MAX);\nSET @test_json = \'{\n    "myNull": null,\n    "myString": "start_\\\\_\\"_\\/_\\b_\\f_\\n_\\r_\\t_\\u2600_stop",\n    "myNumber": 3.14,\n    "myBool": true,\n    "myArray": ["1", 2],\n    "myObject": {"key":"val"}\n    }\'\nSELECT * FROM OPENJSON(@test_json, \'$\')\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果:

\n\n
key         value                           type\n------------------------------------------------\nmyNull      NULL                            0\nmyString    start_\\_"_/___ _ _ _\xe2\x98\x80_stop      1\nmyNumber    3.14                            2\nmyBool      true                            3\nmyArray     ["1", 2]                        4\nmyObject    {"key":"val"}                   5\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于字符串聚合部分,我们长期以来一直遭受“FOR XML PATH”的痛苦。幸运的是,我们在 SQL2017/AzureDB 上有 STRING_AGG(),我将接受依赖于 STRING_AGG() 的解决方案。

\n

Thi*_*iro 0

您可以使用FOR JSON使用此命令

select * from table for json auto
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我的结果:

[{"LogId":1,"DtLog":"2017-09-30T21:04:45.6700000","FileId":1}, {"LogId":2,"DtLog":"2017-09-30T21:08 :35.8633333","FileId":3},{"LogId":3,"DtLog":"2017-09-30T21:08:36.4433333","FileId":2},{"LogId":4,"DtLog ":"2017-09-30T21:08:36.9866667","FileId":12},{"LogId":5,"DtLog":"2017-09-30T21:15:22.5366667","FileId":13} ,{"LogId":6,"DtLog":"2017-09-30T21:38:43.7866667","FileId":17}]