I’m new to PostgreSQL. I have tables like:
CREATE TABLE Person (
ID SERIAL PRIMARY KEY,
Name VARCHAR(32) NOT NULL DEFAULT '',
Surname VARCHAR(32) NOT NULL DEFAULT '',
Birthday DATE,
Gender VARCHAR(8)
);
-- Student table inherits from person
CREATE TABLE Student (
ID_Student SERIAL PRIMARY KEY,
MajorDept VARCHAR(32),
) INHERITS(Person);
-- Student table inherits from person
CREATE TABLE Employee (
ID_Employee SERIAL PRIMARY KEY,
Position VARCHAR(32),
Rank VARCHAR(32),
Salary NUMERIC(12,2)
) INHERITS(Person);
-- Address table references person
CREATE TABLE Address (
ID_Address SERIAL PRIMARY KEY,
Person_id INTEGER REFERENCES Person(ID) NOT NULL,
Email VARCHAR(32) UNIQUE,
Country VARCHAR(32),
CityCode INTEGER,
City VARCHAR(32),
AddressLine VARCHAR(60),
);
According to these tables, when I want to INSERT data into Adress table, Postgres gives that error:
ERROR: insert or update on table “address” violates foreign key
constraint “address_person_id_fkey” DETAIL: Key (person_id)=(1) is
not present in table “person”.
I’ve learned that in Postgres
indexes (including unique constraints) and foreign key constraints
only apply to single tables, not to their inheritance children.
My question is how can I fix this with using triggers? Sample code would be very useful.
After inserting a few rows to child tables, I can see the data with ‘SELECT * FROM Person;’ as well. It looks like:
Person Table
1;"Bill";"Smith";"1985-05-10";"male"
2;"Jenny";"Brown";"1986-08-12";"female"
3;"Bob";"Morgan";"1986-06-11";"male"
4;"Katniss";"Everdeen";"1970-08-12";"female"
5;"Peter";"Everdeen";"1968-08-12";"male"
Student Table
1;"Bill";"Smith";"1985-05-10";"male";1;"chemistry"
2;"Jenny";"Brown";"1986-08-12";"female";2;"physics"
3;"Bob";"Morgan";"1986-06-11";"male";3;"physics"
Employee Table
4;"Katniss";"Everdeen";"1970-08-12";"female";1;"Prof";"1";3500.00
5;"Peter";"Everdeen";"1968-08-12";"male";2;"Assist-Prof";"5";1800.00
First get rid of the FK with something like this:
If that complains about there not being an
address_person_id_fkeyconstraint then use\d address;inpsqlto find out what the FK is called.Then a simple trigger like this should do the trick:
And attach it like this:
Then you’ll get an error like this if you try to add an address for someone that doesn’t exist in
person(including the tables that inherit from it):You’d want to add a BEFORE DELETE trigger to
personto avoid dangling references, that basic structure would be pretty much the same. You might want an index onaddress.person_idto help support the BEFORE DELETE trigger as well.References:
RAISE