Delete Multiple Entires In SQL With Other Tables Using The Data As Foreign Keys - sql

I have several tables which reference one main table using foreign keys.
My goal is for one blanket delete statement from the main table, which will then delete all those with the data as foreign keys as well.
However I get constraint errors as I expect since the reference is deleted before its deleted from the other tables. Is there any way to tell SQL I would like to delete from all tables where the data is used as a foreign key as well?

To have deletes on the parent table cascade to referencing tables, use an ON DELETE CASCADE foreign key. However, if you're deleting all rows from the main table there's a better way to solve your problem using TRUNCATE; see the end of this post.
You can ALTER TABLE to change a default ON DELETE NO ACTION foreign key to ON DELETE CASCADE. Drop the constraint then re-create it with the ON DELETE CASCADE modifier. See CREATE TABLE and the constraints documentation for information on the foreign key constraint syntax.
In brief, instead of col coltype REFERENCES fktable(fkcol) you use col coltype REFERENCES fktable(fkcol) ON DELETE CASCADE.
If you use ON DELETE CASCADE then to get even vaguely decent performance it is vital to create an index on the foreign key column. Even then, for bulk deletes from the target table it's often much faster to go and delete from each foreign key referencing table first, rather than relying on cascades.
You may want to also use ON UPDATE CASCADE if you're using ON DELETE CASCADE.
If you're deleting all rows from the main table, not just a selection of them, you're probably better off truncating the tables with TRUNCATE ... CASCADE:
CASCADE
Automatically truncate all tables that have foreign-key references to
any of the named tables, or to any tables added to the group due to
CASCADE.

The only way to have a DELETE cascade to tables with a foreign key linked to the table you are running your statement on is to have the ON DELETE CASCADE option set on the key, you will need to run an ALTER TABLE statement to change them from their current value to this option:
http://www.postgresql.org/docs/current/interactive/ddl-constraints.html

Related

Linking Two Foreign Keys to one Primary Key

I have two tables, a Photographer and an Influences table. In the Influences table, a Photographer is able to influence another Photographer.
Relational Schema:
Here is my Diagram in SQL:
Instance Example:
My issue is when I try to delete Photographer Tom, since he influences Jason (as shown in Influences table), I get a error stating:
The DELETE statement conflicted with the REFERENCE constraint "FK_Influences_Photographer1". The conflict occurred in database "jma59", table "dbo.Influences"
If Tom was in the column EPName of the Influences table, I have no issue deleting it. I know that this is a foreign key issue but I am not sure how to handle this situation. I created two separate foreign keys that reference to the Photographer primary key. But the problem is that I cannot make it so that both foreign keys cascade on update and delete.
First foreign key is EPName and EPBDate referencing to PName and PBDate of Photographer
Second foreign key is RPName and RPBDate referning to PName and PBDate of Photographer as well.
The error is:
Unable to create relationship 'FK_Influences_Photographer1'. Introducing FOREIGN KEY constraint 'FK_Influences_Photographer1' on table 'Influences' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Any advice is greatly appreciated!
You could consider using a Trigger rather than a cascading delete to enforce referential integrity: https://support.microsoft.com/en-gb/help/321843/error-message-1785-occurs-when-you-create-a-foreign-key-constraint-tha

Is there any way to generate a cascade delete statement?

Let's say I have a row in Table A I wish to delete but there a multiple foreign key constraints in other tables. Is there a way to automatically generate the delete command?
I think a tool that would recursively look at the foreign keys and in turn generate a delete statement to take care of all foreign keys should exist, but I can't find one.
I'm on MSSql server2008
When setting up your Foreign Key relationships there is an ON DELETE CASCADE you can add.
MSDN Cascading Referential Integrity Constraints
ON DELETE CASCADE
Specifies that if an attempt is made to delete a row with a key referenced by foreign
keys in existing rows in other tables, all rows containing those foreign keys are also
deleted. If cascading referential actions have also been defined on the target tables,
the specified cascading actions are also taken for the rows deleted from those tables.
SO even has a solution where you are not adding it to the table:
In SQL Server 2005, can I do a cascade delete without setting the property on my tables?

Is it possible to alter the cascading behaviour of existing mysql foreign keys?

I have two tables in mysql, both are type InnoDB and there is an existing foreign key from the first to the second.
However, the foreign key was created without any cascading behaviour. The table is large, and any changes to indexes or new keys locks the table for ~20 minutes.
Is it possible to add "ON DELETE CASCADE" behaviour to an existing foreign key without dropping the key and recreating it?
Unfortunately, no. On Delete and On Update are systemic attributes of the foreign key itself and can only be specified when creating the constraint.

Changing a record in a table (sql server) that has foreign keys?

Does anyone know if there is a quicker way of editing a record that has foreign keys in a table (in sql server).. i will explain.. i have approx 5 tables that have there own ID but are linked together using a foreign key...
Hence i needed to change the foreign key (the contract number in my case), but i had to copy each record to a new record and edit it that way...
As if i try to edit the contract number it gives me the standard error of being associated and violates a foreign key etc
Surly there must be a better way?
ANy ideas?
are you talking about changing the PK and then updating all the Fks? In that case enable cascade updates and this will be done automagically
same with deletes, you enable cascade deletes
ON DELETE CASCADE
Specifies that if an attempt is made to delete a row with a key referenced by foreign keys in existing rows in other tables, all rows containing those foreign keys are also deleted. If cascading referential actions have also been defined on the target tables, the specified cascading actions are also taken for the rows deleted from those tables.
ON UPDATE CASCADE
Specifies that if an attempt is made to update a key value in a row, where the key value is referenced by foreign keys in existing rows in other tables, all of the foreign key values are also updated to the new value specified for the key. If cascading referential actions
I'm not an SQL expert, but can't you set something like ON UPDATE CASCADE to automatically update the foreign key when the primary key is changed?
Or try disabling the integrity constraint, do your changes and attempt to re-enable the constraint. Basically, if you didn't do it right you will get an error then (can't enable a constraint that would be violated).

How do I clear a table with a lot of references in oracle?

For instance, suppose I have table A. Then I have tables B-Z that have a foreign key to table A's primary key. Then perhaps there are also some tables that have a foreign key constraint to a table in B-Z's primary key constraint. Is there any easy way to clear out table A and all of the tables that refer to A (or that refer to a table that refers to A) without having to explicitly delete from each table or add an ON CASCADE constraint to each foreign key?
Note that this is mainly for testing purposes, not to be used in production. I would just drop the entire schema and start over again, but that simply isn't feasible for every test (considering how long it takes to build the schema).
I think the most efficient way to do this would be to drop all the FK's, truncate the tables, and then rebuild the FK's.