SQLite 字符串含 NUL 字符问题多,教你判断和移除!

📅 2026/7/16 8:43:54
SQLite 字符串含 NUL 字符问题多,教你判断和移除!
字符串中的 NUL 字符1. 引言SQLite 允许数据库存储的字符串值中间包含 NUL 字符ASCII 0x00Unicode \u0000。然而在字符串中使用 NUL 可能会引发一些意外状况其一[length() SQL 函数](lang_corefunc.html#length) 仅统计到第一个 NUL 字符不包括该字符之前的字符数量其二[quote() SQL 函数](lang_corefunc.html#quote) 只显示到第一个 NUL 字符不包括该字符之前的字符其三[CLI](cli.html) 中的 [.dump](cli.html#dump) 命令在生成的 SQL 输出中会省略第一个 NUL 字符以及其后的所有文本实际上[CLI](cli.html) 在所有情况下都会省略第一个 NUL 字符之后的所有内容。所以不建议在 SQL 文本字符串中使用 NUL 字符。2. 意外行为来看下面这段 SQLCREATE 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 语句的输出为1,abc,3这里假设 [CLI](cli.html) 已设置为 [.mode quote](climode.html#dotmodequote)。但要是运行SELECT * FROM t1 WHERE babc;则不会返回任何行。SQLite 知道 t1.b 列实际存储的是一个 7 字符的字符串而 7 字符的字符串 abc||char(0)||xyz 不等于 3 字符的字符串 abc所以不会返回任何行。可这可能会让用户感到困惑因为 [CLI](cli.html) 的输出似乎显示该字符串只有 3 个字符。这看似是个 bug但这就是 SQLite 的运行方式。3. 如何判断字符串中是否有 NUL 字符若使用 [CAST](lang_expr.html#castexpr) 将字符串转换为 BLOB就能看到字符串的完整长度。例如SELECT a, CAST(b AS BLOB) FROM t1;结果如下1,X6162630078797a在 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 bsubstr(b,1,instr(b,char(0))) WHERE instr(b,char(0));