SQLite3执行ALTER TABLE ADD FOREIGN KEY报语法错误如何解决
问题场景
正在完成CS50课程的finance项目,当前数据库执行.schema命令的输出如下:
sqlite> .schema CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username TEXT NOT NULL, hash TEXT NOT NULL, cash NUMERIC NOT NULL DEFAULT 10000.00); CREATE TABLE sqlite_sequence(name,seq); CREATE TABLE history( symbol TEXT, name TEXT, shares INTEGER, price NUMERIC, time DATETIME ); CREATE UNIQUE INDEX username ON users (username);
尝试为history表添加指向users表id字段的外键,首先执行ALTER TABLE history ADD COLUMN id INT;语句新增id列,随后执行添加外键的语句时始终返回错误,相关执行代码与报错信息如下:
sqlite> ALTER TABLE history ADD COLUMN id INT; sqlite> ALTER TABLE history ADD FOREIGN KEY(id) REFRENCES users(id); Parse error: near "FOREIGN": syntax error ALTER TABLE history ADD FOREIGN KEY(id) REFRENCES users(id); ^--- error here
错误原因
报错来自两个核心问题:
- 关键字拼写错误:外键关联的关键字书写有误,
REFRENCES是错误拼写,正确写法为REFERENCES。 - SQLite本身的语法限制:SQLite的
ALTER TABLE语法不支持直接给已存在的表追加外键约束,就算修正拼写错误,ADD FOREIGN KEY的写法依然会触发语法报错。
解决步骤
SQLite给已有表添加外键需要通过重建表的方式实现,操作流程如下:
- 首先开启外键生效开关(SQLite默认关闭外键约束校验),执行命令:
PRAGMA foreign_keys = ON;
- 将现有history表重命名为临时备份表:
ALTER TABLE history RENAME TO history_temp;
- 新建带正确外键约束的history表,字段和原表保持一致,外键字段建议设置为非空,避免出现无归属用户的无效交易记录:
CREATE TABLE history( id INTEGER NOT NULL, symbol TEXT, name TEXT, shares INTEGER, price NUMERIC, time DATETIME, FOREIGN KEY(id) REFERENCES users(id) );
- 将临时备份表中的数据全部迁移到新创建的history表中:
INSERT INTO history SELECT * FROM history_temp;
- 校验迁移后的数据完整无误,删除临时备份表即可:
DROP TABLE history_temp;
注意:如果之前新增的id列存在空值,迁移数据前需要先给每条历史记录补全对应的用户id,否则会触发外键约束校验失败,无法完成数据插入。
内容的提问来源于stack exchange,提问作者MWD
相关产品推荐
相关产品推荐

