首先先介紹 Oracle 裏面的 TRANSLATE 的用法
先是語法:
Oracle
語法:TRANSLATE(char, from, to)
用法:返回將出現在from中的每個字符替換爲to中的相應字符以後的字符串。
若from比to字符串長,那麼在from中比to中多出的字符將會被刪除。
三個參數中有一個是空,返回值也將是空值。
SQL> SELECT TRANSLATE('2KRW229',
2 '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
3 '9999999999XXXXXXXXXXXXXXXXXXXXXXXXXX') AS "License"
4 FROM DUAL;
License
-------
9XXX999
某些情況下,要從一個字符串中,提取數字信息的,可以使用:
SQL> SELECT TRANSLATE('2KRW229',
2 '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', '0123456789')
3 AS "Translate example"
4 FROM DUAL;
Tran
----
2229
更簡單的寫法,就是第一個字母是不存在的字母,後面全部是需要被刪除的。
SQL> SELECT TRANSLATE('2KRW229',
2 '#ABCDEFGHIJKLMNOPQRSTUVWXYZ', '#')
3 AS "Translate example"
4 FROM DUAL;
Tran
----
2229
還有一種寫法,就是把需要保留的都標記下來,其他的都替換爲空白
SQL> SELECT TRANSLATE('2KRW229',
2 '1234567890' || '2KRW229', '1234567890')
3 AS "Translate example"
4 FROM DUAL;
Tran
----
2229
下面是 SQL Server 下面的實現:
CREATE FUNCTION TRANSLATE(
@string VARCHAR(MAX),
@from_str VARCHAR(MAX),
@to_str VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
-- 返回將(所有出現的)from_str中的每個字符替換爲to_str中的相應字符以後的string。
-- TRANSLATE 是 REPLACE 所提供的功能的一個超集。
-- 如果 from_str 比 to_str 長,那麼在 from_str 中而不在 to_str 中的額外字符將從 string 中被刪除,因爲它們沒有相應的替換字符。
-- to_str 不能爲空。
-- Oracle 將空字符串解釋爲 NULL,並且如果TRANSLATE 中的任何參數爲NULL,那麼結果也是 NULL。
IF @string IS NULL OR @from_str IS NULL OR @to_str IS NULL
BEGIN
RETURN NULL;
END;
-- 源長度 與 目標長度
DECLARE @FromLen INT, @ToLen INT;
SET @FromLen = LEN(@from_str);
SET @ToLen = LEN(@to_str);
-- 準備用於返回的數值.
DECLARE @resultVal VARCHAR(MAX);
SET @resultVal = @string;
-- 用於存儲 本次需要替換的字符信息.
DECLARE @thisTimeReplace CHAR(1);
-- 從後向前依次替換.
WHILE @FromLen > 0
BEGIN
-- 取得本次即將要替換的字符.
SET @thisTimeReplace = SUBSTRING(@from_str, @FromLen, 1);
IF CHARINDEX(@thisTimeReplace, @from_str) < @FromLen
BEGIN
-- 假如當前這個要替換的字符,在前面還有,那麼這裏就不替換了
-- 原因,爲了支持
-- SELECT TRANSLATE('2KRW229', '1234567890' || '2KRW229', '1234567890')
-- 這樣的效果.
-- 向前處理上一個.
SET @FromLen = @FromLen - 1;
CONTINUE;
END
IF @FromLen > @ToLen
BEGIN
-- from_str 比 to_str 長,那麼在 from_str 中而不在 to_str 中的額外字符將從 string 中被刪除,因爲它們沒有相應的替換字符。
SET @resultVal = REPLACE(@resultVal, SUBSTRING(@from_str, @FromLen, 1), '');
END
ELSE
BEGIN
-- from_str中的每個字符替換爲to_str中的相應字符以後的string
SET @resultVal = REPLACE(@resultVal, @thisTimeReplace, SUBSTRING(@to_str, @FromLen, 1));
END;
-- 處理完當前字符後,向前處理上一個.
SET @FromLen = @FromLen - 1;
END;
-- 依次處理完畢後,返回結果.
RETURN @resultVal;
END
go
測試結果:
1> SELECT dbo.TRANSLATE('2KRW229',
2> '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
3> '9999999999XXXXXXXXXXXXXXXXXXXXXXXXXX') AS "License"
4> go
License
----------------
9XXX999
(1行受影響)
1>
2> SELECT dbo.TRANSLATE('2KRW229',
3> '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', '0123456789')
4> AS "Translate example"
5> go
Translate example
----------------
2229
(1行受影響)
1>
2>
3> SELECT dbo.TRANSLATE('2KRW229',
4> '#ABCDEFGHIJKLMNOPQRSTUVWXYZ', '#')
5> AS "Translate example"
6> go
Translate example
----------------
2229
(1行受影響)
1>
2> SELECT dbo.TRANSLATE('2KRW229',
3> '1234567890' + '2KRW229', '1234567890')
4> AS "Translate example"
5> go
Translate example
----------------
2229
(1 行受影響)