Sql 如何从列中提取特定文本

Sql 如何从列中提取特定文本,sql,sql-server,tsql,Sql,Sql Server,Tsql,我正在使用SQL Server 2016,在其中一个nvarchar(max)type列中加载JSON响应。 现在我想创建一个派生列,或者甚至是一个视图,它将在完整的JSON响应中找到特定的值,并仅在新的派生列中显示该值 例如: **Complete_JSON_Repsone** --> this is SQL column {"result":{"banner_image_light":"","country&quo

我正在使用SQL Server 2016,在其中一个
nvarchar(max)
type列中加载JSON响应。 现在我想创建一个派生列,或者甚至是一个视图,它将在完整的JSON响应中找到特定的值,并仅在新的派生列中显示该值

例如:

**Complete_JSON_Repsone**  --> this is SQL column
{"result":{"banner_image_light":"","country":"USA","parent":"","notes":"","stock_symbol":"","u_op_dev_version":"","u_restriciton":"No","discount":"","sys_id":"7a2c008c1b07ac50a62cea0ce54bcbe8","market_cap":"0","customer":"false"}}
我尝试了下面的查询,但它没有给出预期的结果,它在
sys\u id
之后打印了所有内容:

SELECT 
   Substring (
      a.Complete_JSON_Repsone, 
      Charindex( '"sys_id":', Complete_JSON_Repsone) + 1, 
      Len(Complete_JSON_Repsone) 
   ) AS [Sys_Idd] 
FROM <table-name> a
预期产出:

 Sys_Idd
 7a2c008c1b07ac50a62cea0ce54bcbe8
更新

样本输入:

Create table dbo.log1
(
  Id varchar(50),
  Complete_JSON_Response nvarchar(max),
  Sys_Id varchar(50)
)


insert into dbo.log1 (Id,Complete_JSON_Response) 
values ('S1','{"result":{"banner_image_light":"","country":"USA","parent":"","notes":"","stock_symbol":"","u_op_dev_version":"","u_restriciton":"No","discount":"","sys_id":"7a2c008c1b07ac50a62cea0ce54bcbe8","market_cap":"0","customer":"false"}}')
,('S2','{"result":{"banner_image_light":"","country":"Aus","parent":"","notes":"","stock_symbol":"","u_op_prod_version":"","u_restriciton":"No","discount":"","sys_id":"5b2c008c1b07ac50a62cea0ce54bcbe8","market_cap":"1","customer":"TRUE"}}')

select * from dbo.log1
Id    Sys_Id
S1   7a2c008c1b07ac50a62cea0ce54bcbe8
S2   5b2c008c1b07ac50a62cea0ce54bcbe8
在上面的select query prints中,Sys_id列的NULL值作为该列的值,而不是最初插入的值。我希望在预期的输出中,它应该只填充(派生)从Complete_JSON_Response列到sys_id列的sys_id值,而不是NULL

预期输出:

Create table dbo.log1
(
  Id varchar(50),
  Complete_JSON_Response nvarchar(max),
  Sys_Id varchar(50)
)


insert into dbo.log1 (Id,Complete_JSON_Response) 
values ('S1','{"result":{"banner_image_light":"","country":"USA","parent":"","notes":"","stock_symbol":"","u_op_dev_version":"","u_restriciton":"No","discount":"","sys_id":"7a2c008c1b07ac50a62cea0ce54bcbe8","market_cap":"0","customer":"false"}}')
,('S2','{"result":{"banner_image_light":"","country":"Aus","parent":"","notes":"","stock_symbol":"","u_op_prod_version":"","u_restriciton":"No","discount":"","sys_id":"5b2c008c1b07ac50a62cea0ce54bcbe8","market_cap":"1","customer":"TRUE"}}')

select * from dbo.log1
Id    Sys_Id
S1   7a2c008c1b07ac50a62cea0ce54bcbe8
S2   5b2c008c1b07ac50a62cea0ce54bcbe8

SQL Server 2016支持JSON,因此您可以尝试使用
JSON\u VALUE()

作为附加选项,您可以通过递归搜索创建简化的自定义项:

CREATE FUNCTION dbo.ParseJson (
    @json nvarchar(max),
    @key nvarchar(max)
)
RETURNS @ResultTable TABLE (
   [value] nvarchar(max)
)
AS
BEGIN
   ;WITH rCTE AS (
      SELECT 
          CONVERT(nvarchar(max), N'$') COLLATE DATABASE_DEFAULT AS [path], 
          CONVERT(nvarchar(max), JSON_QUERY(@json, '$')) COLLATE DATABASE_DEFAULT AS [value]
      UNION ALL
      SELECT 
         CONVERT(nvarchar(max), c.[key]) COLLATE DATABASE_DEFAULT,
         CONVERT(nvarchar(max), c.[value]) COLLATE DATABASE_DEFAULT                                        
      FROM rCTE r
      CROSS APPLY OPENJSON(r.[value]) c
      WHERE ISJSON(r.[value]) = 1
   )
   INSERT INTO @ResultTable ([value])
   SELECT [value]
   FROM rCTE
   WHERE (ISJSON([value]) = 0) AND (path = @key)
   
   RETURN
END
声明:

DECLARE @json nvarchar(max) = N'
   {
   "result":{
      "banner_image_light":"",
      "country":"USA",
      "parent":"",
      "notes":"",
      "stock_symbol":"",
      "u_op_dev_version":"",
      "u_restriciton":"No",
      "discount":"",
      "sys_id":"7a2c008c1b07ac50a62cea0ce54bcbe8",
      "market_cap":"0",
      "customer":"false"
   },
   "result2":{
      "sys_id":"xxxx008c1b07ac50a62cea0ce54bcbe8"
   }
   }
'

SELECT j.[value] AS sys_id
FROM (VALUES (@json)) a (Complete_JSON_Response)
OUTER APPLY dbo.ParseJson(a.Complete_JSON_Response, 'sys_id') j
结果:

sys_id
--------------------------------
xxxx008c1b07ac50a62cea0ce54bcbe8
7a2c008c1b07ac50a62cea0ce54bcbe8

SQL Server 2016支持JSON,因此您可以尝试使用
JSON\u VALUE()

作为附加选项,您可以通过递归搜索创建简化的自定义项:

CREATE FUNCTION dbo.ParseJson (
    @json nvarchar(max),
    @key nvarchar(max)
)
RETURNS @ResultTable TABLE (
   [value] nvarchar(max)
)
AS
BEGIN
   ;WITH rCTE AS (
      SELECT 
          CONVERT(nvarchar(max), N'$') COLLATE DATABASE_DEFAULT AS [path], 
          CONVERT(nvarchar(max), JSON_QUERY(@json, '$')) COLLATE DATABASE_DEFAULT AS [value]
      UNION ALL
      SELECT 
         CONVERT(nvarchar(max), c.[key]) COLLATE DATABASE_DEFAULT,
         CONVERT(nvarchar(max), c.[value]) COLLATE DATABASE_DEFAULT                                        
      FROM rCTE r
      CROSS APPLY OPENJSON(r.[value]) c
      WHERE ISJSON(r.[value]) = 1
   )
   INSERT INTO @ResultTable ([value])
   SELECT [value]
   FROM rCTE
   WHERE (ISJSON([value]) = 0) AND (path = @key)
   
   RETURN
END
声明:

DECLARE @json nvarchar(max) = N'
   {
   "result":{
      "banner_image_light":"",
      "country":"USA",
      "parent":"",
      "notes":"",
      "stock_symbol":"",
      "u_op_dev_version":"",
      "u_restriciton":"No",
      "discount":"",
      "sys_id":"7a2c008c1b07ac50a62cea0ce54bcbe8",
      "market_cap":"0",
      "customer":"false"
   },
   "result2":{
      "sys_id":"xxxx008c1b07ac50a62cea0ce54bcbe8"
   }
   }
'

SELECT j.[value] AS sys_id
FROM (VALUES (@json)) a (Complete_JSON_Response)
OUTER APPLY dbo.ParseJson(a.Complete_JSON_Response, 'sys_id') j
结果:

sys_id
--------------------------------
xxxx008c1b07ac50a62cea0ce54bcbe8
7a2c008c1b07ac50a62cea0ce54bcbe8

你可以使用一个函数。这可能会导致一些性能问题,但效果良好

select
'{"result":{"banner_image_light":"","country":"USA","parent":"","notes":"","stock_symbol":"","u_op_dev_version":"","u_restriciton":"No","discount":"","sys_id":"7a2c008c1b07ac50a62cea0ce54bcbe8","market_cap":"0","customer":"false"}}' json
into tmp_json



CREATE FUNCTION dbo.trialFnc(
    @json nvarchar(max),
    @key nvarchar(255)
)
RETURNS nvarchar(255)
AS 
BEGIN
    declare @txt1 nvarchar(max) = right(@json, len(@json) - (charindex(@key, @json)) + 1 - len(@key) - 3)
    declare @txt2 nvarchar(max) = left(@txt1, charindex('"', @txt1) - 1)

    RETURN @txt2
END;   


select
    dbo.trialFnc(json, 'country') country
,   dbo.trialFnc(json, 'sys_id') sys_id
from tmp_json
它将向您返回以下信息:

国家 系统id 美国 7a2c008c1b07ac50a62cea0ce54bcbe8
你可以使用一个函数。这可能会导致一些性能问题,但效果良好

select
'{"result":{"banner_image_light":"","country":"USA","parent":"","notes":"","stock_symbol":"","u_op_dev_version":"","u_restriciton":"No","discount":"","sys_id":"7a2c008c1b07ac50a62cea0ce54bcbe8","market_cap":"0","customer":"false"}}' json
into tmp_json



CREATE FUNCTION dbo.trialFnc(
    @json nvarchar(max),
    @key nvarchar(255)
)
RETURNS nvarchar(255)
AS 
BEGIN
    declare @txt1 nvarchar(max) = right(@json, len(@json) - (charindex(@key, @json)) + 1 - len(@key) - 3)
    declare @txt2 nvarchar(max) = left(@txt1, charindex('"', @txt1) - 1)

    RETURN @txt2
END;   


select
    dbo.trialFnc(json, 'country') country
,   dbo.trialFnc(json, 'sys_id') sys_id
from tmp_json
它将向您返回以下信息:

国家 系统id 美国 7a2c008c1b07ac50a62cea0ce54bcbe8
谢谢@Zhorov,但在这种情况下,JSON值是硬编码的,正如我所说,Complete_JSON_Repsone列中的值已经像日志一样写入,并且每行都是动态的。@VikasJ其他可能的JSON内容是什么?我认为将此内容解析为JSON应该是您的第一个选择。看起来很完美@Zhorov@Zhorov我已经更新了我的第一篇帖子。请检查一下我的确切要求。谢谢。@VikasJ这是一个简单的
更新
更新dbo.log1设置Sys\u Id=JSON\u值(完成JSON\u响应,'$.result.Sys\u Id')
。谢谢@Zhorov,但在这种情况下,JSON值是硬编码的,正如我所说,Complete_JSON_Repsone列中的值已经像日志一样写入,并且每行都是动态的。@VikasJ其他可能的JSON内容是什么?我认为将此内容解析为JSON应该是您的第一个选择。看起来很完美@Zhorov@Zhorov我已经更新了我的第一篇帖子。请检查一下我的确切要求。谢谢。@VikasJ这是一个简单的
更新
更新dbo.log1设置Sys\u Id=JSON\u值(完整的JSON\u响应,$.result.Sys\u Id')
。当你说JSON是动态的,它的动态是什么?钥匙和整体结构是否至少保持不变?你在使用SQL2016+?@Charlieface我已经更新了我的第一篇帖子。请检查一下我的确切要求。谢谢。
JSON\u VALUE
应该可以帮你解决这个问题,不是吗?当你说JSON是动态的时,它的动态是什么?钥匙和整体结构是否至少保持不变?你在使用SQL2016+?@Charlieface我已经更新了我的第一篇帖子。请检查一下我的确切要求。谢谢。
JSON\u VALUE
应该能帮到你,不是吗?