You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UTF-8编码SQLite中SUBSTR与INSTR多字节字符兼容问题

SQLite中SUBSTR与INSTR配合处理多字节字符的问题及解决方法

问题描述

在UTF-8编码的SQLite数据库里,SUBSTR函数按字节而非字符处理字符串,这在包含多字节字符的场景下会导致功能失效。而INSTR函数基于Unicode码点返回位置,两者配合提取子串时会出现裁剪错误。

简化测试用例

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE test (title TEXT);
INSERT INTO test VALUES(X'3232313031315f313335365f417072c3a8732d6d6964695f31312d31302d32303232220d');
INSERT INTO test VALUES(X'3232313031335f313535315f5f5245504f52544147455f31372d30312d32303230220d');
COMMIT;

环境与数据信息

sqlite> .version
SQLite 3.26.0 2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238alt1
zlib version 1.2.11
gcc-8.3.1 20191121 (Red Hat 8.3.1-5)
sqlite> PRAGMA encoding;
UTF-8
sqlite> .schema
CREATE TABLE test (title TEXT);
sqlite> select * from test;
221011_1356_Après-midi_11-10-2022"
221013_1551__REPORTAGE_17-01-2020"

问题复现

两个字符串的字符长度相同,但第一个字符串包含双字节字符è,字节长度比第二个多1。使用INSTR返回的字符位置是34,但SUBSTR按字节裁剪,导致第一个字符串被多截了一部分:

sqlite> select INSTR(title, '"'), SUBSTR(title, 0, INSTR(title, '"')) from test;
34|221011_1356_Après-midi_11-10-202
34|221013_1551__REPORTAGE_17-01-2020

该问题在Windows下的SQLite 3.41.2版本中依然存在。

解决方法

将字段CAST为varchar即可解决此问题,让SUBSTR按字符而非字节处理:

sqlite> select INSTR(cast(title as varchar), '"'), SUBSTR(cast(title as varchar), 0, INSTR(cast(title as varchar), '"')) from test; -- nbk提供的解决方案,核心是转换为varchar让SUBSTR正常工作
34|221011_1356_Après-midi_11-10-2022
34|221013_1551__REPORTAGE_17-01-2020

内容的提问来源于stack exchange,提问作者Bruno Rohère

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:15:05