2012-03-13 77 views
1

我有一列說TestSQL Server替換冒號前面和分號後的所有值

考得值像asp:test;abcaasps:tesst;abcsaasssp:tsest;assbca

我只對文本之前感興趣的一個;:後,所以我的結果應該是像

test, tesst, tsest 

我只想做它帶有一個SQL查詢,而不是以編程方式在代碼中。

SQL Server是否支持某種正則表達式?

任何幫助表示讚賞。

編輯

重要的是,一些值可能沒有;:所以我的查詢應該也不會失敗可能是某種檢查此

+0

如果數據不包含冒號和/或分號,您會期望什麼結果? – 2012-03-13 13:13:35

+0

我強烈建議不要在數據庫中做任何事情,除了crud。數據庫用於**存儲**數據不用於**處理**!在應用程序端進行處理。如果'asp'和'test'和'abca'帶有一些含義,那麼將它們分成三列。規範化它! – Oybek 2012-03-13 13:15:44

+0

@Gasastros我真的很抱歉,如果沒有冒號和分號,我想得到完整的字符串 – Moons 2012-03-14 04:10:02

回答

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) 
+2

哇!這看起來像黑魔法和伏都教結合 - 但它的作品! :-) – 2012-03-13 13:24:07

+0

@MikaelEriksson即使在接下來的10年工作之後,你仍然是天才,我無法寫出這樣的疑問。你是gr88888888888888。 – Moons 2012-03-14 05:49:32

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 
+0

感謝您的回答,但請閱讀我更新的問題,某些值可能沒有:和/或;所以在這種情況下,查詢必須不會失敗 – Moons 2012-03-13 13:05:37

+0

歡迎來到StackOverflow:如果您發佈代碼,XML或數據樣本,請**在文本編輯器中突出顯示這些行,然後單擊「代碼示例」按鈕(「{}' )在編輯器工具欄上以良好的格式和語法突出顯示它! – 2012-03-13 13:17:36

+0

謝謝你的建議,我會的。只是還不熟悉編輯工具。 – 2012-03-13 13:19:40

3

T-SQL確實有PATINDEX模式匹配,但不支持強大的正則表達式API。但是,如果您擁有SQL Server 2005及更高版本,則可以創建CLR user-defined function。但是,使用PATINDEX/CHARINDEX和SUBSTRING,您可以使用常規的用戶定義函數完成所需的工作。

4

對於SQL引擎支持的字符串函數:字符串,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 
+0

+1僅使用SUBSTRING一次。太好了! – 2012-03-13 13:13:35

+1

如果數據不包含冒號或分號,則此代碼將失敗。 – 2012-03-13 13:16:04

+0

查看當前的變體 – 2012-03-13 13:27:16

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 
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 
0

您可以使用一個子或PATINDEX由他人(我的個人偏好的建議會用於UDF)。

但是,您需要知道,將這些技術用作WHERE子句的一部分可能會導致表掃描。

根據您的數據大小,服務器負載和進行查詢的頻率,嘗試其他方法可能更有意義。例如,添加填充此數據的另一列。