【问题标题】:SQL Parsing a StringSQL 解析字符串
【发布时间】:2021-03-02 04:49:59
【问题描述】:

谁能告诉我哪里出错了,我似乎无法提取第四个单词 CCC,尝试了所有方法,不想将其放入表中,只是在选择中返回子字符串?

DECLARE  @ProductCode VARCHAR(256) 

SET @ProductCode = 'CCCC-DDDDDDD-AAA-CCC-BBBBB' 

SELECT LEFT(@ProductCode,CHARINDEX('-',@ProductCode) - 1) AS CHAR1, 

    SUBSTRING(@ProductCode,CHARINDEX('-',@ProductCode) + 1, 
                CHARINDEX('-',@ProductCode,CHARINDEX('-', @ProductCode) + 1) - (CHARINDEX('-',@ProductCode) + 1)) AS CHAR2, 
        
    SUBSTRING(@ProductCode,CHARINDEX('-',@ProductCode,CHARINDEX('-',@ProductCode) + 1) + 1, 
                DATALENGTH(@ProductCode) - CHARINDEX('-', @ProductCode,CHARINDEX('-',@ProductCode) + 1) - CHARINDEX('-',REVERSE(@ProductCode))) AS CHAR3, 

    SUBSTRING(@ProductCode,CHARINDEX('-',@ProductCode,CHARINDEX('-',@ProductCode), CHARINDEX('-',@ProductCode) + 1)) + 1, 
DATALENGTH(@ProductCode) - CHARINDEX('-', @ProductCode,CHARINDEX('-',@ProductCode), CHARINDEX('-',@ProductCode) + 1) - CHARINDEX('-',REVERSE(@ProductCode))) AS CHAR4,
       RIGHT(@ProductCode,CHARINDEX('-',REVERSE(@ProductCode)) - 1) AS LASTCHAR

GO

非常感谢

【问题讨论】:

  • 帮自己一个忙,找到一个提供序数位置的字符串拆分函数。在某些时候,MS 会改进内置功能来做同样的事情。添加 TRIM 只用了 17 年。
  • 而且使用datalength在逻辑上是不正确的。如果您需要处理 nvarchar 字符串,您的代码将无法正常工作。
  • 您要提取的字符串是否总是在同一个位置?

标签: sql sql-server substring charindex


【解决方案1】:

也许它会更简单:

select s.value
from string_split(@productcode, '-') s
where @productcode like '%-%-%-' + s.value + '-%' and
      @productcode not like '%-%-%-%-' + s.value + '-%' and

  

【讨论】:

  • STRING_SPLIT 要求兼容级别至少为 130
  • @JohnJoseph 。 . .或者换一种说法,它从 2016-06-01 的当前版本开始可用——现在大约四年半了。
  • 因此,假设您想提供帮助而不是刻薄...如果 OP 具​​有 SQL Server 2014 或更早版本,则无法将兼容性更改为 130 或更高版本。跨度>
【解决方案2】:

以下是完成任务的一种方法:

select substring(@productcode,charindex('-',@ProductCode,charindex('-',@ProductCode,charindex('-',@ProductCode,charindex('-',@ProductCode))+1)+1)+1,datalength(@productcode)-charindex('-',@ProductCode,charindex('-',@ProductCode,charindex('-',@ProductCode,charindex('-',@ProductCode,charindex('-',@ProductCode))+1)+1)+1)-2);

使用多种方法提取 细绳。您不需要 REVERSE FUNTION 来获取字符串的结尾 ,您可以继续使用 charindex 提取“-”的位置 函数并从字符串的总长度中减去它。

【讨论】:

    【解决方案3】:
    --get 3rd and 4th words (the same way as for the 2nd word)
    
    DECLARE  @ProductCode VARCHAR(256) 
    
    SET @ProductCode = 'CC12CC-DDD34DD-A56A-C78C-BB910BB' 
    
    SELECT LEFT(@ProductCode,CHARINDEX('-',@ProductCode) - 1) AS CHAR1, 
    
    SUBSTRING(@ProductCode,CHARINDEX('-',@ProductCode) + 1, 
                    CHARINDEX('-',@ProductCode,CHARINDEX('-', @ProductCode) + 1) - (CHARINDEX('-',@ProductCode) + 1)) AS CHAR2, 
            
    SUBSTRING(
    @ProductCode,
    --.. from position of 2nd "-" plus one 
    CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) + 1) + 1,
    --as many chars as there are between 2nd&3rd "-"
    CHARINDEX('-', @ProductCode, CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) + 1) + 1) -1 --3rd "-" minus 1
    - --minus position 2nd "-"
    CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) + 1) --= chars between 2nd and 3rd "-"
    ) as xCHAR3,                 
                    
    SUBSTRING(
    @ProductCode,
    --.. from position of 3rd "-" plus one 
    CHARINDEX('-', @ProductCode, CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) + 1) + 1) + 1,
    --get as many chars as there are between 3rd&4th "-"
    CHARINDEX('-', @ProductCode, CHARINDEX('-', @ProductCode, CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) + 1) + 1)+1) -1 --4th "-" minus 1
    - --minus position 3rd "-"
    CHARINDEX('-', @ProductCode, CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) + 1) + 1) --= chars between 3rd and 4th "-"
    ) as xCHAR4, 
    
    RIGHT(@ProductCode,CHARINDEX('-',REVERSE(@ProductCode)) - 1) AS LASTCHAR
    
    GO
    
    --... or ...
    DECLARE  @ProductCode VARCHAR(256);
    
    SET @ProductCode = 'CC12CC-DDD34DD-A56A-C78C-BB910BB'; 
    
    select 
        p.value('comment()[1]', 'varchar(100)') as char1,
        p.value('comment()[2]', 'varchar(100)') as char2,
        p.value('comment()[3]', 'varchar(100)') as char3,
        p.value('comment()[4]', 'varchar(100)') as char4,
        p.value('comment()[5]', 'varchar(100)') as char5                
    from
    (
    --splitting on '-', xml comment is rather safe
    select cast('<!--'+replace(@ProductCode, '-', '--><!--')+'-->' as xml) p
    ) as t;
    

    【讨论】:

      【解决方案4】:

      这种方法的优点是可读性强,但是很丑……

      DECLARE  @ProductCode VARCHAR(256) 
      
      SET @ProductCode = 'CCCC-DDDDDDD-AAA-CCC-BBBBB' 
      
      select @ProductCode = substring(@ProductCode,charindex('-',@ProductCode)+1,99)
      select @ProductCode = substring(@ProductCode,charindex('-',@ProductCode)+1,99)
      select @ProductCode = substring(@ProductCode,charindex('-',@ProductCode)+1,99)
      select @ProductCode = left(@ProductCode,charindex('-',@ProductCode)-1)
      
      select @ProductCode
      

      【讨论】:

        【解决方案5】:

        这种方法的优点是灵活,您可以更改搜索的第 N 个单词...

        declare @ProductCode varchar(256) 
        declare @WordSought int = 4
        declare @Cntr int = 0
        
        set @ProductCode = 'CCCC-DDDDDDD-AAA-CCC-BBBBB' 
        
        while @cntr < @WordSought - 1
        begin
            select @ProductCode = substring(@ProductCode,charindex('-',@ProductCode)+1,99)
            set @cntr = @cntr + 1
        end
        
        select left(@ProductCode,charindex('-',@ProductCode + '-') - 1)
        

        【讨论】:

          猜你喜欢
          • 2010-10-13
          • 1970-01-01
          • 2021-02-18
          • 2013-05-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多