Có, bạn có thể, mà không cần thêm một cột mới. Bạn phải cẩn thận để làm điều đó một cách chính xác để tránh làm hỏng cơ sở dữ liệu, vì vậy bạn nên sao lưu hoàn toàn cơ sở dữ liệu của mình trước khi thử điều này.
cho ví dụ cụ thể của bạn:
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
hay nói chung hơn:
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;
Dù bằng cách nào, trước tiên bạn có thể muốn xem định nghĩa SQL là gì trước khi bạn thực hiện bất kỳ thay đổi nào:
select sql from SQLITE_MASTER where name = 'child' and type = 'table';
Nếu bạn sử dụng phương pháp thay thế (), bạn có thể thấy nó hữu ích, trước khi thực hiện, trước tiên hãy kiểm tra lệnh thay thế () của bạn bằng cách chạy:
select replace(sql, ...) from SQLITE_MASTER where name = 'child' and type = 'table';