我正在处理一个 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 上有更好的方法来完成此任务吗?
它是 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"
}
一种可能的解决方案是使用
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"}