前幾天剛好有朋友問,怎麼下TSQL判斷,資料表中欄位含有中文的字,
就先想到可以用先把字串分解成一個一個的字元,再來做 ASCII 的比對,
建立的副程式如下
我的想法是因為最後一個英文 z 是122 ,所以比 122 大就判斷不是英文,
而 A-Z,a-z 的範圍 ASCII 如下
-- a 97
-- z 122
-- A 65
-- Z 90
01 | CREATE FUNCTION [dbo].[udf_IsContainChinese] |
02 | (@inString nvarchar(1000)) |
03 | RETURNS int |
04 | AS |
05 | BEGIN |
06 |
07 | DECLARE @flag int |
08 | |
09 | DECLARE @valueLength int |
10 | SET @valueLength = LEN(@inString) |
11 | DECLARE @i int |
12 | SET @i = 1 |
13 | WHILE @valueLength >= @i |
14 | BEGIN |
15 | DECLARE @ChcekValue int |
16 |
17 | SELECT @ChcekValue = ASCII(SUBSTRING(@inString,@i,1)) |
18 | --SELECT @ChcekValue |
19 | if(@ChcekValue > 122) |
20 | BEGIN |
21 | -- 有中文 |
22 | SET @flag = 1 |
23 | -- 跳出 |
24 | BREAK |
25 | END |
26 | ELSE |
27 | BEGIN |
28 | SET @flag = 0 |
29 | END |
30 | SET @i = @i +1 |
31 | END |
32 | RETURN @flag |
33 | END |
而 Function 的使用如下,將 Function傳入欄位值,會傳回 1 ,0 用來判斷,
也可以將 Function 拿來當 WHERE 的比對來使用
1 | SELECT *,dbo.udf_IsContainChinese(value) |
2 | FROM dbo.TestTemp |
3 |
|
後來想一想,是不是還有別的方法也可以判斷資料欄位中是否還有中文的值,
一直想到是不是有類似 Regular 的方式,後來查了一下 SQL 中有 PATINDEX 可以使用,
就想說找出第一個中文字的起點,再找出最後一個中文字,就能下規則的方式來找出,
後來有點懶惰,就用一個一個測試,猜數字的方式,來找出第一個中文,
而找出第一個中文跟最後一個中文測試的TSQL如下:
01 | --土法煉鋼的方式找到'一'是中文字的起點 19968 |
02 | SELECT UNICODE('一') |
03 | SELECT NCHAR(19968) |
04 | --土法煉鋼的方式找到'龥'是中文字的終點 40869 |
05 | SELECT UNICODE('龥') |
06 | SELECT NCHAR(40869) |
07 | -- 但'龥' 在用UNICODE查出卻是 63 |
08 | -- 而在 40869 - 40861 龞,龟 .... 這幾個字查出來都是 63 |
09 | -- 只有 '龜' 查出來是 40860 |
10 |
11 | SELECT UNICODE('龜') |
12 | SELECT NCHAR(40860) |
因為欄位都會存 nvarchar 的方式,所以我用 UNICODE 的方式來查出,
但遇到了一個問題,最後一個中文字因該是 '龥' 40869 ,但NCHAR('龥')
卻是 63 ,而 40861 - 40869 這幾個字 NCHAR(' ') 都會是63,
這點到現在我也還沒搞懂,還望有高手能夠指點,
而慢慢的往前推,就發現 '龜' 字 40860 是可以在 NCHAR 傳回正常的 40860 ,
所以我就先認定合格的中文字範圍是 一-龜
而這個範例 TSQL使用 PATINDEX 程式碼如下:
1 | SELECT patindex('%[一-龜]%',value),* |
2 | FROM dbo.TestTemp |
3 | WHERE patindex('%[一-龜]%',value) > 0 |
執行畫面如下,也可以將PATINDEX當WHERE條件來比對
第二個方法比較是鎖定中文字的範圍,來做比對的方式,但有發生前面提到的
「而 40861 - 40869 這幾個字 NCHAR(' ') 都會是63」,這點還沒想通是什麼原因,
一般的資料欄位中是否中文比對,用兩種方式都能夠可以比對的出來,
或許還有更好的方法,還請大家多指點。
參考資源:
http://msdn.microsoft.com/zh-tw/library/ms188395.aspx
http://www.dotblogs.com.tw/dotjum/archive/2008/07/19/4597.aspx
