【问题标题】:Extracting a single line value from a multi-line string T-SQL从多行字符串 T-SQL 中提取单行值
【发布时间】:2022-01-01 21:17:46
【问题描述】:

我有一个包含以下格式的字符串的多行 nvarchar:

@String =  
'ReportHeaderColor{R:98, B:183, G:178} 
ReportHeaderFontColor{R:255, B:255, G:255} 
ReportBodyHeaderColor{R:98, B:183, G:178} 
ReportBodyFontColor{R:255, B:255, G:255}'

我希望能够使用 nvarchar 值 @Attribute = 'ReportHeaderFontColor' 并仅从 @String 中提取包含 @Attribute 值的行

【问题讨论】:

  • 提问时,您需要提供minimal reproducible example: (1) DDL 和样本数据填充,即 CREATE 表和 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试在 T-SQL 中实现它。 (3) 期望的输出,基于上述#1 中的样本数据。 (4) 您的 SQL Server 版本 (SELECT @@version;)。
  • 您可能应该考虑使用适当的格式,例如 JSON 或 XML,其中有内置的解析方法

标签: sql-server


【解决方案1】:

只是另一种方法

示例

Declare @String varchar(max)=  
'ReportHeaderColor{R:98, B:183, G:178}
ReportHeaderFontColor{R:255, B:255, G:255}
ReportBodyHeaderColor{R:98, B:183, G:178}
ReportBodyFontColor{R:255, B:255, G:255}'

Declare @Find varchar(150) = 'ReportHeaderFontColor'

Select value
 From  string_split(replace(replace(@String,'}','}|'),char(13)+char(10),''),'|')
 where charindex(@Find,value)>0

结果

value
ReportHeaderFontColor{R:255, B:255, G:255}

【讨论】:

    【解决方案2】:

    下面如何使用apply 查找要查找的开始/结束位置并使用substring 提取:

    declare @Attribute nvarchar(100)= 'ReportHeaderFontColor',
    
    @String nvarchar(max) =
    'ReportHeaderColor{R:98, B:183, G:178}
    ReportHeaderFontColor{R:255, B:255, G:255}
    ReportBodyHeaderColor{R:98, B:183, G:178}
    ReportBodyFontColor{R:255, B:255, G:255}';
    
    with s as (select @string as string)
    select Substring(string,b.pos,e.pos-b.pos+1)
    from s
    cross apply(values(charindex(Concat('ReportBodyHeaderColor','{'), string)))b(pos)
    cross apply(values(CharIndex('}', string, b.pos)))e(pos)
    where b.pos>0;
    

    结果:

    ReportHeaderFontColor{R:255, B:255, G:255}

    【讨论】:

      【解决方案3】:

      可以通过换行符char(10)分割字符串,然后去掉回车符char(13),如下:

      Declare @Attribute nVarChar(50)= 'ReportHeaderFontColor'
      Declare @String nVarChar(max) =  
      'ReportHeaderColor{R:98, B:183, G:178} 
      ReportHeaderFontColor{R:255, B:255, G:255} 
      ReportBodyHeaderColor{R:98, B:183, G:178} 
      ReportBodyFontColor{R:255, B:255, G:255}'
      
      Select Replace(Value,Char(13),'') As Result
      From String_Split(@String,Char(10))
      Where Value Like Concat('%',@Attribute,'%')
      
      Result
      ReportHeaderFontColor{R:255, B:255, G:255}

      【讨论】:

        【解决方案4】:

        感谢您的所有建议,很遗憾我无法使用 string_split,因为我们的一些客户使用的系统早于 SQL 2016。

        玩了一会儿后,我想出了以下解决方案,我将其放在 UDF 中并添加了一些错误检查:

        declare @header_row nvarchar(max) = 
        'ReportHeaderColor{R:98, B:183, G:178} 
        ReportHeaderFontColor{R:255, B:255, G:255} 
        ReportBodyHeaderColor{R:98, B:183, G:178} 
        ReportBodyFontColor{R:255, B:255, G:255}'
        
        declare @Attribute nvarchar(max) = 'ReportHeaderFontColor'
        
        declare @String nvarchar(255)
        
        -- check that the header row is not empty and actually contains the attribute
        if (len(@header_row) = 0 or @header_row not like '%' + @Attribute + '%')
        begin
            select @String = null
        end
        else begin
        
            select @String = 
                replace(replace(replace(
                    left(
                        substring(@header_row,charindex(@Attribute + '{', @header_row) + len(@Attribute + '{'), 999),charindex('}',
                        substring(@header_row,charindex(@Attribute + '{', @header_row) + len(@Attribute + '{'), 999))-1)
                ,'R:',''),'G:',''),'B:','')
        
            -- if the string is not in the correct format(3 integers separated by a comma) set @String to null
            if (select count(1)
                from dbo.fn_ListToTable(@String,',') x
                where ISNUMERIC(x.List) = 1 and x.List <= 255) <> 3
            begin
                set @String = null
            end
        
        end
        

        【讨论】:

        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-06-18
        • 2014-12-13
        • 1970-01-01
        • 2013-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多