How do I delete rows from different tables atomically?
Table A has a primary key and foreign key into Table B.
The standard solution is to use ON DELETE CASCADE for your constraint.
Search for 'cascade' on that page.
If that is not an option, this SO question may interest you: In SQL Server 2005, can I do a cascade delete without setting the property on my tables?
Related
I am using EF Core 6.0. When I delete the parent row, I would like to not take action(remove or setnull foreign key column) child row and remanining child row and foreign key column's value.
I tried NoAction behavior but NoAction is the same with Restrict behavior.
Delete NoAction and Delete Restrict are, almost, the same thing. See the important part: "both of these options cause referential constraints to be enforced".
In a relational database, referential constraint (or referential integrity) means that a value in a foreign key should exist on the referenced table, they cannot be a value in a foreign key that not exists in the referenced table. (Thank you, #IvanStoev, about notice me to include this content)
Quoting Impact on database schema MS docs:
The behaviors of ON DELETE NO ACTION (the database default) and ON DELETE RESTRICT in relational databases are typically either identical or very similar. Despite what NO ACTION may imply, both of these options cause referential constraints to be enforced. The difference, when there is one, is when the database checks the constraints. Check your database documentation for the specific differences between ON DELETE NO ACTION and ON DELETE RESTRICT on your database system.
SQL Server doesn't support ON DELETE RESTRICT, so ON DELETE NO ACTION is used instead.
The only values that will cause cascading behaviors on the database are Cascade and SetNull. All other values will configure the database to not cascade any changes.
The following table shows the result of each OnDelete value on the foreign key constraint created by EF Core migrations or EnsureCreated:
DeleteBehavior
Impact on database schema
Cascade
ON DELETE CASCADE
Restrict
ON DELETE RESTRICT
NoAction
database default
SetNull
ON DELETE SET NULL
ClientSetNull
database default
ClientCascade
database default
ClientNoAction
database default
I have a DataSet with multiple tables the source document is an XML file.
mydataset.ReadXML(filename);
There are multiple tables with multiple relations. I have the database in the SQL created via code - tables, columns and relations.
Now I would like to insert the data . (Yes I want everything).
EDIT: The SQL tables use Identity Columns autogenerate - because I am not sure the incoming data will never duplicate one of the parameters that I would like to assume is unique.
So what methods should I do to ensure data is input considering I have foreign key constraints , how should I iterate the the tables in the dataset to make sure I don't try to insert in tables requiring an existing id. Do I create a hard coded map (I prefer not too) , or do I walk the tables looking for a Foreign key and verify the parent table etc..
Any Ideas ? I am sure someone has done this before and has a simple answer for me.
You have a couple of options. Assuming the database is not generating the key values, this is pretty simple. Either
1) You discover the order to load the tables so that each table with a Foreign Key is loaded after the table to which it refers.
2) You turn off constraint checking in SqlBulkCopy, and then optionally check the constraints after loading.
To check the constraints after load, run a command like
alter table SomeTable with check check constraint fk_SomeTable_OtherTable
If you do have database-generated keys, this is all harder. But the best way to tackle that is to use SEQUENCE objects isntead of IDENTITY columns and run sp_sequence_get_range to fetch the new key ranges to the client and apply the keys there first.
My team are using SqlMetal to generate database classes from a SqlServer database. It works perfectly for all of our existing classes and foreign key associations but it's refusing to generate the code for a particular new foreign key association that we want to add. This key is from an audit table to a global event table detailing the time the audit record was created and the user it was created by. Many similar foreign key associations between other audit tables and this global "event" table exist in the system and SqlMetal generates code for those associations.
I've tried resolving this problem by:
Dropping and recreating the table
Removing the primary key
Creating a new identical table with a different name
Removing all other fields from the table
Dumping the indexes
Performing a fresh database build
Renaming the foreign key
None of the above seem to resolve the problem. However, SqlMetal does correctly generate code for foreign key associations from this table to some (but not all) other tables in the system. The association between these two tables would only generate when I altered the original create table script to include the foreign key association rather than running it (or a new equivalent table) in later. Unfortunately, we need to be able to deploy this change as a script to our existing production database so this isn't an option. I've seen a couple of articles and forum posts mentioning similar problems but none seem to give any solution or even an explanation.
I created a table in SQL that just contained 2 foreign keys, Which Linked a single Bulk upload entry to many titles. After updating my edmx model.
I noticed there is no table in the diagram.
Just an Association mapped between my title table and my bulkupload table.
There is no table in the diagram so I cannot delete the table.
I cannot add things to the table because there is no connection in the C# Code. '
Does anybody have information on why this is happening and how I can fix and add this table so its able to add entries to it?
You can leave it as an association if you'd like. To add things to you junction table you add things to your Icollection so in pseducode:
BulkEntry.Titles.add(TitleToAdd)
During data transfer i want to disable/enable
All foreign keys on table
All foreign keys on all tables
via query in MSAccess.
I will call query it from C# Module. There will be bulk insertion.
You could delete your relationship from MSysRelationships do your stuff, make sure it is all valid then recreate the record in MSysRelationships.
This seems difficult though. You're knowingly putting bad data into a table with constraints. Why not put your data into a temp table with the same design as your table with the constraints then use an insert query to move the records in to the canonical table according to the rules you've established in the relationships. That way you don't ever drop relationships and risk ruining your table with bad data.