Re: Delete all records NOT referenced by Foreign Keys

From: "D(dot) Dante Lorenso" <dante(at)lorenso(dot)com>
To: Stephan Szabo <sszabo(at)megazone(dot)bigpanda(dot)com>
Cc: Martijn van Oosterhout <kleptog(at)svana(dot)org>, Bruno Wolff III <bruno(at)wolff(dot)to>, pgsql-general(at)postgresql(dot)org
Subject: Re: Delete all records NOT referenced by Foreign Keys
Date: 2003-12-14 09:02:49
Message-ID: 3FDC2739.2040408@lorenso.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Stephan Szabo wrote:

>On Sun, 14 Dec 2003, D. Dante Lorenso wrote:
>
>
>
>>PG already can block a delete when it knows that foreign key exists, so
>>why can't I perform a query that says...
>>
>> DELETE FROM tablename
>> WHERE FOREIGN_KEY_EXISTS(oid) IS FALSE;
>>
>>
>
>That's fairly different from the checks that are performed for the foreign
>keys which happen after the action has happened and errors to prevent the
>action from being visible. The where clause happens long before that. If
>the above has to check each referencing table for matching rows for each
>row in tablename, I'd also expect it to perform poorly.
>
>
My hope was that there was some sort of (semaphore? / counter?) associated
with each row that indicated whether a dependency existed at all. Although
that would most likely not be an indexed column, I could apply additional
WHERE constraints to avoid a full table scan.

If such a counter existed, it would certainly speed up deletes when no
foreign
key checks were necessary. But I suppose it would also slow down
deletes when
it becomes necessary to decrement a counter for the dependencies created
by the
row being deleted.

So...internally, how does a row KNOW that it can not be deleted because of
a foreign key constraint? Whatever that mechanism is, isn't there a way for
me to make use of that as I try my query?

And... if not...how about something like this in PL/SQL:

-- Find all the address records which might need to be removed...
FOR my_rec IN
SELECT addr_id
FROM address
WHERE acct_id = in_acct_id
AND addr_is_active IS FALSE
LOOP

-- try to delete this record...
DELETE FROM address
WHERE addr_id = my_rec.addr_id;

END LOOP;

This will loop through the records one at a time and try to delete them.
However, I don't want to have any exceptions thrown if the DELETE action
can not be performed. Is there a TRY/CATCH type of code that I can
surround the DELETE with to prevent the entire operation from being
aborted on the first error found?

Dante

----------
D. Dante Lorenso
dante(at)lorenso(dot)com

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Martijn van Oosterhout 2003-12-14 09:34:18 Re: Delete all records NOT referenced by Foreign Keys
Previous Message Greg Stark 2003-12-14 08:53:26 Re: Delete all records NOT referenced by Foreign Keys