【问题标题】:How do I delete multiple records in my database如何删除数据库中的多条记录
【发布时间】:2016-06-16 00:59:46
【问题描述】:

我想创建一个按钮来删除所有需要删除的记录。我的数据库 person、address 和 cv 中有三个表... address_id 与 person 表中的 person_address 有关系,而 cv_id 与 person 表中的 person_cv 有关系。按下删除按钮时,应删除与此人相关的所有内容。我尝试了很多方法,例如:

 echo "<td><a href='delete.php?id=<?" . $row['id'] . "'>delete</a></td>";

使用外部 delete.php 但它根本不起作用...link 在链接中我用于 delete.php 的教程

我的详细信息页面,删除按钮应该在 CV 之后:

<?php
$servername = "localhost";
$username = "root";
$password = "usbw";
$dbname = "persons";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
} 

$sql = "SELECT person_firstname, person_lastname, 
           person_email, person_phonenumber,  
           address_street,address_housenumber, 
           address_city,address_state,address_zipcode, cv_path
    FROM person 
       inner join address on address.address_id = person.person_address 
       inner join cv on cv.cv_id = person.person_cv";

$result = $conn->query($sql);
if ($result->num_rows > 0) {

  echo "<table border=1>
  <tr>
  <th>Voornaam</th>
  <th>Achternaam</th>
  <th>Straat</th>
  <th>Huisnummer</th>
  <th>Postcode</th>
  <th>Stad</th>
  <th>Provincie</th>
  <th>Email</th>
  <th>Mobiel</th>
  <th>CV</th>
  </tr>";


while($row = $result->fetch_assoc()) {
    echo "<tr>";
    echo "<td>" . $row["person_firstname"] . "</td>";
    echo "<td>" . $row["person_lastname"] . "</td>";
    echo "<td>" . $row["address_street"] . "</td>";
    echo "<td>" . $row["address_housenumber"] . "</td>";
    echo "<td>" . $row["address_zipcode"] . "</td>";
    echo "<td>" . $row["address_city"] . "</td>";
    echo "<td>" . $row["address_state"] . "</td>";
    echo "<td>" . $row["person_email"] . "</td>";
    echo "<td>" . $row["person_phonenumber"] . "</td>";
    echo "<td><a href='http://localhost:8080/website/" . $row['cv_path'] . "'>cv file</a></td>";
    echo "</tr>";
}
}
else {
echo "Er is niks in het database gevonden";
}
$conn->close();
?> 

删除.php:

<?php

$host="localhost"; // Host name 
$username="root"; // Mysql username 
$password="usbw"; // Mysql password 
$db_name="persons"; // Database name 
$tbl_name="person"; // Table name 

// Connect to server and select databse.
mysql_connect("$host", "$username", "$password")or die("cannot connect"); 
mysql_select_db("$db_name")or die("cannot select DB");

// get value of id that sent from address bar 
$id=$_GET['person_id'];

// Delete data in mysql from row that has this id 
$sql="DELETE FROM $tbl_name WHERE person_id='$id'";
$result=mysql_query($sql);

// if successfully deleted
if($result){
echo "Deleted Successfully";
echo "<BR>";
echo "<a href='admin.php'>Back to main page</a>";
}

else {
echo "ERROR";
}
?> 

<?php
// close connection 
mysql_close();
?>

【问题讨论】:

  • 让生活变得简单 - 使用 InnoDB 表并使用级联删除设置外键 ~ 这样当您从一个主表中删除一条记录时,相关表中的所有相关记录都将被删除
  • 我猜您的外键缺少on delete 约束:只需将这些键更改为on delete cascade,属于用户的所有数据都将与他一起删除
  • 我同意 RamRaider,级联删除似乎是一个不错的解决方案。许多数据库都支持(我使用 SQL Server),所以您的数据库也可能支持。
  • 我对 PHP 有点陌生,所以请解释一下。我不想更改数据库中的任何内容。
  • 看看Adding constraints in phpMyAdmin(那里的cmets中的所有链接也应该包含有价值的信息)

标签: php mysql


【解决方案1】:

有两种方法:

  1. 从所有 3 个表中手动删除。以下是对此的查询:

    delete prsn, addr, cv from person prsn join address addr on p.person_address = addr.address_id join cv cv on prsn.person_cv = cv.cv_id where prsn.id = ?

  2. 以这样的方式创建外键约束,一旦父记录被删除,子记录就会自动被删除。例如。像这样重新创建地址表:

    create table address( ... FOREIGN KEY (address_id) REFERENCES person(person_Address) ON DELETE CASCADE );

然后,我们只需要执行以下查询:

delete from person where id = ?

