【问题标题】:SQL Server replace all values before a colon and after a semi-colonSQL Server 替换冒号前和分号后的所有值
【发布时间】:2012-03-29 20:56:53
【问题描述】:

我有一个专栏说Test

测试有asp:test;abcaasps:tesst;abcsaasssp:tsest;assbca等值

我只对; 之前和: 之后的文本感兴趣,所以我的结果应该是这样的

test, tesst, tsest

我只想通过 SQL 查询而不是在代码中编程。

SQL Server 是否支持某种正则表达式?

感谢任何帮助。

编辑

重要部分是某些值可能没有;: 所以我的查询也不应该失败可能是对此的某种检查

【问题讨论】:

  • 如果数据不包含冒号和/或分号,您期望得到什么结果?
  • 我强烈建议不要在数据库中做任何事情,除了 crud。数据库是用于存储数据而不是用于处理!在应用程序端处理它。如果asptestabca 具有某些含义,则将它们分成三列。规范化它!!!
  • @GMastros 很抱歉回复晚了,如果没有冒号和分号,我想得到完整的字符串

标签: sql sql-server tsql substring


【解决方案1】:
declare @T table
(
  Col varchar(20)
)

insert into @T values
('asp:test;abca'), 
('asps:tesst;abcsa'), 
('asssp:tsest;assbca'),
('asssp:tsestassbca'),
('asssptsest;assbca'),
('asssptsestassbca'),
(':;')

select  left(T2.Col, charindex(';', T2.Col+';')-1) 
from @T as T1
  cross apply (select stuff(T1.Col, 1, charindex(':', T1.Col), '')) as T2(Col)

【讨论】:

  • 哇!这看起来像是黑魔法和巫术的结合——但它确实有效! :-)
  • @MikaelEriksson 即使工作了 10 年,你还是个天才,我无法编写这样的查询。你是 gr88888888888888。
【解决方案2】:

对于sql引擎支持的字符串函数:substring、charindex:

SUBSTRING(s, CHARINDEX(':', s) + 1, CHARINDEX(';', s) - CHARINDEX(':', s) - 1)

带有错误处理的完整代码

case 
  when CHARINDEX(':', s) > 0 and CHARINDEX(';', s) > 0 
    then SUBSTRING(s, CHARINDEX(':', s) + 1, CHARINDEX(';', s) - CHARINDEX(':', s) - 1) 
 else null
end

【讨论】:

  • 如果数据不包含冒号或分号,此代码将失败。
  • 查看我的回复以获得更简单的处理方法。
【解决方案3】:

T-SQL 确实有 PATINDEX 来进行模式匹配,但不支持强大的正则表达式 API。但是,如果您有 SQL Server 2005 及更高版本,则可以创建一个CLR user-defined function。但是,您可以通过使用 PATINDEX/CHARINDEX 和 SUBSTRING 的常规用户定义函数来完成您想要的。

【讨论】:

    【解决方案4】:

    这是一个使用 CharIndex 的示例,它可以执行您想要的操作,并且如果缺少冒号或分号也不会失败。

    Declare @Temp Table(Test VarChar(50))
    
    Insert Into @Temp Values('asp:test;abca')
    Insert Into @Temp Values('asps:tesst;abcsa')
    Insert Into @Temp Values('asssp:tsest;assbca')
    Insert Into @Temp Values('Hello World')
    Insert Into @Temp Values('Hello World:')
    Insert Into @Temp Values('Hello World;')
    
    Select  SubString(Test, CharIndex(':', Test) + 1, CharIndex(';', Test + ':;') - CharIndex(':', Test) - 1)
    From    @Temp
    

    【讨论】:

      【解决方案5】:

      您可以编写这样的函数来处理所有情况 - 有一个冒号 (:) 和/或有一个分号 (;) - 或者根本没有。无论如何,这将返回您正在寻找的字符串片段:

      ALTER FUNCTION dbo.ExtractString (@InputString VARCHAR(500))
      RETURNS VARCHAR(500)
      AS BEGIN
          DECLARE @Result VARCHAR(500)
      
          DECLARE @ColonPos INT, @SemicolonPos INT
      
          SET @ColonPos = CHARINDEX(':', @InputString)
          SET @SemicolonPos = CHARINDEX(';', @InputString)
      
          IF @ColonPos > 0 
              IF @SemicolonPos > 0
                  SET @Result = SUBSTRING(@InputString, @ColonPos + 1, @SemicolonPos - 1 - @ColonPos)
              ELSE    
                  SET @Result = SUBSTRING(@InputString, @ColonPos + 1, 500)
          ELSE
              IF @SemicolonPos > 0
                  SET @Result = SUBSTRING(@InputString, 1, @SemicolonPos - 1)
              ELSE    
                  SET @Result = @InputString
      
          RETURN @Result
      END
      

      既然只是一个字符串操作函数,在性能上也应该不会太差。

      如果您针对各种输入运行它:

      SELECT 
          dbo.ExtractString('asp:test;abca'),
          dbo.ExtractString('asps:tesst;abcsa'), 
          dbo.ExtractString('asssp:tsest;assbca'),
          dbo.ExtractString('test'),
          dbo.ExtractString('a:test'),
          dbo.ExtractString('atest;something')
      

      你会得到这些结果:

      test   tesst   tsest   test   test   atest
      

      【讨论】:

        【解决方案6】:

        类似的东西?

        DECLARE @n TABLE (test VARCHAR(100))
        
        INSERT @n (test)
        VALUES  ('asp:test;abca'), ('asps:tesst;abcsa'), ('asssp:tsest;assbca')
        
        INSERT @n (test)
        VALUES  ('asptest;abca'), ('asps:tesstabcsa'), ('asssptsestassbca')
        
        
        SELECT SUBSTRING(test, CHARINDEX(':', test) + 1, ISNULL(NULLIF(CHARINDEX(';', test), 0), LEN(test) + 1) - CHARINDEX(':', test) - 1)
        FROM @n
        

        【讨论】:

        • 感谢您的回答,但请阅读我更新的问题,某些值可能没有:和/或;所以在这种情况下查询不能失败
        • 欢迎使用 StackOverflow:如果您发布代码、XML 或数据示例,在文本编辑器中突出显示这些行并单击“代码示例”按钮 ({ } ) 在编辑器工具栏上很好地格式化和语法突出显示它!
        • 感谢您的建议,我会的。只是还不熟悉编辑器工具。
        【解决方案7】:

        您可以按照其他人的建议使用子字符串或 patindex(我个人的偏好是使用 UDF)。

        但是,您需要注意,将这些技术用作 WHERE 子句的一部分可能会导致表扫描。

        根据您的数据大小、服务器负载和进行此查询的频率,尝试其他方法可能更有意义。例如,添加另一个填充了此数据的列。

        【讨论】:

          猜你喜欢
          • 2014-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-12
          • 2020-12-28
          • 1970-01-01
          • 2016-07-31
          • 1970-01-01
          相关资源
          最近更新 更多