ใช่คุณสามารถทำได้โดยไม่ต้องเพิ่มคอลัมน์ใหม่ คุณต้องระมัดระวังในการทำอย่างถูกต้องเพื่อหลีกเลี่ยงไม่ให้ฐานข้อมูลเสียหายดังนั้นคุณควรสำรองฐานข้อมูลให้ครบถ้วนก่อนที่จะลองทำเช่นนี้
สำหรับตัวอย่างเฉพาะของคุณ:
CREATE TABLE child(
id INTEGER PRIMARY KEY,
parent_id INTEGER,
description TEXT
);
--- create the table we want to reference
create table parent(id integer not null primary key);
--- now we add the foreign key
pragma writable_schema=1;
update SQLITE_MASTER set sql = replace(sql, 'description TEXT)',
'description TEXT, foreign key (parent_id) references parent(id))'
) where name = 'child' and type = 'table';
--- test the foreign key
pragma foreign_keys=on;
insert into parent values(1);
insert into child values(1, 1, 'hi'); --- works
insert into child values(2, 2, 'bye'); --- fails, foreign key violation
หรือมากกว่าโดยทั่วไป:
pragma writable_schema=1;
// replace the entire table's SQL definition, where new_sql_definition contains the foreign key clause you want to add
UPDATE SQLITE_MASTER SET SQL = new_sql_definition where name = 'child' and type = 'table';
// alternatively, you might find it easier to use replace, if you can match the exact end of the sql definition
// for example, if the last column was my_last_column integer not null:
UPDATE SQLITE_MASTER SET SQL = replace(sql, 'my_last_column integer not null', 'my_last_column integer not null, foreign key (col1, col2) references other_table(col1, col2)') where name = 'child' and type = 'table';
pragma writable_schema=0;
ไม่ว่าจะด้วยวิธีใดคุณอาจต้องการทราบก่อนว่านิยาม SQL คืออะไรก่อนที่คุณจะทำการเปลี่ยนแปลงใด ๆ :
select sql from SQLITE_MASTER where name = 'child' and type = 'table';
หากคุณใช้วิธีการแทนที่ () คุณอาจพบว่ามีประโยชน์ก่อนที่จะดำเนินการให้ทดสอบคำสั่งแทนที่ () ของคุณก่อนโดยรัน:
select replace(sql, ...) from SQLITE_MASTER where name = 'child' and type = 'table';