如何将对象的 JSON 数组的列更改为 SQL Server 中的对象

问题描述 投票:0回答:2

我正在处理一个 SQL 表,其中有一列包含 JSON 值。 该列的每一行都是 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 azure-sql-database
2个回答
0
投票

它是 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"
}

0
投票

一种可能的解决方案是使用

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"}
© www.soinside.com 2019 - 2024. All rights reserved.