I have the following table:
CREATE TABLE child(
id INTEGER PRIMARY KEY,
parent_id INTEGER,
description TEXT);
How do I add a forei
If you are using the Firefox add-on sqlite-manager you can do the following:
Instead of dropping and creating the table again one can just modify it like this.
In the Columns text box, right click on the last column name listed to bring up the context menu and select Edit Column. Note that if the last column in the TABLE definition is the PRIMARY KEY then it will be necessary to first add a new column and then edit the column type of the new column in order to add the FOREIGN KEY definition. Within the Column Type box , append a comma and the
FOREIGN KEY (parent_id) REFERENCES parent(id)
definition after data type. Click on the Change button and then click the Yes button on the Dangerous Operation dialog box.
Reference: Sqlite Manager
You can't.
Although the SQL-92 syntax to add a foreign key to your table would be as follows:
ALTER TABLE child ADD CONSTRAINT fk_child_parent
FOREIGN KEY (parent_id)
REFERENCES parent(id);
SQLite doesn't support the ADD CONSTRAINT
variant of the ALTER TABLE
command (sqlite.org: SQL Features That SQLite Does Not Implement).
Therefore, the only way to add a foreign key in sqlite 3.6.1 is during CREATE TABLE
as follows:
CREATE TABLE child (
id INTEGER PRIMARY KEY,
parent_id INTEGER,
description TEXT,
FOREIGN KEY (parent_id) REFERENCES parent(id)
);
Unfortunately you will have to save the existing data to a temporary table, drop the old table, create the new table with the FK constraint, then copy the data back in from the temporary table. (sqlite.org - FAQ: Q11)
You can try this:
ALTER TABLE [Child] ADD COLUMN column_name INTEGER REFERENCES parent_table_name(column_id);
Yes, you can, without adding a new column. You have to be careful to do it correctly in order to avoid corrupting the database, so you should completely back up your database before trying this.
for your specific example:
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
or more generally:
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;
Either way, you'll probably want to first see what the SQL definition is before you make any changes:
select sql from SQLITE_MASTER where name = 'child' and type = 'table';
If you use the replace() approach, you may find it helpful, before executing, to first test your replace() command by running:
select replace(sql, ...) from SQLITE_MASTER where name = 'child' and type = 'table';
In case somebody else needs info on SQLiteStudio, you can easily do it form it's GUI.
Double-click on the column and double-click foreign key row, then tick foreign key and click configure. You can add the reference column, then click OK in every window.
Finally click on the green tick to commit changes in the structure.
BE AWARE THAT THESE STEPS CREATE SQL SCRIPTS THAT DELETES THE TABLE AND RECREATES IT!!
Backup your data from the database.