Deleting Data
Remove rows with DELETE FROM ... WHERE, test the WHERE first, and delete in the order the foreign keys allow.
Apprentice · T-SQL · SQL · Updated
After this lesson you can
- Remove rows with DELETE, in an order the foreign keys allow
Key takeaways
DELETE FROMremoves the rows itsWHEREmatches. Without aWHEREit tries to remove every row, and there's no undo.- Test the
WHEREwith aSELECTfirst, then changeSELECT *intoDELETEand keep theWHEREas it was. - Delete in the reverse order of inserting: first the rows that point to a row, such as the order lines, then the order itself.
- Business records are often kept, not deleted: Northwind stops selling a product by updating its
Discontinuedcolumn.
DELETE removes rows from a table.
DELETE FROM <table>
WHERE <which rows>;
As with UPDATE, the WHERE decides which rows go, and without it every row goes.
Deleting what you added
Add a shipper, then remove it:
INSERT INTO Shippers (CompanyName, Phone)
VALUES ('Rapid Delivery', '(503) 555-0110');
DELETE FROM Shippers
WHERE CompanyName = 'Rapid Delivery';
(1 row affected)
(1 row affected)
SELECT first, again
The same habit as for UPDATE: run a SELECT with the same WHERE, check the rows, then change SELECT * into DELETE:
SELECT *
FROM Shippers
WHERE ShipperId = 4;
DELETE FROM Shippers
WHERE ShipperId = 4;
Foreign keys decide the order
Try to delete product 1, Chai:
DELETE FROM Products
WHERE ProductId = 1;
The DELETE statement conflicted with the REFERENCE constraint "FK_Order_Details_Products". The conflict occurred in database "Northwind", table "dbo.OrderDetails", column 'ProductId'.
Chai appears on 38 order lines, and each of them points at product 1 with a foreign key. Deleting the product would leave those order lines pointing at nothing, so the database refuses.
To delete a row that others point to, you first deal with the rows that point to it: delete them, or change them to point somewhere else. The order is the reverse of inserting:
| To insert | To delete |
|---|---|
| the category first, then its products | the products first, then their category |
| the order first, then its order lines | the order lines first, then the order |
For real business data, like Chai and its orders, you usually don't delete at all: the sales happened, and the records matter. That's why Northwind's products have a Discontinued column: you stop selling a product by updating it, not by deleting it.
Deleting everything
DELETE FROM Customers;
Without a WHERE, this tries to delete every customer. (Here, the foreign keys from Orders stop it, but a table nothing points to would simply be emptied.) If you ever really mean to delete every row, write a WHERE that says so, such as WHERE ShipperId > 0, so it's clearly on purpose.
Check yourself
2 questions to try on the lesson page.
So what
A DELETE can't be taken back. Test its WHERE with a SELECT, delete children before parents, and ask whether the row should really be deleted, or only marked as no longer in use.