How to Delete a Row from multiply tables in sql? - sql

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.

Related

How do I automatically delete all associated components while deleting a product in a SQL relational database?

Is this possible?
If so, does it happen automatically or do I need to config the definition of the foreign key in the component table properly?
The foreign key(s) would need to be defined as ON DELETE CASCADE in order for this to occur. Generally I'd recommend against such a setting because can you imagine (say) deleting a row from your GENDER table and suddenly discovering that half of the millon rows in your CUSTOMER table just vanished, and similarly half of the 100 million rows in your CUSTOMER_SALES tables also went.... That's a career limiting move.
If the foreign keys are not defined as ON DELETE CASCADE you could still mine the data dictionary to wor out the relationships in order to build a "delete child before parent" mechanism for those rare scenarios where you might need this

Delete rows from binding source with foreign key

I have a DataSource with 2 tables one projectDiamter and other diameterSet. ProjectDiameter id contains primary key and diameterset has foreign key constraint with same key.
Now when I select row from projectdiameter table diameterset DataGridView get filtered accordingly. I have lots of rows in diameterset (lets say 15000 for selected project only) which I want to delete when delete button is pressed.
I wanted to know which is the fastest way to delete it from DataGridView and SQL table.
I tried following code but wanted to check if there is any better way of getting the same.
FKProjectDiameterBindingSource.MoveFirst()
For j As Int16 = 0 To FKProjectDiameterBindingSource.Count - 1
For i As Int16 = 0 To FKDiameterDiameterSetBindingSource.Count - 1
FKDiameterDiameterSetBindingSource.Clear()
FKDiameterDiameterSetBindingSource.MoveFirst()
FKDiameterDiameterSetBindingSource.RemoveCurrent()
Next
FKProjectDiameterBindingSource.MoveNext()
Next
Me.Validate()
DiameterTableAdapter.Update(RSM3DDB1.Diameter)
DiameterSetTableAdapter.Update(RSM3DDB1.DiameterSet)
Does the foreign key relationship exist formally in the database? That is, is there an actual relationship defined in SQL? If so, I'd suggest setting that relationship to CASCADE DELETE and then all you have to do is call DiameterSetTableAdapter.UPDATE after you update Diameter.
A good explanation on CASCADE DELETE is here
https://www.mssqltips.com/sqlservertip/2365/sql-server-foreign-key-update-and-delete-rules/ Note that the keyword is just "Cascade" but you apply it to DELETE, the article explains ("It is not necessary that the same rule be applied for both update and delete operations. There may be different rules for each of the update and delete operations on a single FK constraint.")
If the relationship isn't formal, that is it logically exists but isn't enforced, then I'd put a trigger on the Diameter table and in that trigger delete all the rows in DiameterSet where the DiameterID equals the deleted DiameterID. Note that in a trigger a row that is modified (as opposed to deleted) will be in both the INSERTED and DELETED temporary tables, so you have to take steps to make sure you're not removing rows that reference a modified Diameter.
If you take this second approach, you can still just run the 2 UPDATE procedures on the 2 table adapters in VB, it's just more coding in SQL than setting the CASCADE DELETE.
Both approaches are MUCH more efficient than doing it in VB, and it can add up if you have hundreds of rows affected.
Using either of these also has the advantage of being atomic, whereas your approach is not.

Not to delete child record when parent deletes

I do have a sql table where Table B has a one-to-many foreign key relationship with table A id. I do not want the table B records to be deleted if table A relative parent record is deleted. I have tried CASCADE and NO ACTION at delete & update but nothing gives a solution other than removing the foreign key constraint. Is there another way I can have a work around without removing the constraint?
I didn't hear of any way to have a foreign key constraint and keep the record on the child table after it was deleted from the parent table. Thats why its called constraint, its a rule that cannot be broken.
I can suggest another thing, instead of deleting the record, make it unavailable. Add a date field or an indication feild, that will tell you this record is out of order.

Delete Across Tables MS Access

I am trying to delete records in two different tables. I get the error message:
Specify the table containing the records you want to delete.
The table MSShipment will be the reference source for the records I would like to delete across both tables.
DELETE MSShipment.BoxNumber AS MSShipment_BoxNumber, MedicalSort.BoxNumber AS MedicalSort_BoxNumber
FROM MSShipment
INNER JOIN MedicalSort
ON MSShipment.[BoxNumber] = MedicalSort.[BoxNumber];
You should consider setting up referential integrity with cascade deletes between MSShipment and MedicalSort.
This way when you delete the record from MSShipment, all of the detail records in Medical Sort are deleted.
This will happen all the time throughout your application.

How can I delete records from a table when there are foreign keys that depend on these records?

I have lots of tables that have foreign keyed to a PersonId column. I need to delete a person from the database.
If I do a simple:
DELETE FROM Persons WHERE PersonId=111
I get an error:
Msg 547, Level 16, State 0, Line 1
The DELETE statement conflicted with the REFERENCE constraint "FK_CIPerson". The conflict occurred in database "adb", table "CI", column 'Person_Id'.
I keep going "down the tree" of dependencies and delete from the roots. This has generally worked, until I got to a certain table where it won't let me delete any further. I believe I have to join 2 tables and delete the rows in BOTH tables that have my PersonId in it.
This join joins the tables in the way I want them to be joined:
SELECT *
FROM Table1
INNER JOIN Table2 ON Table1.anId = Table2.someId
This results in a joined table that has the PersonId (from Table2). I now want to delete all the rows where PersonId=111, so I need a where clause plonked in too.
Thanks in advance!
By definition, SQL DELETE statement only affects one table. If you need to cascade delete, you can simplify things by using #paqogomez suggestion: just specify ON DELETE CASCADE option on the foreign key declaration.
There are at least 3 solutions:
ON CASCADE DELETE
(As answered by Gerardo) If the problem is just foreign key constraints, then you can use this and deleting the person will do all the rest. But this may not always work. As usr said, there are some cases in which foreign keys are complex and mangled a bit.
BEFORE DELETE TRIGGER
You can define a trigger and activate it BEFORE DELETE on the person table. In the trigger you can take care of the deletion of dependent rows from other tables. This is similar to the ON CASCADE DELETE, but you have a little more control over how to perform the deletion... this may solve some of those complex problems.
STORED PROCEDURE
You can define a stored procedure with a person_id parameter. The code would be similar to the trigger's. But in stored procedures you can sometimes do some extras, like deactivating foreign keys (not sure about SQL Server though).
DELETION SCRIPT
This is the most powerful, as you can mix DDL and SQL and do all sorts of stuff. But scripts usually have to be run manually, which might not be acceptable in your case.