SQLite字符串中的NUL字符
摘要
SQLite允许字符串中包含NUL字符,但这可能导致字符串函数和CLI输出中出现意外行为;本文介绍了如何检测和删除嵌入的NUL字符。
暂无内容
查看缓存全文
缓存时间: 2026/07/16 01:46
# 字符串中的 NUL 字符
来源:https://sqlite.org/nulinstr.html
字符串中的 NUL 字符
## 1. 引言
SQLite 允许在数据库存储的字符串值中间包含 NUL 字符(ASCII 0x00,Unicode \u0000)。然而,在字符串中使用 NUL 可能会导致一些意外行为:
1. `length()` SQL 函数(https://sqlite.org/lang_corefunc.html#length)仅计算到第一个 NUL 字符之前的字符数(不包括该 NUL)。
2. `quote()` SQL 函数(https://sqlite.org/lang_corefunc.html#quote)仅显示到第一个 NUL 字符之前的内容(不包括该 NUL)。
3. 在 CLI(https://sqlite.org/cli.html)中,`.dump`(https://sqlite.org/cli.html#dump)命令在其生成的 SQL 输出中会省略第一个 NUL 字符及其之后的所有文本。实际上,CLI(https://sqlite.org/cli.html)在所有上下文中都会省略第一个 NUL 字符之后的所有内容。
不建议在 SQL 文本字符串中使用 NUL 字符。
## 2. 意外行为
考虑以下 SQL:
```
CREATE TABLE t1(
a INTEGER PRIMARY KEY,
b TEXT
);
INSERT INTO t1(a,b) VALUES(1, 'abc'||char(0)||'xyz');
SELECT a, b, length(b) FROM t1;
```
上面的 SELECT 语句的输出为:
(在本文档中,我们假设 CLI(https://sqlite.org/cli.html)已设置“.mode quote(https://sqlite.org/climode.html#dotmodequote)”。)但如果你执行:
```
SELECT * FROM t1 WHERE b='abc';
```
则不会返回任何行。SQLite 知道 t1.b 列实际保存的是一个 7 字符字符串,而 7 字符字符串 'abc'||char(0)||'xyz' 与 3 字符字符串 'abc' 不相等,因此不会返回任何行。但用户很容易因此感到困惑,因为 CLI(https://sqlite.org/cli.html)的输出似乎显示该字符串只有 3 个字符。这看起来像是一个 bug,但这就是 SQLite 的工作方式。
## 3. 如何判断字符串中是否包含 NUL 字符
如果你将字符串 `CAST`(https://sqlite.org/lang_expr.html#castexpr)为 BLOB,则会显示字符串的完整长度。例如:
```
SELECT a, CAST(b AS BLOB) FROM t1;
```
得到以下结果:
在 BLOB 输出中,你可以清楚地看到 NUL 字符是 7 字符字符串中的第 4 个字符。
另一种更自动化的判断字符串值 X 是否包含嵌入 NUL 字符的方法是使用如下表达式:
```
instr(X,char(0))
```
如果该表达式返回非零值 N,则说明在第 N 个字符位置存在一个嵌入的 NUL。因此,要统计包含嵌入 NUL 字符的行数:
```
SELECT count(*) FROM t1 WHERE instr(b,char(0))>0;
```
## 4. 从文本字段中移除 NUL 字符
以下示例展示了如何从表的列中移除 NUL 字符及其之后的所有文本。因此,如果你的数据库文件包含嵌入的 NUL 并希望移除它们,运行类似于下面的 UPDATE 语句可能会有所帮助:
```
UPDATE t1 SET b=substr(b,1,instr(b,char(0)))
WHERE instr(b,char(0));
```
*本页最后更新于 2022-05-23 22:21:54Z*
相似文章
在SQLite中推荐使用严格表
SQLite的严格表强制执行严格类型检查,以防止常见的数据类型错误。本文介绍了如何使用它们以及它们的优缺点。
用细齿梳检查 SQLite
John Regehr 描述了使用 tis-interpreter 在 SQLite 中搜索未定义行为,发现了其他工具遗漏的错误,如悬空指针使用和未初始化读取。
Unicode 字符串的等价性很奇怪 (2016)
Unicode 字符串等价性很复杂,尤其是涉及校对规则时,会导致意外的结果,例如删除控制字符和非确定性分组。作者讨论了在数据库系统中正确实现 Unicode 支持所面临的挑战。
用 String View 修复 C 字符串
一篇博客文章,解释了 C 语言中以 NUL 结尾的字符串所存在的问题,并介绍了一个小型的单文件 C 库,该库提供 str_view 和 str_owned 结构体,以实现更安全、更高效的字符串处理。
C字符串:一个50年的错误
对C语言中空终止字符串的批评,认为基于长度的字符串在现代编程中更优越,可以减少错误并提高性能。