Why do I get this error when the table I'm inserting into is empty? A previous iteration of the table (since dropped) had a serial, so I wondered if Postgres was caching the old table schema?
Here's the error:
-- Executing query:
DELETE FROM student
WHERE sno =101;
ERROR: duplicate key value violates unique constraint "cancel_pkey"
DETAIL: Key (eno, cdate)=(1, 2014-12-08 21:21:53.710883) already exists.
CONTEXT: SQL statement "INSERT INTO cancel(eno,excode,sno)
SELECT eno, excode, sno
FROM entry
WHERE eno = OLD.eno"
PL/pgSQL function cancel_entry() line 3 at SQL statement
SQL statement "DELETE FROM entry
WHERE sno = OLD.sno"
PL/pgSQL function delete_student() line 8 at SQL statement
The actual insert query takes place within a trigger which looks like this:
CREATE OR REPLACE FUNCTION delete_student()
RETURNS trigger AS $BODY$
BEGIN
IF (SELECT EXISTS (SELECT * FROM entry WHERE sno = OLD.sno)) THEN
INSERT INTO cancel(eno,excode,sno)
SELECT eno, excode, sno
FROM entry
WHERE sno = OLD.sno;
DELETE FROM entry
WHERE sno = OLD.sno;
END IF;
RETURN OLD;
END; $BODY$
LANGUAGE plpgsql;
CREATE TRIGGER DeleteStudent
BEFORE DELETE ON student
FOR EACH ROW
execute procedure delete_student();
The cancel
table schema looks like:
CREATE TABLE cancel (
eno INTEGER NOT NULL,
excode CHAR(4) NOT NULL, --not unique as many instances of cancellations for exam
sno INTEGER NOT NULL, --not unique as student may cancel several exams
cdate TIMESTAMP NOT NULL DEFAULT NOW(),
cuser VARCHAR(128) NOT NULL DEFAULT CURRENT_USER,
PRIMARY KEY(eno,cdate)
-- sno is not a foreign key, as it must still exist even where student is deleted.
);
And the entry
table schema is:
CREATE TABLE entry (
eno INTEGER NOT NULL DEFAULT NEXTVAL('eno_sequence'),
excode CHAR(4) NOT NULL,
sno INTEGER NOT NULL,
egrade DECIMAL(5,2) CHECK(egrade BETWEEN 0 AND 100),
PRIMARY KEY(eno),
FOREIGN KEY(excode) REFERENCES exam MATCH FULL ON DELETE RESTRICT,
FOREIGN KEY(sno) REFERENCES student MATCH FULL ON DELETE RESTRICT --handle with stored procedure to retain student reference in cancel table
);
'student' table schema
CREATE TABLE student (
sno INTEGER NOT NULL,
sname VARCHAR(20) NOT NULL,
semail VARCHAR(20) NOT NULL,
PRIMARY KEY(sno)
);