繁体   English   中英

从 SQL 中的双转义 JSON 列中提取值

[英]Extract value from double escaped JSON column in SQL

我有 ports_list 表,下面有端口列:

港口 预期输出
"[{\"id\":193,\"name\":\"PORT C\"}]" 端口 C
"[{\"id\":204,\"name\":\"PORT D\"}]" 端口 D
"[{\"id\":45,\"name\":\"PORT I\"},{\"id\":193,\"name\":\"PORT C\"},{\ "id\":204,\"name\":\"PORT D\"},{\"id\":271,\"name\":\"PORT G\"}]" 端口 I,端口 C,端口 D,端口 G

我使用这种方法并以某种方式设法在一行中只有一个端口值时获得结果,不幸的是它无法连续满足多个端口值:

select ports,
REPLACE( substring(ports, CHARINDEX('"name\":\', ports, 1)+10, LEN(ports)-10), 
                        '\"}]"', 
                        ''
                       )
from ports_list
港口 output
"[{\"id\":193,\"name\":\"PORT C\"}]" 端口 C
"[{\"id\":204,\"name\":\"PORT D\"}]" 端口 D
"[{\"id\":45,\"name\":\"PORT I\"},{\"id\":193,\"name\":\"PORT C\"},{\ "id\":204,\"name\":\"PORT D\"},{\"id\":271,\"name\":\"PORT G\"}]" 端口 I"},{"id":193,"name":"PORT C"},{"id":204,"name":"端口 D"},{"id":271,"name": "端口 G"}]"

有人可以帮我按照第一张表获得预期的 output 吗?

您的ports列是双转义的 JSON,换句话说,它包含一个 JSON 转义的字符串,表示 JSON object。

所以我们只需要把它放回常规的 JSON 来查询它。 让我们将其填充到[] JSON 数组中,然后将其传递给JSON_VALUE

select ports,
    STRING_AGG(j.name, ', ')
from ports_list
outer apply OPENJSON(JSON_VALUE('[' + ports + ']', '$[0]'))
    with (name nvarchar(100) '$.name') as j
group by ports;

您创建了一个解决方案,仅在存在一个端口时才解析。

function CharIndex 总是返回第一个 '"name":' 和 function SUBSTRING 总是返回字符串减去最后十个字符。

解决问题的一种形式是创建用户 function 以返回端口的所有 ocorrency。

尝试在下面创建 function

CREATE FUNCTION uf_findPorts
(
    @string nvarchar(max)
)
RETURNS nvarchar(MAX)
AS
BEGIN
    DECLARE
          @length INT ,
          @aux INT ,
          @return NVARCHAR(MAX)
           

  
  SET @length = LEN(@string)
  SET @aux = 1
  SET @return = ''


  WHILE(CHARINDEX('"name\":\', @string,@aux) != 0)
  BEGIN 
    SET @return = @return + '  ' + REPLACE( substring(@string,
            CHARINDEX('"name\":\', @string,@aux)+10, 
               6), 
                        '\"}]"', 
                        ''
                       )
    
    SET @string = SUBSTRING(@string,CHARINDEX('"name\":\', @string,@aux) + 6,LEN(@string) )
    

  END

  RETURN @return
 

END
GO

去测试:

select ports,dbo.uf_findPorts(ports)
from ports_list

SELECT dbo.uf_findPorts('[{\"id\":45,\"name\":\"PORT I\"},{\"id\":193,\"name\":\"PORT C\"},{\"id\":204,\"name\":\"PORT D\"},{\"id\":271,\"name\":\"PORT G\"}]')

SELECT dbo.uf_findPorts('"[{\"id\":193,\"name\":\"PORT C\"}]"')

OBS:如果存在任何写入错误,您可以纠正我

感谢那些试图提供帮助的人。

如果将来有人偶然遇到类似问题,请在此处发布我的解决方案:

 select ports = replace(replace(replace(dbo.fnRemovePatternFromString(dbo.fnRemovePatternFromString(dbo.fnRemovePatternFromString(dbo.fnRemovePatternFromString(ports,'%[\"{}]%',1),'%name:%',5),'%id:%',3),'%[0-9]%',1),'[,',''),',,',','),']','')
    from ports_list

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM