How do I convert an existing column to Foreign Key?
Asked Answered
P

3

15

I have a two tables.

Table a looks something like this -- first row is column names, both contain characters:

id |  tractce   | someString
1  |  "0011900" | "Label here"

Table b:

id | tractFIPS
1  | "0011900"

How do I convert a.tractce to a foreign key column referencing b.id?

So that it's:

id |  tractce | someString
1  |  1       | "Label here"
Pily answered 29/1, 2018 at 21:33 Comment(0)
A
8

You can't do this in one step. You need to first add a new column that can hold the primary key of table b, then update table a and then add the foreign key and drop the old column:

alter table a add b_id int;

update a
   set b_id = b.id
from b 
where a.tractce = b.tractfips;


alter table a drop column tractce;
alter table a add constraint fk_a_b foreign key (b_id) references b;

Online example: http://rextester.com/LPWNHK59722

Acutance answered 29/1, 2018 at 23:2 Comment(1)
Are you sure about this? This answer with some upvotes above seems to say its possible: https://mcmap.net/q/781860/-how-do-i-convert-an-existing-column-to-foreign-keyOvum
B
6

This will add the constraint as long as there isn't any rogue data in the tables:

ALTER TABLE TableName
ADD CONSTRAINT fk_Name
FOREIGN KEY (ColumnName) 
REFERENCES TableName(ColumnName);
Burglarious answered 29/1, 2018 at 21:37 Comment(3)
Sorry, I edited my question to fix a typo and clarify it. Does your answer still apply?Pily
you cant have a foreign key on columns that don't have the same data in (well you can but its never a good idea and would be pointless). You would have to match id to id or tractce to tractFIPS. the syntax would be the sameBurglarious
Am I right in assuming any existing data in the updated column would be lost ?Varietal
M
0

You can convert it as you have asked:

UPDATE a SET tractce = b.id FROM b WHERE TRIM(a.tractce) = TRIM(b.tractfips);
ALTER TABLE a ALTER COLUMN tractce TYPE INTEGER USING (a.tractce::integer);
ALTER TABLE a ADD CONSTRAINT a_tractce_b_fk FOREIGN KEY (tractce) 
  REFERENCES b (id) ON UPDATE RESTRICT ON DELETE SET NULL;

but better to rename a.tractce into a.tractce_id

ALTER TABLE a RENAME tractce TO tractce_id;
Metabolism answered 30/4, 2023 at 11:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.