当前,在3.25.2版中,SQLite仅对alter table支持有限。例如。您不能更改列的数据类型(类型相似性)或删除列。
通常的解决方法是使用所需的架构创建一个新表,将原始表中的数据填充其中,删除原始表,然后重命名新表。但是,如果原始表是具有外键关系的父表怎么办?
official solution正在关闭外键,进行所需的更改,然后再打开外键。但是我对此有点恼火,因为这PRAGMA foreign_keys =
在交易内部不会生效,因此需要在发行之前和之后进行发行。
我想改用延迟外键。 我有3个查询,其中一个似乎有效,另外两个则无效。我的问题如下:
PRAGMA foreign_keys = OFF;
DROP TABLE IF EXISTS Parent;
CREATE TABLE Parent(A TEXT UNIQUE, COLUMN_TO_DROP FLOAT);
INSERT INTO Parent VALUES('whatever', 0.0);
DROP TABLE IF EXISTS Child;
CREATE TABLE Child(C TEXT REFERENCES Parent(A) DEFERRABLE INITIALLY DEFERRED);
INSERT INTO Child VALUES('whatever');
PRAGMA foreign_keys = ON;
BEGIN TRANSACTION;
CREATE TABLE Temp AS SELECT A FROM Parent;
DROP TABLE Parent;
CREATE TABLE Parent (A TEXT UNIQUE);
INSERT INTO Parent SELECT * FROM Temp;
DROP TABLE Temp;
COMMIT;
BEGIN TRANSACTION;
CREATE TABLE Temp AS SELECT A FROM Parent;
DROP TABLE Parent;
CREATE TABLE Parent AS SELECT * FROM Temp; -- different from Query1
CREATE UNIQUE INDEX ParentIndex on Parent(A); -- different from Query1
DROP TABLE Temp;
COMMIT;
结果:
sqlite> PRAGMA foreign_key_check;
sqlite> .schema
CREATE TABLE Child(C TEXT REFERENCES Parent(A) DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE Parent(A TEXT);
CREATE UNIQUE INDEX ParentIndex on Parent(A);
sqlite> SELECT * FROM Parent;
whatever
BEGIN TRANSACTION;
CREATE TABLE Temp (A TEXT UNIQUE); -- different from Query1
INSERT INTO Temp SELECT A FROM Parent; -- different from Query1
DROP TABLE Parent;
CREATE TABLE Parent (A TEXT UNIQUE);
INSERT INTO Parent SELECT * FROM Temp;
DROP TABLE Temp;
COMMIT;
结果:
sqlite> PRAGMA foreign_key_check;
sqlite> .schema
CREATE TABLE Child(C TEXT REFERENCES Parent(A) DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE Parent (A TEXT UNIQUE);
sqlite> SELECT * FROM Parent;
whatever
请注意,PRAGMA foreign_key_check
在任何情况下均未报告任何问题。