2016-03-08 65 views
3

我需要運行select語句來替換varchar列中的單個字符。該列中的每個字符都將被更改。 A-Z需要更改爲「A」,0-9需要更改爲「0」。我想我明白如何用正則表達式來找到它們,但我不確定替換函數是否可以用來做這件事。例如替換單個字符的模式

ABC123 > AAA000 
Z15X97 > A00A00 

可這TSQL來完成,而無需使用子以時間來改變每個字符一個,或不喜歡replace(<column>, 'B','A')語句(用於數字25字母,8)名單?

+1

你只處理大寫嗎?除了「純拉丁語A-Z」之外還可能會有特殊字符嗎? – Shnugo

+0

在我的情況下,evrything是大寫字母A到Z或0到9,但是你說得很好。 – Roger

回答

2

試試這樣說:

DECLARE @tbl TABLE(TestString VARCHAR(100)); 
INSERT INTO @tbl VALUES('ABC123'),('Z15X97'); 

WITH RunningNummbers AS 
(
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Inx 
    FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS x(y) 
    CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS a(b) 
    CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS c(d) --1000 running numbers 
) 
SELECT TestString 
     ,( 
     SELECT CASE WHEN SUBSTRING(tbl.TestString,Inx,1) BETWEEN 'A' AND 'Z' THEN 'A' 
        ELSE CASE WHEN SUBSTRING(tbl.TestString,Inx,1) BETWEEN '0' AND '9' THEN '0' ELSE SUBSTRING(tbl.TestString,Inx,1) END 
       END 
     FROM RunningNummbers 
     WHERE Inx<=LEN(tbl.TestString) 
     FOR XML PATH('') 
     ) AS Replaced 
FROM @tbl AS tbl 

結果

ABC123 AAA000 
Z15X97 A00A00 
3

這裏有一種方法,它的效率低,希望這只是一次性的

CREATE TABLE tbl (id INT, txt VARCHAR(255)); 
INSERT tbl VALUES (1, 'ABC123'), (2, 'Z15X97'), (3, 'AZ09'), (4, 'ABCXYZ') 

;WITH T (id, txt, pos) AS (
    SELECT id, CAST(txt AS VARCHAR(255)), 0 FROM tbl 
    UNION ALL 
    SELECT id, 
     CAST(STUFF(txt, pos + 1, 1, CASE WHEN SUBSTRING(txt, pos + 1, 1) LIKE '[A-Z]' THEN 'A' ELSE '0' END) AS VARCHAR(255)), 
     pos + 1 
    FROM T WHERE pos < LEN(txt) 
) 
SELECT id, txt 
FROM T WHERE pos = LEN(txt) 

id txt 
4 0000000000AAAAAA 
3 AA00 
2 A00A00 
1 AAA000 
+0

遞歸CTE,不錯的做法,+1從我身邊 – Shnugo

+0

謝謝你們倆。這兩個工作。但是,我可能不得不求助於一個簡單的mycolumn = replace(mycolumn,'B','A'),並將它分解爲多個set語句,因爲我有540m行。 :/ – Roger