ASCII()返回首字符ASCII码而非字符串长度,CHAR()仅支持0–255整数,二者均不适用于多字节字符或Unicode场景,应优先使用数据库原生Unicode函数。

ASCII函数返回的是字符的ASCII码值,不是字符串长度
很多人误以为 ASCII() 能用来测字符串长度,其实它只处理第一个字符。比如 ASCII('ABC') 返回 65('A' 的 ASCII 值),后面 'B'、'C' 完全被忽略。如果你要取多字符的编码,得配合 SUBSTRING() 或循环逻辑(如递归 CTE 或数字表)逐个提取。
常见错误现象:SELECT ASCII('你好') 在 MySQL 或 SQL Server 中返回 20320(其实是 '你' 的 GBK 编码值,不是 ASCII)——这说明该函数在非 ASCII 字符集下行为不可靠,本质是按当前列/连接的字符集字节序取首字节,不是标准 ASCII。真正安全的场景仅限于单字节字符,比如英文、数字、标点。
- 使用前确认字段字符集是
latin1或ascii,否则结果无意义 - PostgreSQL 没有内置
ASCII(),要用get_byte(encode(col, 'escape'), 0)替代,且只适用于 UTF-8 下的 ASCII 范围字符 - SQL Server 中
ASCII(N'中')返回 20013,这是 Unicode 码点,但函数名仍叫 ASCII —— 注意文档误导性
CHAR函数只能接受0–255之间的整数,超出会报错或截断
CHAR() 是 ASCII 编码的逆操作,但它严格限制输入范围。例如 CHAR(256) 在 SQL Server 中直接报错 Argument 1 of the CHAR function is invalid;MySQL 5.7+ 则静默转为 CHAR(0)(空字符),MySQL 8.0 开始报错。这意味着你不能用它生成 Unicode 字符(比如中文),哪怕你知道 UTF-8 编码是多字节的。
典型误用:CHAR(20320) 想输出 '你' —— 实际上 20320 远超 255,结果不可预测。正确做法是:如果数据库支持,改用 NCHAR()(SQL Server)或 CHR() 配合 Unicode 模式(Oracle),或直接写 Unicode 字面量 N'你'。
- MySQL 中可用
CHAR(65 USING utf8mb4),但 65 仍是 ASCII 值,不解决中文问题 - PostgreSQL 用
chr(65),同样只支持 0–255;Unicode 字符需chr(65::int4)+convert_from(decode(...), 'UTF8')组合,非常绕 - 别依赖
CHAR()做加密或编码转换,它不是设计来干这个的
用ASCII和CHAR做简单大小写翻转时要注意字符集排序规则
小写字母 a–z 的 ASCII 是 97–122,大写 A–Z 是 65–90,差值恒为 32。所以 CHAR(ASCII(col) - 32) 看似能转大写,但实际风险很大:一旦字段含空格(32)、数字(48–57)或非字母字符,计算结果会落到控制字符区(0–31)或无效范围,导致乱码或截断。
更严重的是,这种写法绕过了数据库的 collation 规则,无法处理带重音符号的字母(如 é、ñ)、德语 ß、土耳其语 İ 等。SQL Server 的 UPPER()、MySQL 的 UPPER() 都基于当前排序规则,而手工 ASCII 运算完全无视这点。
- 只对纯 ASCII 英文字母字段临时调试可用,生产环境禁用
- 遇到
ASCII('a') - 32 = 65成功,但ASCII(' ')是 32,减完变 0,CHAR(0)在多数客户端显示为空或异常 - 若字段定义为
varchar(10) COLLATE Latin1_General_BIN,大小写翻转仍可能因二进制比较失效,手工运算毫无优势
真正需要字符编码转换时,优先用数据库原生Unicode函数而非ASCII/CHAR组合
想把字符串转成十六进制编码?用 HEX()(MySQL)、CONVERT(VARCHAR, col, 2)(SQL Server);想从十六进制还原?用 UNHEX() 或 CONVERT(VARBINARY, col, 2)。这些才是为编码转换设计的接口。ASCII() 和 CHAR() 只是遗留的单字节工具,强行套用到现代多字节场景里,等于拿螺丝刀当锤子用。
一个具体例子:你想把用户输入的密码字符串转成 ASCII 字节序列再哈希。正确路径是先确保连接字符集为 utf8mb4,然后用 SHA2( CAST(col AS BINARY), 256 ),而不是写一堆 ASCII(SUBSTRING(col,1,1)) 拼接——后者既慢又易出错,还无法处理 emoji。
- SQL Server 中
DATALENGTH(N'你')返回 4(UTF-16 编码占 2 字),而ASCII(N'你')返回 20013,二者单位根本不一致 - MySQL 8.0+ 支持
TO_BASE64()和FROM_BASE64(),比手撕 ASCII 安全得多 - 跨库迁移时,
CHAR(65)在所有系统都返回 'A',但CHAR(20320)在各库表现完全不同,兼容性为零
ASCII 和 CHAR 函数的边界很窄:它们只在纯英文、单字节环境里可靠。只要涉及中文、emoji、特殊符号或任意国际化需求,立刻切换到对应数据库的 Unicode 原生函数,别试图用老办法硬撑。

















