I have two tables that look like the following :
Table 1 :
invoices
Table 2 :
invoice_details
public function deleteInvoice($id='')
{
if( !empty( $id ) ){
$query = "DELETE FROM invoices where uuid ='$id'";
if(mysqli_query($this->_con, $query))return true;
else return false;
}else{
return false;
}
}
Table 2 contains a column called "invoice_id" that relates to the "id" of Table 1
Whenever I remove an invoice using the above function, I also want to remove the invoice_details at the same time. Is there an easy way to modify the above code to do that?
First you need to put a foreign key constraint on invoice_details
ALTER TABLE invoice_details
ADD CONSTRAINT fk_invoice
FOREIGN KEY(invoice_id)
REFERENCES invoices(id)
ON DELETE CASCADE;
Then you can delete your invoice and it will delete the details automatically
Don't modify the code. Have a foreign key relationship between the tables with an ON DELETE CASCADE option.
ALTER TABLE invoice_details ADD CONSTRAINT fk_invoice FOREIGN KEY invoice_id REFERENCES invoices(invoice_id) ON DELETE CASCADE;
Now the database does the job for you.
You could do this using foreign key constraints, forcing a CASCADE on delete. See https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html for additional details.
Related
I'm deleting some rows (users) from a table using the following query
DELETE
FROM
rfs_users
WHERE
ID > 1 AND user_registered < '2017-05-16 12:09:54' AND user_login NOT IN ('username1', 'username2')
I have another table and I also need to delete some rows from it. This table (rfs_usermeta) has a different structure and I can't use the same query on it.
In rfs_users, one row corresponds to one user. In rfs_usermeta, multiple rows corresponds to one user. I could just use
DELETE FROM rfs_usermeta WHERE user_id > 1
but that would delete almost all rows. I need to delete a user in rfs_usermeta if that user is also to be deleted in rfs_users.
For example:
// loop rows in rfs_users
for (row in rfs_users) {
// target specific rows
if (row.user_id > 1 && row.user_registered < '2017-05-16 12:09:54' && !('username1', 'username2').includes(row.user_login)) {
// delete matching row
row.remove()
// also delete rows from rfs_usermeta
rfs_usermeta.getRows(row.user_id).remove()
}
}
How do I form this query?
Does the usermeta have a Foreign Key Constraint to the users table? If so you can set what happens in the referenced row.
You can automatically remove corresponding rows by adding the foreign key constraint to the usermeta like this:
ALTER TABLE usermeta ADD CONSTRAINT FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
This removes all usermeta rows that reference a removed user.
If you do not want to do that you can also add a Trigger to the user table that removes usermeta rows.
Hope this helps ;)
Run this alter.On delete cascade will automatically take care of this.
alter table rfs_usermeta modify constraint fk_name foreign key (user_id) references rfs_users (ID) on delete cascade;
I have one table referencing another. As I see - there are two ways to delete cascading:
What is the difference between CREATE TRIGGER BEFORE DELETE and FOREIGN KEY ON DELETE? Are there any differences in performance?
I came up with this advantage of FOREIGN KEY:
The cascading delete is more obvious because it's attached in the table definition.
Full question:
I have the two tables:
project(id, ...) <- works_on(id, project_id, ...)
What are the differences in
CREATE TABLE works_on (
...
FOREIGN KEY (project_id) REFERENCES project ON DELETE CASCADE
...
);
and
CREATE TRIGGER trigger_delete_cascading
BEFORE DELETE ON project
DELETE works_on
WHERE project_id = id;
A FOREIGN KEY will restrict values that can be stored in the project_id column of the works_on table. You will not be able to set a value that does not exist in the project table.
A TRIGGER does not restrict the range of values that can be stored.
If wrote trigger BEFORE delete,will DELETE record from CHILD TABLE and due to some Server error or Other constraint if record is unable to delete from MAIN TABLE(PARENT) then it makes redundant data.
So whenever you required delete plus more action like maintaining LOG table then only you have to go with Trigger.Otherwise ON DELETE CASCADE is great to work.
Hope this will helps you.
I'm working on a little support (ticket) system. My tables are tickets and ticket_replies.
Design of tickets table is
id|user_id|title|...
Design of ticket_replies looks like:
id|ticket_id|...
The foreign key I added looks like this:
ALTER TABLE `ticket_replies` ADDFOREIGN KEY (`ticket_id`)
REFERENCES `sampleauth`.`tickets`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
Now when I delete a "ticket" in the "ticket" table it gets deleted in "ticket_replies" too. The other way this doesn't work, all in all I would like this to work the other way too, so my database has all the time consistency. How to do so?
Add this trigger will delete its primary key when you try to delete foreign key
CREATE TRIGGER `ticket_replies_BEFORE_DELETE` BEFORE DELETE ON `ticket_replies` FOR EACH ROW
BEGIN
DELETE FROM tickets WHERE id = OLD.ticket_id;
END
Although there are some similar questions about the subject, I can't find the right answer for my problem. I have 2 tables called customer and car. What I want to do is this: When I delete a customer from database, I want the car that belongs to that customer will be automatically deleted as well. The code that MySQL Workbench generated for me is this:
ALTER TABLE `autocare`.`car`
ADD CONSTRAINT `customerId`
FOREIGN KEY (`CUSTOMER_ID`)
REFERENCES `autocare`.`customer` (`ID`)
ON DELETE CASCADE
ON UPDATE RESTRICT;
And I get this error:
ERROR 1452: Cannot add or update a child row: a foreign key constraint fails
(`autocare`.`#sql-80c_388`, CONSTRAINT `customerId` FOREIGN KEY (`CUSTOMER_ID`)
REFERENCES `customer` (`ID`) ON DELETE CASCADE)
There was no relation between those tables before. Any ideas? Thanks in advance!
Your goal is ultimately to implement a cascading deletion from customer to car. When you attempt to add the constraint with the tables as they are now, it fails because the car table must include rows having a a CUSTOMER_ID value which does not currently exist in the parent customer table.
You should first locate those orphan rows and delete them (since your goal is to delete them anyway). You can find them with a query like:
SELECT *
FROM car
WHERE
CUSTOMER_ID NOT IN (SELECT ID FROM customer)
Once the orphan records are removed, the foreign key constraint can be met by the remaining existing rows and your ALTER TABLE statement will succeed.
I have a table called custom_carts and I have a table called custom_cart_items.
custom_cart_items has a foreign key called custom_cart_id that is set to custom_cart.id
According to the Cake Manual, when you call Model->delete() the first param is the id of the entry you want to delete and the second param is whether or not to cascade delete the dependent entries.
So when I call $this->CustomCart->delete(7,true) I get this error:
SQL Error: 1451: Cannot delete or
update a parent row: a foreign key
constraint fails
(`krake`.`custom_cart_items`,
CONSTRAINT `custom_cart_items_ibfk_1`
FOREIGN KEY (`custom_cart_id`)
REFERENCES `custom_carts` (`id`))
Here is the query:
DELETE `CustomCart`
FROM `custom_carts` AS `CustomCart`
LEFT JOIN `users` AS `User`
ON (`CustomCart`.`user_id` = `User`.`id`)
WHERE `CustomCart`.`id` = 25
Shouldn't it cascade and dlete the other entry too?
So why am I getting an error?
You must set the dependent parameter to true in the model with the hasmany relationship in order to enable cascading deletion.
Your model would look something like this:
class CustomCart extends AppModel {
var $name = 'CustomCart';
var $hasMany = array(
'CustomCartItem' => array(
'dependent'=> true
)
);
}
Please see http://book.cakephp.org/view/82/hasMany
Just adding fields to a table (regardless of the field name) does not tell CakePHP that they're associated, nor does it link them for cascading deletion.
You need to set the associations in your model: SEE DETAILS HERE.
On the other hand, if you want to delete a record from a table A, and there is another table B which as a FOREIGN KEY constraint on table A, you must set the option on that foreign key of the table B in the Database like this
"SET NULL ON DELETE".
I usually do this in MySqlWorkbench, but you can also use legacy SQL queries to create a table with such an option.