本文彙整 8 大字串處理自訂函數,涵蓋判斷/提取中文、提取數字、提取英文、過濾重複字元 (兩種演算法)、依分隔符分割取第 N 段,提供完整建立腳本可直接部署使用。為 fun_getCN 中文判斷函數。
| 函數名稱 | 功能 | 回傳型別 |
|---|---|---|
| fun_getCN | 判斷含中文並提取所有中文字元 | NVARCHAR(4000) |
| GET_NUMBER2 | 提取字串中所有數字 (0-9) | VARCHAR(100) |
| GET_STR | 提取字串中所有英文字母 (a-z) | VARCHAR(100) |
| CHINA_STR | 提取中文字元 (吖-座 範圍法) | VARCHAR(100) |
| DISTINCT_STR | 依分隔符去重 (保留首次出現順序) | VARCHAR(100) |
| DISTINCT_STR2 | 字元級去重 (不保證順序) | VARCHAR(100) |
| SPLIT_STR | 依分隔符分割並取第 N 段 | VARCHAR(100) |
-- 1. 判斷/提取中文
CREATE FUNCTION dbo.fun_getCN(@str NVARCHAR(4000))
RETURNS NVARCHAR(4000) AS BEGIN
DECLARE @word NCHAR(1), @CN NVARCHAR(4000) = '';
WHILE LEN(@str) > 0 BEGIN
SET @word = LEFT(@str, 1);
IF UNICODE(@word) BETWEEN 19968 AND 19968 + 20901
SET @CN = @CN + @word;
SET @str = RIGHT(@str, LEN(@str) - 1);
END
RETURN @CN;
END
GO
-- 2. 提取數字
CREATE FUNCTION dbo.GET_NUMBER2(@S VARCHAR(100))
RETURNS VARCHAR(100) AS BEGIN
WHILE PATINDEX('%[^0-9]%', @S) > 0
SET @S = STUFF(@S, PATINDEX('%[^0-9]%', @S), 1, '');
RETURN @S;
END
GO
-- 3. 提取英文
CREATE FUNCTION dbo.GET_STR(@S VARCHAR(100))
RETURNS VARCHAR(100) AS BEGIN
WHILE PATINDEX('%[^a-z]%', @S) > 0
SET @S = STUFF(@S, PATINDEX('%[^a-z]%', @S), 1, '');
RETURN @S;
END
GO
-- 4. 提取中文 (範圍法)
CREATE FUNCTION dbo.CHINA_STR(@S NVARCHAR(100))
RETURNS VARCHAR(100) AS BEGIN
WHILE PATINDEX('%[^吖-座]%', @S) > 0
SET @S = STUFF(@S, PATINDEX('%[^吖-座]%', @S), 1, N'');
RETURN @S;
END
GO
-- 5. 過濾重複字元 (分隔符法,保留順序)
CREATE FUNCTION dbo.DISTINCT_STR(@S NVARCHAR(100), @SPLIT VARCHAR(50))
RETURNS VARCHAR(100) AS BEGIN
IF @S IS NULL RETURN NULL;
DECLARE @NEW VARCHAR(50) = '', @INDEX INT, @TEMP VARCHAR(50);
IF LEFT(@S, 1) <> @SPLIT SET @S = @SPLIT + @S;
IF RIGHT(@S, 1) <> @SPLIT SET @S = @S + @SPLIT;
WHILE CHARINDEX(@SPLIT, @S) > 0 AND LEN(@S) <> 1 BEGIN
SET @INDEX = CHARINDEX(@SPLIT, @S);
SET @TEMP = LEFT(@S, CHARINDEX(@SPLIT, @S, @INDEX + LEN(@SPLIT)));
IF @NEW = '' SET @NEW = @TEMP;
ELSE SET @NEW = @NEW + REPLACE(@TEMP, @SPLIT, '') + @SPLIT;
WHILE CHARINDEX(@TEMP, @S) > 0
SET @S = STUFF(@S, CHARINDEX(@TEMP, @S) + LEN(@SPLIT),
CHARINDEX(@SPLIT, @S, CHARINDEX(@TEMP, @S) + LEN(@SPLIT)) - CHARINDEX(@TEMP, @S), '');
END
RETURN RIGHT(LEFT(@NEW, LEN(@NEW) - 1), LEN(LEFT(@NEW, LEN(@NEW) - 1)) - 1);
END
GO
-- 6. 過濾重複字元 (字元法,不保留順序)
CREATE FUNCTION dbo.DISTINCT_STR2(@S VARCHAR(8000))
RETURNS VARCHAR(100) AS BEGIN
IF @S IS NULL RETURN NULL;
DECLARE @NEW VARCHAR(50) = '';
WHILE LEN(@S) > 0 BEGIN
SET @NEW = @NEW + LEFT(@S, 1);
SET @S = REPLACE(@S, LEFT(@S, 1), '');
END
RETURN @NEW;
END
GO
-- 7. 分割字串取第 N 段
CREATE FUNCTION dbo.SPLIT_STR(
@S VARCHAR(8000), @INDEX INT, @SPLIT VARCHAR(10)
)
RETURNS VARCHAR(100) AS BEGIN
IF @S IS NULL RETURN NULL;
DECLARE @SPLITLEN INT = LEN(@SPLIT + 'A') - 2;
WHILE @INDEX > 1 AND CHARINDEX(@SPLIT, @S + @SPLIT) > 0
SELECT @INDEX = @INDEX - 1,
@S = STUFF(@S, 1, CHARINDEX(@SPLIT, @S + @SPLIT) + @SPLITLEN, '');
RETURN ISNULL(LEFT(@S, CHARINDEX(@SPLIT, @S + @SPLIT) - 1), '');
END
GO
-- 中文提取
SELECT dbo.fun_getCN(N'ASDKG論壇KDL'); -- 論壇
SELECT dbo.fun_getCN(N'ASDKDL'); -- (空字串)
-- 數字提取
PRINT dbo.GET_NUMBER2(N'呵呵ABC123ABC'); -- 123
-- 英文提取
PRINT dbo.GET_STR(N'呵呵ABC123ABC'); -- ABCABC
-- 中文提取 (範圍法)
PRINT dbo.CHINA_STR(N'呵呵ABC123ABC'); -- 呵呵
-- 去重 (分隔符)
PRINT dbo.DISTINCT_STR(N'A,A,B,C,C,B,C,', N','); -- A,B,C
-- 去重 (字元)
SELECT dbo.DISTINCT_STR2('AABCCD'); -- ABCD
-- 分割
PRINT dbo.SPLIT_STR('AA|BB|CC', 2, '|'); -- BB
WHILE 迴圈逐字元處理,不適合大量資料高頻呼叫 (如百萬列查詢中的 SELECT 列表)。STRING_SPLIT、TRANSLATE、CONCAT_WS 等。ufn_) 避免衝突。這組函數庫適用於中小型資料清洗、ETL 轉換、報表資料整理等離線/低頻場景,部署即用,無相依性。