简介

在工作中遇到了一个场景需要判断字符串中是否有中文,虽然之前也遇到过,但是没有记录。这次记录于此。

详解

经查询,有三种方式,分别是根据编码范围,根据字符和字节长度,使用正则。
经测试发现,使用正则不太准确,故不介绍这种。

根据编码范围

中文字符的Unicode编码范围在(19968,40869)之间。
结合unicode函数实现,
其功能是获取字符串中第一个字符的unicode编码,如下:

SELECT UNICODE('111');  --返回 49
SELECT UNICODE('122');  --返回 50
SELECT UNICODE('211');  --返回 49

写个函数,方便以后调用,如下:

CREATE FUNCTION dbo.isHasChinese
(
    @inputString NVARCHAR(MAX)
)
RETURNS BIT
AS
BEGIN
    DECLARE @hasChinese BIT = 0;
        DECLARE @onechar VARCHAR(128);
        DECLARE @position INT = 1;
        DECLARE @len INT;
        SELECT @len=LEN(@inputString);

        WHILE @position <= @len
        BEGIN
                SELECT @onechar = SUBSTRING(@inputString, @position, 1)
                IF (unicode(@onechar) between 19968 and 40869)
                BEGIN
                    SET @hasChinese = 1;
                    BREAK;
                END
                SET @position = @position + 1;
        END;
    RETURN @hasChinese;
END

如果字符串中包含中文字符,则返回布尔1,否则返回布尔0。使用效果如下:

SELECT dbo.isHasChinese('culturesun');       --返回 0
SELECT dbo.isHasChinese('culturesun你好');   --返回 1
SELECT dbo.isHasChinese('你好');             --返回 1

因布尔类型的特殊性,既可以将返回结果当字符,也可以当数值,如下:

SELECT 1 where dbo.isHasChinese('culturesun')=0;       --返回 1
SELECT 1 where dbo.isHasChinese('culturesun')='0';       --返回 1

根据字符和字节长度

众所周知,在多数编码中,英文字符是一个字节,而中文字符是两个字节。
所以,如果字节长度大于字符长度,那么字符串中就是包含中文的。
配合lendatalength函数使用便可判断字符串中是否有中文。
len函数可获取到字符长度,datalength函数可获取到字节长度,如下:

SELECT LEN('111');            --返回 3
SELECT LEN('你好呀');         --返回 3
SELECT DATALENGTH('111');     --返回 3
SELECT DATALENGTH('你好呀');  --返回 6

写个函数,方便以后调用,如下:

ALTER FUNCTION dbo.isHasChinese
(
    @inputString VARCHAR(MAX)
)
RETURNS BIT
AS
BEGIN
        DECLARE @hasChinese BIT = 0;
    IF DATALENGTH(@inputString)>LEN(@inputString)
        BEGIN
            SET @hasChinese=1;
        END
    RETURN @hasChinese;
END

如果字符串中包含中文字符,则返回布尔1,否则返回布尔0。使用效果如下:

SELECT dbo.isHasChinese('culturesun');       --返回 0
SELECT dbo.isHasChinese('culturesun你好');   --返回 1
SELECT dbo.isHasChinese('你好');             --返回 1

结语

学习过程中,遇到了一点突发情况,所以又增加了一个小知识。

SQL server数据库中有NVARCHARVARCHAR两个类型,相似但是有差别。

NVARCHAR 是用 UTF-16 编码
VARCHAR 是用 UTF-8 编码
而 UTF-16 编码的字节数通常是 UTF-8 编码的两倍(相对于单字节编码字符,比如英文字符), 所以使用 datalength 函数获取 NVARCHAR 类型的字节数可能会与常识有误差,例如字母 a 常识是一个字节,但是使用 NVARCHAR 类型的 a 是两个字节