使用expo-sqlite时主键非空约束报错问题排查
Expo-SQLite插入数据时NOT NULL约束错误的解决方案
你的理解是对的:SQLite的主键可以配置为自动自增,插入新行时无需手动提供id值。问题出在你的建表语句语法上,而非expo-sqlite包本身。
问题根源
SQLite中,只有当主键字段被定义为INTEGER PRIMARY KEY(语义上匹配该关键字即可,SQLite不严格区分大小写)时,才会自动为该字段生成自增的整数值。而你的建表语句里,id字段只是integer类型+主键约束,属于普通非空主键,不会自动生成值,所以插入时不传入id就会触发NOT NULL约束错误。
另外你的transactions表外键引用了不存在的test_categories表,应该改为categories,这也是潜在问题。
修正后的建表代码
修改两个表的建表语句,将id字段改为自增主键:
useEffect(() => { // Create new tables if no database exist db.transaction((tx) => { tx.executeSql( 'create table if not exists categories (id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(255));', [], () => {}, (tx, err) => { console.log('建表错误(categories)', err); return true; } ); tx.executeSql( 'create table if not exists transactions (id INTEGER PRIMARY KEY AUTOINCREMENT, tx_datetime datetime, tx_value varchar(255), note varchar(255), tx_day integer, tx_month integer, tx_year varchar(255), category integer, tx_type integer default 0, foreign key (category) references categories (id));', [], () => {}, (tx, err) => { console.log('建表错误(transactions)', err); return true; } ); }); }, []);
补充说明
INTEGER PRIMARY KEY已经足够让SQLite自动生成自增id,AUTOINCREMENT关键字是可选的——它会强制id严格递增且不重用已删除行的id(默认情况下,SQLite可能会重用已删除的id值),可根据业务需求选择是否添加。- 修正外键引用的表名后,
transactions表的外键约束才能正常生效。
验证插入操作
修改建表语句后,你原来的插入代码就能正常执行,无需传入id字段:
db.transaction((tx) => { tx.executeSql( 'insert into categories(name) values("testing");', [], () => console.log("插入成功"), (tx, err) => { console.log('插入错误', err); return true; } ); });
内容的提问来源于stack exchange,提问作者jted95
相关产品推荐
相关产品推荐

