I am tidying up an Access 2007 database with a central key table whose Primary key is a foreign key in numerous tables (about 20 in all) but the person who set this up obviously did not set up the constraints with DELETE CASCADE because when I attempt to delete a record in the central table I am warned of foreign key relations. Is there a way I can perform a delete and search through all tables deleting the relevant foreign key records. It appears I cannot add DELETE CASCADE without recreating all the referential entegrity
You can edit the relationship between each table by going to database tools -> relationship -> edit the relevant relationship between tables to make it cascade.
Related
EF 5.0 Code First, SQL2012 localdb
I'm dveloping an application that has many lookup tables bound to comboboxes for input. When the db is built EF finds all of the relationships and adds foreign keys where appropriate. So now, as example, I have a table with a number of fields mapped to lookup table entries. If I delete an entry in the table I don't want to cascade delete the mapped entry in the lookup table. How do I protect the lookup table from cascade deletions? I'm using DataAnnotations. Thanks!
Foreign keys work essentially the opposite of the way you seem to think they work. If you delete a row on the "many" side of a 1:M relationship, nothing happens to the table on the "one" side (the lookup table).
If you delete a row from the "one" side (the lookup table), then the delete should cascade to the tables on the "many" side. (As long as those tables have ON DELETE CASCADE as part of their foreign key references.)
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
so i have to tables that have a relation between them - relation type: one to many.
and i thought that the following query:
DELETE Orderstbl.*, ItemsInOrdertbl.*
FROM Orderstbl INNER JOIN ItemsInOrdertbl ON Orderstbl.OrderID = ItemsInOrdertbl.OrderId
WHERE (((Orderstbl.OrderID)=26));
will delete all the rows in both tables that contain the OrderID = 26
but to my surprise it filled the following error :
could not delete from specified tables
tried to find an answer on google , didnt help much thanks in advance :D
You could also create a relationship that includes CASCADE DELETE, then when you delete from one it will delete from the other
from microsoft:
If you select the Cascade Delete Related Records check box when you
define a relationship, any time that you delete records in the primary
table, Microsoft Access automatically deletes related records in the
related table. For example, if you delete a customer record from the
Customers table, all the customer's orders are automatically deleted
from the Orders table (this includes records in the Order Details
table related to the Orders records). When you delete records from a
form or datasheet with the Cascade Delete Related Records check box
selected, Microsoft Access warns you that related records may also be
deleted. However, when you delete records using a delete query,
Microsoft Access automatically deletes the records in related tables
without displaying a warning.
Using the CASCADE DELETE is a simple and clean way to make sure the correct records are removed from both tables.
Here is another article discussing CASCADE DELETE with MS-Access.
Delete one or more records from an Access database
If you have a foreign key set between columns in two tables, you have to be sure to delete the child column first, and then the master. The proper way to do this is to set a constraint upon deletion of the master, such as UPDATE or DELETE. The constraint takes care of the foreign key relations, so you never wind up with orphan rows all over the place.
To create the constraints in MySQL (for example)...
[CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (index_col_name, ...)
REFERENCES tbl_name (index_col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
The other option is to do it programmatically, deleting the row in child tables first, and then the master.
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?
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).