函數定義
CREATE FUNCTION dbo.NWGetPYFirst(@str VARCHAR(500))
RETURNS VARCHAR(500)
AS
BEGIN
DECLARE @strlen INT = LEN(@str),
@return VARCHAR(500) = '',
@i INT = 0,
@ch NCHAR(1),
@py CHAR(1);
-- 拼音區間對照表(依 GB2312 區位碼排序)
DECLARE @pyTable TABLE (
chn NCHAR(1) COLLATE Chinese_PRC_CS_AS NOT NULL PRIMARY KEY,
py CHAR(1) COLLATE Chinese_PRC_CS_AS NOT NULL
);
INSERT INTO @pyTable VALUES
(N'吖','A'),(N'八','B'),(N'嚓','C'),(N'咑','D'),(N'妸','E'),(N'發','F'),
(N'旮','G'),(N'铪','H'),(N'丌','I'),(N'咔','K'),(N'垃','L'),(N'嘸','M'),
(N'拏','N'),(N'噢','O'),(N'妑','P'),(N'七','Q'),(N'呥','R'),(N'仨','S'),
(N'他','T'),(N'屲','U'),(N'夕','X'),(N'丫','Y'),(N'帀','Z');
WHILE @i < @strlen
BEGIN
SET @i += 1;
SET @ch = SUBSTRING(@str, @i, 1);
-- 非 ASCII 視為漢字
IF UNICODE(@ch) > 127
BEGIN
SELECT TOP 1 @py = py
FROM @pyTable
WHERE chn <= @ch
ORDER BY chn DESC;
SET @return += ISNULL(@py, @ch);
END
ELSE
SET @return += @ch; -- 英數符號保留原字
END
RETURN @return;
END
使用範例
SELECT dbo.NWGetPYFirst(N'夢想國度') -- MXJD
SELECT dbo.NWGetPYFirst(N'noctwolf分享源碼') -- noctwolfFXDM
SELECT dbo.NWGetPYFirst(N'') -- (空字串)
原理解析
- 利用
Chinese_PRC_CS_AS 排序規則,漢字按拼音順序編碼。
- 建立「每個聲母起始漢字」對照表,查找
chn <= 目標字 且最大的那一筆,即得聲母。
- 逐字迴圈處理,非漢字直接保留。
效能與擴充建議
- 表值參數改為永久資料表或記憶體最佳化表,避免每次呼叫重建表變數。
- 大量資料轉換時,改用
CLR 函數 (C#) 以 Microsoft.International.Converters.PinyinConverter 實作,速度提升 10 倍以上。
- 支援多音字需引入詞庫與上下文判斷,純 T-SQL 難以完美解決。
適用場景
- 中文排序輔助欄位(
ORDER BY dbo.NWGetPYFirst(Name))。
- 拼音索引建立、輸入法聯想、簡拼搜尋。
- 資料遷移時產生拼音代碼欄位。