Oracle 裏面的 TRANSLATE 以及 SQL Server 下的實現

首先先介紹 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 行受影響)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章