Consider the following table structure (which I have shamelessly nicked from this excellent answer):
categories: products:
+----+------+ +----+---------+
| id | name | | id | name |
+----+------+ +----+---------+
| 1 | red | | 1 | mittens |
| 2 | blue | | 2 | boots |
+---++------+ +----+---------+
products_categories:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 1 | 2 | // blue mittens
| 2 | 1 | // red boots
| 2 | 2 | // blue boots
+------------+-------------+
The foreign keys for products_categories
in this scenario are set up as ON DELETE CASCADE
, so when I DELETE FROM categories WHERE id = 2;
all records having 2
as their category_id
will get deleted.
Suppose I alter the foreign key for the category to ON DELETE RESTRICT
(which seems to be the default value anyway). Deleting any record from categories
will now fail, as long as there is a record in products_categories
which references the record in question.
Is there any way to determine if a DELETE
on a specific record will fail? The DB clearly is able to evaluate this as part of the DELETE
query.
I have a program (C#) which might want to delete a record from a table that is fenced in by a RESTRICT
constraint. At the moment I have to try { } catch(Exception ex) { }
the DELETE
query, which will throw an exception if the record cannot be deleted due to constraints. I feel that this kind flow control through exceptions for this task is not a good practice, and it seems that there is no obvious way around it. Or is there?
I can see, that having an opportunity to query the database if a record can be deleted, might introduce a lot of concurrency issues (Suppose the record cannot be deleted and right after I get my (negative) result, another user deletes the final record that made the test fail. I then have invalid information about the state of the database on my hands.
I consulted this and that neither of which gave me a satisfactory answer.