I have two tables. table a references table b I believe.
When I try to delete the package alltogether like this:
$query="DELETE a, b FROM classified as a, $sql_table as b WHERE a.ad_id = '$id'
AND a.classified_id = b.classified_id AND a.poster_password='$pass'";
b MUST be deleted first I guess.
Even in PhpMyAdmin I cant delete a if b is still there, so I delete b first.
But what decides the order in which comes first?
The tables are alla InnoDB.
What should I do?
Thanks
The MySQL manual says about multi-table DELETE and foreign keys:
If you use a multiple-table DELETE
statement involving InnoDB tables for
which there are foreign key
constraints, the MySQL optimizer might
process tables in an order that
differs from that of their
parent/child relationship. In this
case, the statement fails and rolls
back. Instead, you should delete from
a single table and rely on the ON
DELETE capabilities that InnoDB
provides to cause the other tables to
be modified accordingly.
So that when a record in your main table is deleted, so are its foreign references, e.g:
ALTER TABLE products
ADD CONSTRAINT fk_supplier
FOREIGN KEY (supplier_id, supplier_name)
REFERENCES supplier(supplier_id, supplier_name)
ON DELETE CASCADE;
Your Delete syntax is invalid. You need to do this in two statements (unless as nuqqsa mentioned, you have CASCADE DELETE enabled on the relationship between table a and table b):
Delete From b
Where Exists (
Select 1
From a
Where a.poster_password = '$pass'
And a.ad_id = '$id'
And a.classified_id = b.classified_id
)
Delete From a
Where a.poster_password = '$pass'
And a.ad_id = '$id'
What decides which comes first is the foreign keys relationships. Whichever table is the parent table must be deleted from last.
Related
I am new and don't know how to code well, but I want to modify the system.
TARGET: When I delete the 'id' from the students table it will also delete 'userid' from the voters table.
SCREENSHOT OF DB:
students TABLE
voters TABLE
HERE IS CODE I AM USING. (THIS CODE ONLY DELETE THE ROWS ON students TABLE)
I have tried using another query but nothing happened. Can someone please fix the code for me? I am new to this.
<?php ob_start();
session_start();
if (!isset($_SESSION['id'])){
header("location:../login.php");
}
?>
<?php
include('../connect.php');
$id=$_GET['id'];
$del = mysqli_query($connection,"DELETE FROM students WHERE id='$id'");
?>
This is a desired functionality when you are using any RDBMS. i.e. when there are 2 tables with a foreign key relationship between them and the foreign key of the 1st table is a Primary key of the 2nd table. Then deleting the 1st tables record will be triggering the deletion of the record associated with it in the 2nd table.
This is called a cascade delete which is much better explained with the below definition.
A foreign key with cascade delete means that if a record in the parent table is deleted, then the corresponding records in the child table will automatically be deleted. This is called a cascade delete in SQL Server.
MySQL:
You can delete with a JOIN like this:
DELETE users
FROM users
INNER JOIN voters
ON users.id = voters.userid
WHERE users.name = 'Jordan Santos';
See this SQL fiddle for an example with data. (You can comment out the DELETE statement with a # to see the query results without deleting anything.)
Postgres:
You could use two Common Table Expressions (i.e., WITH clauses) to do the deletions in each table:
WITH user_deletion AS (
-- this deletes the user based on username
DELETE
FROM users u
WHERE username='Dad'
RETURNING id, username
),
vote_deletion AS (
-- this gets the deleted user_id from above and deletes the corresponding vote(s)
DELETE
FROM votes
WHERE user_id = (SELECT id FROM user_deletion)
RETURNING vote_id, user_id, vote
)
-- this runs the DELETE statements in the clauses above
SELECT udel.*, vdel.*
FROM user_deletion udel
INNER JOIN vote_deletion vdel
ON udel.id = vdel.user_id;
See this SQL Fiddle for a Postgres example with data, showing results both before and after the deletion.
I already tried lots and lots of combinations but none seem to work =(
I have these two SQL commands:
$sql = "DELETE FROM infogt2000_partner_lead_invoice WHERE infogt2000_partner_lead_invoice_lead_id = ".$id_invoice;
$sql = "DELETE FROM infogt2000_partner_lead WHERE infogt2000_partner_lead_id = ".$id;
And they have to execute "together". Well, if I delete an information from partner_lead it also has to delete the same info from infogt2000_partner_lead_invoice.
The id in infogt2000_partner_lead_id and infogt2000_partner_lead_invoice_lead_id are the same but I cannot write it correctly.
I am currently using MySQL and the type is MyISAM
I gess you will need to use inner join:
DELETE infogt2000_partner_lead_invoice, infogt2000_partner_lead
FROM infogt2000_partner_lead_invoice
INNER JOIN infogt2000_partner_lead
WHERE infogt2000_partner_lead_invoice.infogt2000_partner_lead_invoice_lead_id = infogt2000_partner_lead.infogt2000_partner_lead_id
AND infogt2000_partner_lead_invoice_lead_id = $id
You should consider converting your database tables to InnoDB so that you can create foreign key constraints to cascade on delete. Otherwise, you must write multiple queries, starting from the lowest item in the chain of hierarchy working your way up to the parent-most table. Eg: delete grandchildren, then children, then parents.
I have a number of mysql tables with different table structures and all they have the followings table names and fieldnames (the ones of the left are table names and on the right are field names)
I want to be able to delete the values of the rows using a single variable (example $id = somename) in a single query
user id,
user_image user
user_interest user
user_lang id
user_login user
user_personal user
user_prefer user
user_reviewuser
user_role user_id
user_translang user
user_translate user
user_web id
Also, a particular userid may not be present across all tables.
I am not sure at all on how to delete them all at once. Any tips would be appreciated, i looked at a couploe of similar questions but couldn't find a proper answer.
You want to create a foreign key constraint, and specify "ON DELETE CASCADE". You'll need this for each of your tables that has a foreign key to user. For example,
ALTER TABLE user_image
ADD CONSTRAINT fk_user_image_user FOREIGN KEY (user)
REFERENCES user(id)
ON DELETE CASCADE;
You can use the multi-table DELETE syntax. You need to use a LEFT JOIN in case any of the related tables do not have a corresponding row.
DELETE user, user_image, user_interest, ...
FROM user
LEFT JOIN user_image ON user.id = user_image.user
LEFT JOIN user_interest ON user.id = user_interest.user
...
WHERE user.id = $id
DEMO
However, if you relate the tables using a foreign key constraint, with ON DELETE CASCADE, you can just delete the row from the user table, and all the related rows will be deleted.
I have table structure like this:
PrimaryTable -> p_id Here p_id is primary
SecondoryTable -> s_id p_id Here p_id is a foreign key
ThirdTable -> t_id s_id Here s_id is foreign key
FourthTable -> f_id t_id Here t_id is foreign key
So I am deleting one of my p_id from PrimaryTable and want that its SecondoryTable data should also get delete AND ThirdTable data should be deleted with reference to SecondoryTable and FourthTable data should be deleted with reference to ThirdTable
I know i can write Delete query from bottom to top, but how to do for so many levels like this??
I found this but not sure on howto: https://stackoverflow.com/a/9847308/1182021
Because its four level hierarchy i am confused.
EDIT1:
What if I want to delete Primary on Delete of Child
Kindly suggest.
As per OP's request, this is an answer for the case when the user wants to delete the row from the parent table when a row is deleted from the child table. The case for recursively deleting all the children when a parent is deleted is working using MySQL ON DELETE CASCADE option.
The 4 tables would be table1, table2, table3 & table4.
If the user wants to delete a row in table2 and also the corresponding row in table1 (parent of table2) then in PHP:
// t2_delete_row_id is the id of the table 2 row to be deleted
// get the the parent of table2
$sql_get_parent = "select p_id from table2 where s_id = 't2_delete_row_id '";
// execute this query using MySQLi/PDO to get id of the parent row to be deleted
// assuming that id is t1_parent_row_id
// now delete the row from table 2:
// note that because of the foreign key constraints,
// corresponding rows from table3 and table4 would also be deleted
$sql_delete_child = "delete from table2 where s_id = 't2_delete_row_id'";
if (mysqli_query($sql_delete_child)){
// delete the parent row
$sql_delete_parent = "delete from table1 where p_id = 't1_parent_row_id'";
}
this logic can be extended so that on deleting table3 row, corresponding parent(table2) and "grand-parent" (table1) rows would be deleted as well. A bit of recursion might be needed for that case. And this will of course delete the child rows in table4 because of the foreign key constraint.
If you are not able to use FOREIGN KEYS (ie using MyISAM tables) I would create a TRIGGER for this. Example for first one below ... you will need to make one for each table that's cascading.
DELIMITER //
CREATE TRIGGER `pDeleteTrigger` BEFORE DELETE ON `PrimaryTable`
FOR EACH ROW BEGIN
DELETE FROM `SecondoryTable` WHERE NEW.`p_id` = `SecondoryTable`.`p_id`
END
//
DELIMITER ;
I have two approachs in my mind (if your language is Tsql)
1.- Store procedure
The idea is have a procedure "spDelete_PrimaryTable", so that you can delete the registers in the four tables by writinf something in tsql like:
exec spDelete_PrimaryTable
#p_id= 25 /* (25 or watever p_id of primary table you want to delete)*/
(yes you can call it from vb.net or watever you want to.)
the code would be something like:
use [your_database]
CREATE PROCEDURE [dbo].[spDelete_PrimaryTable]
#p_id nvarchar(MAX)
AS
begin
SET NOCOUNT ON;
delete from FourthTable where t_id in (
select ThirdTable.t_id
from ThirdTable inner join SecondoryTable on ThirdTable.s_id = SecondoryTable.s_id
where SecondoryTable.p_id = #p_id
)
go
delete from ThirdTable where s_id in (
select SecondoryTable.s_id
where SecondoryTable.p_id = #p_id
)
go
/*Lol, I forgot to eliminate from the "SecondoryTable" */
delete from SecondoryTable.s_id
where SecondoryTable.p_id = #p_id
go
delete from PrimaryTable where p_id = #p_id
go
END
GO
2.- Triggers
seems like "Christopher Morrissey" have already posted that while i was editing this answer XP
Basically, I have two tables that have a 1 to 1 relation.
When I delete a row from subset_panel_options I also want to delete the related row in subset_panel_options_list
Here is some of structure for the two tables. There is no need to show the full table.
[subset_panel_options]
->id
->subset_panel_id
[subset_panel_options_list]
->id
->subset_panel_options_id
DELETE subset_panel_options, subset_panel_options_list
FROM subset_panel_options
JOIN subset_panel_options_list
WHERE subset_panel_options.id = subset_panel_options_list.subset_panel_options_id
AND subset_panel_id = $subsetPanelId
Yes, it can:
DELETE FROM subset_panel_options
LEFT JOIN subset_panel_options_list
ON (subset_panel_options.id = subset_panel_options_list.subset_panel_options_id)
WHERE subset_panel_options.subset_panel_id = $subsetPanelId
Using LEFT JOIN you ensure you are deleting from "subset_panel_options" even if there is no corresponding match in the subset_panel_options_list table.
You may also want use referential integrity features available in InnoDB engine. In this case, you need to define subset_panel_options_id as a FK (foreign key) in the subset_panel_options_list table, and an "ON DELETE CASCADE" constraint on it, meaning that when rows at subset_panel_options are deleted, the "orphan" rows in subset_panel_options_list should be immediately deleted too.