【问题标题】:How to change a column of JSON array of objects to object in SQL Server如何将一列 JSON 对象数组更改为 SQL Server 中的对象
【发布时间】:2020-09-27 01:32:33
【问题描述】:

我正在处理一个带有 JSON 值列的 SQL 表。该列的每一行都是 JSON 结构中的字符串值。此 JSON 结构始终是一个数组,其中包含一项的一个或多个对象。对象的数量和关键词可以变化。例如,第一行可能如下所示:

[{"Page View":"Page"}
,{"Search Data":"9"}
,{"Search Distance":"undefined"}
,{"Search Location":"undefined"}
,{"Search Filters":"{}"}
,{"Search No Restrictions":"undefined"}
,{"Search Term":"Services"}
,{"Search Type":"Id"}]

第二行的值可能如下所示:

[{"Page Type":"Service"}
,{"Organization ID":"111555666"}
,{"Service ID":"333444"}
,{"refUrl":"https://randomURL"}]

我正在尝试将这些值转换为具有多个元素的一个对象

所以第一行看起来像这样:

{"Page View":"Page"
,"Search Data":"9"
,"Search Distance":"undefined"
,"Search Location":"undefined"
,"Search Filters":"{}"
,"Search No Restrictions":"undefined"
,"Search Term":"Services"
,"Search Type":"Id"}

第二行是这样的:

{"Page Type":"Service"
,"Organization ID":"111555666"
,"Service ID":"333444"
,"refUrl":"https://randomURL"}

我试过这个方法:

SELECT FRUA.Id,
    REPLACE(REPLACE(REPLACE(REPLACE(JSON_column, '{',''),'}',''), '[','{'),']','}')
FROM test.table

这是可行的,但它可能会意外更改 {[ 的值,例如 "Search Filters":"{}",或者会破坏嵌套元素。有没有更好的方法在 SQL Server Azure 12.0.2000.8 上完成此任务?

【问题讨论】:

标签: sql json sql-server sql-server-2017 sql-server-azure


【解决方案1】:

它是 JSON 对象的未命名 JSON 数组。要访问数组的元素,答案使用 JSON_QUERY 和列偏移量。将 JSON 对象从数组中提取到列中后,该解决方案将使用 JSON_VALUE 提取字段值。将字段值提取到列中后,将使用 FOR JSON PATH 对结果表进行序列化并指定 WITHOUT_ARRAY_WRAPPER。

JSON 数据

declare @json           nvarchar(max)=
N'[{"Page View":"Page"}
  ,{"Search Data":"9"}
  ,{"Search Distance":"undefined"}
  ,{"Search Location":"undefined"}
  ,{"Search Filters":"{}"}
  ,{"Search No Restrictions":"undefined"}
  ,{"Search Term":"Services"}
  ,{"Search Type":"Id"}]';

查询

with j_cte as (
    select
       json_query(@json, '$[0]') AS a,
       json_query(@json, '$[1]') AS b,
       json_query(@json, '$[2]') AS c,
       json_query(@json, '$[3]') AS d,
       json_query(@json, '$[4]') AS e,
       json_query(@json, '$[5]') AS f,
       json_query(@json, '$[6]') AS g,
       json_query(@json, '$[7]') AS h )
select json_value(jc.a, N'$."Page View"') AS [Page View],
       json_value(jc.b, N'$."Search Data"') AS [Search Data],
       json_value(jc.c, N'$."Search Distance"') AS [Search Distance],
       json_value(jc.d, N'$."Search Location"') AS [Search Location],
       json_value(jc.e, N'$."Search Filters"') AS [Search Filters],
       json_value(jc.f, N'$."Search No Restrictions"') AS [Search No Restrictions],
       json_value(jc.g, N'$."Search Term"') AS [Search Term],
       json_value(jc.h, N'$."Search Type"') AS [Search Type]
from j_cte jc for json path, without_array_wrapper;

输出

{
  "Page View": "Page",
  "Search Data": "9",
  "Search Distance": "undefined",
  "Search Location": "undefined",
  "Search Filters": "{}",
  "Search No Restrictions": "undefined",
  "Search Term": "Services",
  "Search Type": "Id"
}

【讨论】:

  • 对不起,我应该更好地说明我的问题。有多行,它们的结构不是静态的,这意味着我不能使用假定 JSON 值的长度或关键字的方法。
  • 祝你好运和最良好的祝愿
【解决方案2】:

一种可能的解决方案是使用 OPENJSON() 从存储的 JSON 数组中提取每个 JSON 对象,并使用 SUSBTRING()STRING_AGG() 构建最终输出:

表:

CREATE TABLE Data (JsonData varchar(1000))
INSERT INTO Data (JsonData)
VALUES
   ('[{"Page View":"Page"}
,{"Search Data":"9"}
,{"Search Distance":"undefined"}
,{"Search Location":"undefined"}
,{"Search Filters":"{}"}
,{"Search No Restrictions":"undefined"}
,{"Search Term":"Services"}
,{"Search Type":"Id"}]'),
   ('[{"Page Type":"Service"}
,{"Organization ID":"111555666"}
,{"Service ID":"333444"}
,{"refUrl":"https://randomURL"}]')

表:

UPDATE Data
SET JsonData = (
   SELECT CONCAT('{', STRING_AGG(SUBSTRING([value], 2, LEN([value]) - 2), ','), '}')
   FROM OPENJSON(JsonData)
)

结果:

JsonData
{"Page View":"Page","Search Data":"9","Search Distance":"undefined","Search Location":"undefined","Search Filters":"{}","Search No Restrictions":"undefined","Search Term":"Services","Search Type":"Id"}
{"Page Type":"Service","Organization ID":"111555666","Service ID":"333444","refUrl":"https://randomURL"}

【讨论】:

    猜你喜欢
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 2016-10-16
    • 1970-01-01
    相关资源
    最近更新 更多