I'm using PostgreSQL 9.1.
I have a table common.client_contact
where I created foreign key using this code:
ALTER TABLE common.client_contact
ADD FOREIGN KEY (contact_id) REFERENCES common.contact_item(id);
If I execute this code, I will get several foreign keys with different names (like client_contact_contact_id_fkey1
, client_contact_contact_id_fkey2
, client_contact_contact_id_fkey3
and so on).
So, before creating new constraint, I need to check if it's exists.
I check if this constraint exists in pg_constraint
table:
SELECT * FROM pg_constraint WHERE conname = 'client_contact_contact_id_fkey'
And now I need to combine them together. Something like
IF NOT EXISTS
(SELECT * FROM pg_constraint WHERE conname = 'client_contact_contact_id_fkey')
ALTER TABLE common.client_contact
ADD CONSTRAINT client_contact_contact_id_fkey
FOREIGN KEY (contact_id) REFERENCES common.contact_item(id)
or just
ALTER TABLE common.client_contact
ADD FOREIGN KEY IF NOT EXISTS (contact_id) REFERENCES common.contact_item(id)
But these two queries are produce syntax error. So, how can I do it in PostgreSQL?
A foreign key is a column (or combination of columns) in a table whose values must match values of a column in some other table. FOREIGN KEY constraints enforce referential integrity, which essentially says that if column value A refers to column value B, then column value B must exist.
Yes, you can have a FOREIGN KEY constraint that references a column with a UNIQUE constraint.
The obvious problem with the lack of foreign keys is that a database can't enforce referential integrity and if it wasn't taken care of properly at the higher level then this might lead to inconsistent data (child rows without corresponding parent rows).
It is completely appropriate and quite normal to have multiple FOREIGN KEYs that refer to the same PRIMARY KEY. They are not the same FOREIGN KEY (they will each build a separate index to use in enforcing the key), they are different FOREIGN KEYs with similar definitions.
Use a DO
block to execute it in PL/PgSQL.
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'client_contact_contact_id_fkey') THEN
ALTER TABLE common.client_contact
ADD CONSTRAINT client_contact_contact_id_fkey
FOREIGN KEY (contact_id) REFERENCES common.contact_item(id);
END IF;
END;
$$;
You seem to be relying on the default constraint name generation, which isn't ideal. It's probably safer to use information_schema
to check for the presence of a constraint that links the two columns.
The following query checks for a foreign key between the two tables without relying on the generated constraint name:
SELECT 1
FROM information_schema.table_constraints tc
INNER JOIN information_schema.constraint_column_usage ccu
USING (constraint_catalog, constraint_schema, constraint_name)
INNER JOIN information_schema.key_column_usage kcu
USING (constraint_catalog, constraint_schema, constraint_name)
WHERE constraint_type = 'FOREIGN KEY'
AND ccu.table_name = 'contact_item'
AND ccu.table_schema = 'common'
AND ccu.column_name = 'contact_id'
AND tc.table_schema = 'common'
AND tc.table_name = 'client_contact'
AND kcu.column_name = 'id';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With