SQL Server中DATALENGTH对多字节字符返回1字节,应使用何替代函数?
在SQL Server中正确获取字符的字节数
问题根源
你遇到的差异核心是字符编码与字符串类型的匹配逻辑不同:
- Oracle的
LENGTHB、PostgreSQL的OCTET_LENGTH默认返回字符在UTF-8编码下的字节数(“和”在UTF-8中占3字节)。 - SQL Server的
DATALENGTH()确实返回值的实际存储字节数,但你的测试场景存在两个关键问题:- 未加
N前缀的字符串常量默认是varchar类型,会使用数据库默认字符集编码。若数据库用单字节字符集(如SQL_Latin1_General_CP1_CI_AS),“和”这类非ASCII字符会被替换为单字节占位符(如?),因此DATALENGTH('和')返回1。 - 即使使用GBK这类多字节非UTF-8字符集,“和”仅占2字节,
DATALENGTH('和')也只会返回2,与UTF-8的3字节结果不符。
- 未加
解决方法
根据你的需求选择对应方案:
1. 获取UTF-8编码下的字节数(匹配Oracle/PostgreSQL结果)
如果你的SQL Server版本是2019及以上(支持UTF-8字符集):
- 直接将数据库或目标列的collation设置为UTF-8类型(如
Chinese_Simplified_UTF8_CI_AS),此时DATALENGTH('和')会直接返回3。 - 无需修改数据库设置的话,可临时转换编码:
SELECT DATALENGTH(CONVERT(VARCHAR(MAX), '和') COLLATE Chinese_Simplified_UTF8_CI_AS)
2. 获取Unicode(UTF-16)编码下的字节数
SQL Server默认Unicode类型为nvarchar,大部分常用汉字占2字节,只需给字符串加N前缀:
SELECT DATALENGTH(N'和') -- 返回2
3. 兼容旧版本的通用方案
若使用SQL Server 2019之前的版本,可自定义函数计算UTF-8字节数:
CREATE FUNCTION dbo.UTF8ByteCount(@str NVARCHAR(MAX)) RETURNS INT AS BEGIN DECLARE @count INT = 0 DECLARE @i INT = 1 WHILE @i <= LEN(@str) BEGIN DECLARE @code INT = UNICODE(SUBSTRING(@str, @i, 1)) IF @code <= 0x7F SET @count += 1 ELSE IF @code <= 0x7FF SET @count += 2 ELSE IF @code <= 0xFFFF SET @count += 3 ELSE SET @count += 4 SET @i += 1 END RETURN @count END
调用方式:
SELECT dbo.UTF8ByteCount('和') -- 返回3
内容的提问来源于stack exchange,提问作者drk
相关产品推荐
相关产品推荐

