From: | David Fetter <david(at)fetter(dot)org> |
---|---|
To: | PostgreSQL General <pgsql-general(at)postgresql(dot)org> |
Subject: | Each foo must have a bar |
Date: | 2006-02-11 20:56:36 |
Message-ID: | 20060211205636.GA6106@fetter.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
Folks,
I'm trying to figure out how to enforce the following. Table foo has
a primary key. Table bar has a foreign key to foo. So far so good.
I'd also like to say, "for each row in foo, there must be at least one
row in bar."
I've tried the following, but the check fails too soon. I also tried
an INITIALLY DEFERRED foreign key on bar to foo, trying the INSERT on
bar first, but that didn't work in transaction_isolation LEVEL
SERIALIZABLE.
Any clues?
Cheers,
D
CREATE TABLE foo (
id SERIAL PRIMARY KEY
);
CREATE TABLE bar (
foo_id INTEGER NOT NULL REFERENCES foo(id)
ON DELETE CASCADE
INITIALLY DEFERRED
);
CREATE FUNCTION foo_trg ()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
DECLARE
childless_foo_count INTEGER;
BEGIN
SELECT INTO
childless_foo_count
COUNT(*)
FROM
foo
LEFT JOIN
bar
ON (foo.id = bar.foo_id)
WHERE bar.foo_id IS NULL;
IF childless_foo_count > 0 THEN
RAISE EXCEPTION 'Each foo must have at least one bar.';
END IF;
RETURN NULL;
END;
$$;
CREATE TRIGGER foo_after
AFTER INSERT OR UPDATE ON foo
FOR EACH STATEMENT
EXECUTE PROCEDURE foo_trg();
--
David Fetter david(at)fetter(dot)org http://fetter.org/
phone: +1 415 235 3778
Remember to vote!
From | Date | Subject | |
---|---|---|---|
Next Message | Michael Fuhr | 2006-02-11 21:59:48 | Re: Each foo must have a bar |
Previous Message | Johan Vromans | 2006-02-11 20:26:57 | Re: Last modification time |