【讨论】:

    【解决方案2】:

    我从屏幕截图中看到您已经在使用InnoDB 表,因此使用person_id 作为引用列在addresscv 表上设置一些外键依赖项应该不会太难。

    作为使用外键来实现 rippled delete 的示例,这似乎是导致问题的三个表,它们具有外键依赖集 - 这样您就可以从 person 表中删除 ~ 使用 @987654327此人的@ 以及相关表中的所有记录也将被删除。

    create table if not exists `person` (
      `id` int(10) unsigned not null auto_increment,
      `name` varchar(50) not null,
      primary key (`id`)
    ) engine=innodb auto_increment=2 default charset=latin1;
    
    create table if not exists `address` (
      `id` int(10) unsigned not null auto_increment,
      `person_id` int(10) unsigned not null default '0',
      `address` varchar(50) not null default '0',
      primary key (`id`),
      unique key `person_id` (`person_id`),
      constraint `fk_user_address` foreign key (`person_id`) references `person` (`id`) on delete cascade on update cascade
    ) engine=innodb auto_increment=2 default charset=latin1;
    
    create table if not exists `cv` (
      `id` int(10) unsigned not null auto_increment,
      `person_id` int(10) unsigned not null default '0',
      `cv` varchar(50) not null default '0',
      primary key (`id`),
      key `person_id` (`person_id`),
      constraint `fk_user_cv` foreign key (`person_id`) references `person` (`id`) on delete cascade on update cascade
    ) engine=innodb auto_increment=2 default charset=latin1;
    
    /* dummy data */
    insert into `person` (`id`, `name`) values (1, 'bobby');
    insert into `address` (`id`, `person_id`, `address`) values (1, 1, '99 riverside drive, dundee');
    insert into `cv` (`id`, `person_id`, `cv`) values (1, 1, 'bobby_cv.docx');
    
    
    /* this is how the tables look */    
    person table
    +----+-------+
    | id | name  |
    +----+-------+
    |  1 | Bobby |
    +----+-------+
    
    address table
    +----+---------------+----------------------------+
    | id | person_id(fk) | address                    |
    +----+---------------+----------------------------+
    |  1 |         1     | 99 Riverside Drive, Dundee |
    +----+---------------+----------------------------+
    
    cv table
    +----+---------------+---------------+
    | id | person_id(fk) | cv            |
    +----+---------------+---------------+
    |  1 |         1     | bobby_cv.docx |
    +----+---------------+---------------+
    

    在这种情况下,要删除与 Bobby 关联的所有记录,sql 可以简单地为:

    delete from `person` where `id`=1;
    

    如果不使用这样的外键,您将需要为每个要删除用户及其关联记录的表构建单独的 sql 语句。

    即:

    delete from person where person_id=X;
    delete from address where person_id=X;
    delete from cv where person_id=X;
    

    更新

    抱歉延迟响应 - 已调用睡眠。

    在您的 sql SELECT 语句中,用于显示用户以及来自其他表的相关详细信息,您没有选择 person_id 这是使删除语句​​起作用所需的关键(双关语)元素。

    $sql = "SELECT person_id, person_firstname, person_lastname, 
           person_email, person_phonenumber,  
           address_street,address_housenumber, 
           address_city,address_state,address_zipcode, cv_path
    FROM person 
       inner join address on address.address_id = person.person_address 
       inner join cv on cv.cv_id = person.person_cv";
    

    那么,在while 循环中

    while($row = $result->fetch_assoc()) {
        $person_id=$row['person_id'];
        /* etc - other content as before */
    
        /* note the parameter used is "ID" */
        echo "<a href='delete.php?id={$person_id}'>Delete</a>";
    }
    

    然后在 delete.php 中提供 FK 依赖项已设置(这完全取决于您如何完成这些)

    /* options used to ensure supplied id is within acceptable bounds */
    $options = array(
        'options' => array(
            'default' => 0,
            'min_range' =>  1,
            'max_range' =>  10000000 /* maximum value for ID */
        )
    );
    
    /* process GET parameters - notably "ID" */
    $id=filter_input( INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT );
    $id=(int)filter_var( $id, FILTER_VALIDATE_INT, $options );
    
    /* construct & execute sql */
    if( is_int( $id ) ){
        $sql="delete from `person` where `id`='{$id}';";
    
        $result=mysql_query( $sql );
    }
    

    一个未解决的问题是 sql 注入。原始代码和我在这里详述的代码都使用现已弃用的mysql_* 系列函数,并且容易受到sql 注入的影响。一旦你发现了这个删除问题,将你的代码迁移到使用mysqli是谨慎的,这样你就可以使用prepared statements

    【讨论】:

    • 这两者之间有关系,我想我使用的是较旧的屏幕截图,但在 person_cv 显示的是 cv_id
    • 好的 - 我在你的选择语句中看到了这种关系,但在屏幕截图中不太清楚 - 对此感到抱歉。
    • 仍然不适合我.. 如何编辑我的 delete.php 以删除所有记录?
    猜你喜欢
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 2018-10-14
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    相关资源
    最近更新 更多