简体   繁体   中英

Do a mysql cascade delete on PHP

I'm helping my friend in doing some database management stuff. Basically he has 2 databases, one is called city and one is called shipping rate. Each tables are displayed in a web page with edit and remove button beside each record. So he can delete the data in database via web.

The deal is, I want to do a cascade delete on this mysql database, so that every time I delete a row in city database, a corresponding row in shipping rate database with the same city_ID is deleted as well. I tried to do some mysql query combination, but it didn't work. Here's what I've got

require_once('../../model/city.php');
    if(isset($_POST['id'])){
        //edit or remove
        $id = $_POST['id'];
        $dbo = City::get_by_id($id);
        if($_POST['action'] == 'remove'){
            //remove
            //$dbo->delete();
            mysql_query("DELETE city.*, shipping_rate_loc.* FROM city c,    shipping_rate_loc s WHERE c.ID_city = s.ID_city");
            echo "Data is removed.";
        }

As you can see, I'm just putting that mysql_query on his previous

$dbo->delete();

code which managed to delete the city, but not its related shipping rate.

I'm fairly novice in using mysql inside PHP, so can anybody help me pointing out where my mistake is? Thank you very much :)

update: I've tried some solutions from the answers. none of them working. even when I simplified things. Which makes me wonder, is there any mistake in terms of connecting the php to the database?

The best approach to this would be to amend the database setup to include on delete cascade to the foreign key for shipping_rate_loc table, eg

create table city
(
    id    integer,
    name  varchar,
    ...
    primary key (id)
);

create table shipping_rate_loc
(
    id          integer,
    city_from   integer,
    city_to     integer,
    ...
    foreign key (city_from) references city(id) on delete cascade,
    foreign key (city_to) references city(id) on delete cascade
);

This way, when you delete a record from city table with

DELETE FROM city WHERE id = myid

all records from table shipping_rate_loc where this city is in the city_from or city_to column would automatically be deleted by the database - without you having to do anything in PHP.

Technically the cascade should be done on the tables themselves. But this requires that foreign keys be setup, which in turn requires InnoDB (which your tables may or may not be).

"DELETE city.*, shipping_rate_loc.* FROM city c, shipping_rate_loc s WHERE c.ID_city = s.ID_city"

The problem with this is you don't actually specify which id to remove in the SQL. Instead of

"WHERE c.ID_city = s.ID_city"

try

"WHERE c.ID_city=:city_id AND s.ID_city=:city_id"

and use parameter binding to pass the POST id into the query.

see http://www.php.net/manual/en/ref.pdo-mysql.php for additional details

you can use a left joined delete to perform a cascading delete.

this would look something like:

$query = "DELETE city, shipping_rate FROM city LEFT JOIN shipping rate ON city.id = shipping_rate.city_id WHERE city.id = $blah";

You may want to write a stored procedure to do it.

CREATE PROCEDURE DeleteCity(IN CityID INT)
BEGIN
    delete from city where ID_city = CityID;
    delete from shipping_rate_loc where ID_city = CityID;
END $$

After that, deleting a City is as simple as:

call DeleteCity(5);

When you create your table you should have set up the CASCADE delete/update then.

check this post which will answer your question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM