错误消息:无法删除或更新父行:外键约束失败
Error message: Cannot delete or update a parent row: a foreign key constraint fails
执行我的 doDelete.php 时,出现此错误消息:
" 无法删除或更新父行:外键约束失败 (fyp
.book
, CONSTRAINT book_user_key
FOREIGN KEY (id
) REFERENCES user
(id
) 删除时无操作 更新时无操作) "
删除查询:
$queryDelete = "DELETE FROM user WHERE id = $theUserID";
从 3 tables:
检索信息查询
$query2 = "SELECT * FROM user,country,book where book.id=user.id AND user.country_id=country.country_id ORDER BY `user`.`id` ASC";
我的 'book' 和 'user' table 之间的关系是用户可以添加一本书。因此,将用户ID放在booktable中,以标识哪个用户添加了一本书。然而,当我想从我的 php 中删除一个用户时,上面的错误信息出现了。下面是检索用户 ID 以删除用户的片段。我该如何解决这个问题?
<td><form method="post" action="doDelete.php"><input type="hidden" name="theUserID" value="<?php echo $rows['id']; ?>" /><input type="submit" value="Delete" /</form></td>
这里是相关的tables
CREATE SCHEMA IF NOT EXISTS `fyp` ;
USE `fyp` ;
-- -----------------------------------------------------
-- Table `fyp`.`country`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `fyp`.`country` ;
CREATE TABLE IF NOT EXISTS `fyp`.`country` (
`country_id` INT NOT NULL AUTO_INCREMENT,
`country` VARCHAR(45) NOT NULL,
PRIMARY KEY (`country_id`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `fyp`.`user`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `fyp`.`user` ;
CREATE TABLE IF NOT EXISTS `fyp`.`user` (
`id` INT NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR(45) NOT NULL,
`password` VARCHAR(45) NOT NULL,
`email_address` VARCHAR(45) NOT NULL,
`date_of_birth` DATE NOT NULL,
`country_id` INT NOT NULL,
`gender_id` INT NOT NULL,
`role_id` INT NOT NULL,
`last_login` TIMESTAMP NULL,
PRIMARY KEY (`id`),
INDEX `fk_user_country1_idx` (`country_id` ASC),
INDEX `fk_user_gender1_idx` (`gender_id` ASC),
INDEX `fk_user_role1_idx` (`role_id` ASC),
CONSTRAINT `user_country_key`
FOREIGN KEY (`country_id`)
REFERENCES `fyp`.`country` (`country_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `user_gender_key`
FOREIGN KEY (`gender_id`)
REFERENCES `fyp`.`gender` (`gender_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `user_role_key`
FOREIGN KEY (`role_id`)
REFERENCES `fyp`.`role` (`role_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `fyp`.`book`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `fyp`.`book` ;
CREATE TABLE IF NOT EXISTS `fyp`.`book` (
`book_id` INT NOT NULL AUTO_INCREMENT,
`title` VARCHAR(45) NOT NULL,
`ISBN` VARCHAR(45) NOT NULL,
`book_desc` VARCHAR(100) NOT NULL,
`year_published` VARCHAR(45) NOT NULL,
`year_of_birth` YEAR NOT NULL,
`image` VARCHAR(45) NULL,
`genre_id` INT NOT NULL,
`publisher_id` INT NOT NULL,
`user_id` INT NOT NULL,
PRIMARY KEY (`book_id`),
INDEX `fk_book_publishers1_idx` (`publisher_id` ASC),
INDEX `fk_book_user1_idx` (`user_id` ASC),
INDEX `fk_book_genre1_idx` (`genre_id` ASC),
CONSTRAINT `book_publishers_key`
FOREIGN KEY (`publisher_id`)
REFERENCES `fyp`.`publishers` (`publisher_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `book_user_key`
FOREIGN KEY (`user_id`)
REFERENCES `fyp`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `book_genre_key`
FOREIGN KEY (`genre_id`)
REFERENCES `fyp`.`genre` (`genre_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
确实,您在图书 table 中有一个约束,即只要有该用户添加的图书,您就不能删除该用户:
CONSTRAINT `book_user_key`
FOREIGN KEY (`user_id`)
REFERENCES `fyp`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
你可以改成
ON DELETE CASCADE
这样删除用户也会删除他们所有的书。
或者您可以将约束设置为
ON DELETE SET NULL
并从 book.user_id 中删除 NOT NULL:这将保留已删除用户的书籍,但将其 user_id 设置为 NULL。
您无法创建用户记录,因为它在 book table 中有相关记录。这就是外键约束的工作原理。您在这一行中创建了此约束:
FOREIGN KEY (`user_id`) REFERENCES `fyp`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
要解决这个问题你可以:
- 删除 book table 中给定用户 ID 的记录,然后再从 user table 中删除给定用户.这将需要一条一条地执行 2 条 DELETE 语句。
- 修改外键并使用
ON DELETE CASCADE
。会导致booktable中的记录连同usertable中的相关记录一起自动删除。
我更喜欢解决方案 1,因为它可以让您更好地控制。它也不太容易出错,因为您必须始终明确地从 2 tables 中删除记录。在第二种情况下,您可能会不小心从数据库中删除大量数据。
我相信您在图书[=51]中有 1 个或多个 user_id(您要删除)数据=].
因为 user_id 在 Book table 是一个 FOREIGN KEY to id in User Table, 然后对 User 的任何删除操作 table 将受到 Constraint 的限制(book_user_key)。
您可以在 SQL 中使用此查询来检查数据是否存在:
SELECT * FROM fyp.book WHERE user_id = ***[UserIDWhichYouWantToDelete]***
所以接下来的事情是,如果您在 table 书中已经有了 "User" 数据,您打算怎么办?
您可以在许多网站上找到更多关于 FOREIGN_KEY 的文献。
执行我的 doDelete.php 时,出现此错误消息:
" 无法删除或更新父行:外键约束失败 (fyp
.book
, CONSTRAINT book_user_key
FOREIGN KEY (id
) REFERENCES user
(id
) 删除时无操作 更新时无操作) "
删除查询:
$queryDelete = "DELETE FROM user WHERE id = $theUserID";
从 3 tables:
检索信息查询$query2 = "SELECT * FROM user,country,book where book.id=user.id AND user.country_id=country.country_id ORDER BY `user`.`id` ASC";
我的 'book' 和 'user' table 之间的关系是用户可以添加一本书。因此,将用户ID放在booktable中,以标识哪个用户添加了一本书。然而,当我想从我的 php 中删除一个用户时,上面的错误信息出现了。下面是检索用户 ID 以删除用户的片段。我该如何解决这个问题?
<td><form method="post" action="doDelete.php"><input type="hidden" name="theUserID" value="<?php echo $rows['id']; ?>" /><input type="submit" value="Delete" /</form></td>
这里是相关的tables
CREATE SCHEMA IF NOT EXISTS `fyp` ;
USE `fyp` ;
-- -----------------------------------------------------
-- Table `fyp`.`country`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `fyp`.`country` ;
CREATE TABLE IF NOT EXISTS `fyp`.`country` (
`country_id` INT NOT NULL AUTO_INCREMENT,
`country` VARCHAR(45) NOT NULL,
PRIMARY KEY (`country_id`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `fyp`.`user`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `fyp`.`user` ;
CREATE TABLE IF NOT EXISTS `fyp`.`user` (
`id` INT NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR(45) NOT NULL,
`password` VARCHAR(45) NOT NULL,
`email_address` VARCHAR(45) NOT NULL,
`date_of_birth` DATE NOT NULL,
`country_id` INT NOT NULL,
`gender_id` INT NOT NULL,
`role_id` INT NOT NULL,
`last_login` TIMESTAMP NULL,
PRIMARY KEY (`id`),
INDEX `fk_user_country1_idx` (`country_id` ASC),
INDEX `fk_user_gender1_idx` (`gender_id` ASC),
INDEX `fk_user_role1_idx` (`role_id` ASC),
CONSTRAINT `user_country_key`
FOREIGN KEY (`country_id`)
REFERENCES `fyp`.`country` (`country_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `user_gender_key`
FOREIGN KEY (`gender_id`)
REFERENCES `fyp`.`gender` (`gender_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `user_role_key`
FOREIGN KEY (`role_id`)
REFERENCES `fyp`.`role` (`role_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `fyp`.`book`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `fyp`.`book` ;
CREATE TABLE IF NOT EXISTS `fyp`.`book` (
`book_id` INT NOT NULL AUTO_INCREMENT,
`title` VARCHAR(45) NOT NULL,
`ISBN` VARCHAR(45) NOT NULL,
`book_desc` VARCHAR(100) NOT NULL,
`year_published` VARCHAR(45) NOT NULL,
`year_of_birth` YEAR NOT NULL,
`image` VARCHAR(45) NULL,
`genre_id` INT NOT NULL,
`publisher_id` INT NOT NULL,
`user_id` INT NOT NULL,
PRIMARY KEY (`book_id`),
INDEX `fk_book_publishers1_idx` (`publisher_id` ASC),
INDEX `fk_book_user1_idx` (`user_id` ASC),
INDEX `fk_book_genre1_idx` (`genre_id` ASC),
CONSTRAINT `book_publishers_key`
FOREIGN KEY (`publisher_id`)
REFERENCES `fyp`.`publishers` (`publisher_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `book_user_key`
FOREIGN KEY (`user_id`)
REFERENCES `fyp`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `book_genre_key`
FOREIGN KEY (`genre_id`)
REFERENCES `fyp`.`genre` (`genre_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
确实,您在图书 table 中有一个约束,即只要有该用户添加的图书,您就不能删除该用户:
CONSTRAINT `book_user_key`
FOREIGN KEY (`user_id`)
REFERENCES `fyp`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
你可以改成
ON DELETE CASCADE
这样删除用户也会删除他们所有的书。
或者您可以将约束设置为
ON DELETE SET NULL
并从 book.user_id 中删除 NOT NULL:这将保留已删除用户的书籍,但将其 user_id 设置为 NULL。
您无法创建用户记录,因为它在 book table 中有相关记录。这就是外键约束的工作原理。您在这一行中创建了此约束:
FOREIGN KEY (`user_id`) REFERENCES `fyp`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
要解决这个问题你可以:
- 删除 book table 中给定用户 ID 的记录,然后再从 user table 中删除给定用户.这将需要一条一条地执行 2 条 DELETE 语句。
- 修改外键并使用
ON DELETE CASCADE
。会导致booktable中的记录连同usertable中的相关记录一起自动删除。
我更喜欢解决方案 1,因为它可以让您更好地控制。它也不太容易出错,因为您必须始终明确地从 2 tables 中删除记录。在第二种情况下,您可能会不小心从数据库中删除大量数据。
我相信您在图书[=51]中有 1 个或多个 user_id(您要删除)数据=].
因为 user_id 在 Book table 是一个 FOREIGN KEY to id in User Table, 然后对 User 的任何删除操作 table 将受到 Constraint 的限制(book_user_key)。
您可以在 SQL 中使用此查询来检查数据是否存在:
SELECT * FROM fyp.book WHERE user_id = ***[UserIDWhichYouWantToDelete]***
所以接下来的事情是,如果您在 table 书中已经有了 "User" 数据,您打算怎么办?
您可以在许多网站上找到更多关于 FOREIGN_KEY 的文献。