如何从 SQL 服务器中的嵌套 JSON 中提取数据

How to extract data from nested JSON in SQL Server

DECLARE @CONTACTS varchar(max)
SET @CONTACTS = 
N'[
{"contacts":"[{\"idRole\":1,\"cdsid\":\"RWILS351\"},{\"idRole\":3,\"cdsid\":\"EKANOUS\"},{\"idRole\":126,\"cdsid\":\"RLAESCH1\"}]"},
{"contacts":"[{\"idRole\":1,\"cdsid\":\"RWILS351\"},{\"idRole\":3,\"cdsid\":\"EKANOUS\"}]"},
{"contacts":"[{\"idRole\":1,\"cdsid\":\"OINES\"},{\"idRole\":1,\"cdsid\":\"YSEGARRA\"},{\"idRole\":3,\"cdsid\":\"OINES\"},{\"idRole\":3,\"cdsid\":\"TISMAIL3\"}]"},
{"contacts":"[{\"idRole\":1,\"cdsid\":\"DBELL30\"},{\"idRole\":3,\"cdsid\":\"DBELL30\"}]"},
{"contacts":"[{\"idRole\":1,\"cdsid\":\"DBELL30\"},{\"idRole\":3,\"cdsid\":\"DBELL30\"}]"},
{"contacts":"[{\"idRole\":1,\"cdsid\":\"DSANGINE\"},{\"idRole\":3,\"cdsid\":\"DSANGINE\",\"idAttribute\":[{\"pmtGroup\":2},{\"pmtGroup\":5}]},{\"idRole\":3,\"cdsid\":\"EDESMET\"},{\"idRole\":126,\"cdsid\":\"NSPENC16\"}]"},
{"contacts":"[{\"idRole\":1,\"cdsid\":\"DSANGINE\"},{\"idRole\":3,\"cdsid\":\"DSANGINE\",\"idAttribute\":[{\"pmtGroup\":2}]},{\"idRole\":3,\"cdsid\":\"EDESMET\"},{\"idRole\":126,\"cdsid\":\"NSPENC16\"}]"},
{"contacts":"[{\"idRole\":1,\"cdsid\":\"DSANGINE\"},{\"idRole\":3,\"cdsid\":\"DSANGINE\",\"idAttribute\":[{\"pmtGroup\":2}]},{\"idRole\":3,\"cdsid\":\"EDESMET\"},{\"idRole\":126,\"cdsid\":\"NSPENC16\"}]"},
{"contacts":"[{\"idRole\":1,\"cdsid\":\"DSANGINE\"},{\"idRole\":3,\"cdsid\":\"DSANGINE\",\"idAttribute\":[{\"pmtGroup\":2},{\"pmtGroup\":5}]},{\"idRole\":3,\"cdsid\":\"EDESMET\"},{\"idRole\":126,\"cdsid\":\"NSPENC16\"}]"},
{"contacts":"[{\"idRole\":1,\"cdsid\":\"DSANGINE\"},{\"idRole\":3,\"cdsid\":\"DSANGINE\",\"idAttribute\":[{\"pmtGroup\":2}]},{\"idRole\":3,\"cdsid\":\"EDESMET\"},{\"idRole\":126,\"cdsid\":\"NSPENC16\"}]"},
{"contacts":"[{\"idRole\":1,\"cdsid\":\"DSANGINE\"},{\"idRole\":3,\"cdsid\":\"DSANGINE\",\"idAttribute\":[{\"pmtGroup\":2}]},{\"idRole\":3,\"cdsid\":\"EDESMET\"},{\"idRole\":126,\"cdsid\":\"NSPENC16\"}]"},
{"contacts":"[{\"idRole\":1,\"cdsid\":\"DSANGINE\"},{\"idRole\":3,\"cdsid\":\"DSANGINE\",\"idAttribute\":[{\"pmtGroup\":2}]},{\"idRole\":3,\"cdsid\":\"EDESMET\"},{\"idRole\":126,\"cdsid\":\"NSPENC16\"}]"},
{"contacts":"[{\"idRole\":3,\"cdsid\":\"THERMANN\"}]"}]'

SELECT d.idRole, d.cdsid,e.pmtGroup
FROM  OPENJSON (@CONTACTS)
WITH (
    contacts nvarchar(max) AS JSON
) as c 
CROSS APPLY OPENJSON (c.contacts) 
WITH (
    idRole INT '$.idRole',
    cdsid NVARCHAR(50) '$.cdsid',
    idAttribute NVARCHAR(MAX) '$.idAttribute' AS JSON
) as d
CROSS APPLY OPENJSON(d.idAttribute)
WITH (
    pmtGroup NVARCHAR(8) '$.pmtGroup'
) as e;

我需要从 JSON 中获取值 idRole、cdsid、pmtGroup。我的查询中缺少什么?我做了一些研究并尝试了交叉应用,但没有返回任何数据

首先,您是否正在使用 openjson,因此您应该提供格式正确的 json 数据。添加此行以在操作前格式化您的数据。

此外,无需终止 ",因为这是一个可识别的 sql 字符。

SET @CONTACTS= REPLACE(REPLACE(REPLACE(@CONTACTS, '\', ''), '"[', '['), ']"', ']')

问题是 contacts 中包含的值不是 JSON 对象,它是一个包含 序列化 JSON 对象的字符串.

因此您需要删除 AS JSON 才能检索它。

此外,如果你想获得没有pmtGroup的对象,你需要OUTER APPLY

SELECT d.idRole, d.cdsid,e.pmtGroup
FROM  OPENJSON (@CONTACTS)
WITH (
    contacts nvarchar(max)
) as c 
CROSS APPLY OPENJSON (c.contacts) 
WITH (
    idRole INT,
    cdsid NVARCHAR(50),
    idAttribute NVARCHAR(MAX) AS JSON
) as d
OUTER APPLY OPENJSON(d.idAttribute)
WITH (
    pmtGroup NVARCHAR(8)
) as e;

或者你可以只使用路径 $.idAttribute[0].pmtGroup

SELECT d.idRole, d.cdsid,d.pmtGroup
FROM  OPENJSON (@CONTACTS)
WITH (
    contacts nvarchar(max)
) as c 
CROSS APPLY OPENJSON (c.contacts) 
WITH (
    idRole INT,
    cdsid NVARCHAR(50),
    pmtGroup NVARCHAR(8) '$.idAttribute[0].pmtGroup'
) as d;

db<>fiddle