SQL Server在冒号之前和分号后替换所有值

时间:2012-03-13 12:56:32

标签: sql sql-server tsql substring

我有一栏说Test

测试的值包括asp:test;abcaasps:tesst;abcsaasssp:tsest;assbca

我只对;之前和:之后的文字感兴趣,所以我的结果应该像

test, tesst, tsest

我只是想用SQL查询来做,而不是用代码编程。

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

感谢任何帮助。

修改

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

7 个答案:

答案 0 :(得分:5)

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)

答案 1 :(得分:4)

对于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

答案 2 :(得分:3)

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

答案 3 :(得分:3)

以下是使用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

答案 4 :(得分:2)

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

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

答案 5 :(得分:1)

那样的东西?

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

答案 6 :(得分:0)

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

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

根据您的数据大小,服务器负载以及进行此查询的频率,尝试其他内容可能更有意义。例如,添加另一列并填充此数据。