从表中删除一行

时间:2018-02-27 22:29:24

标签: mysql innodb delete-row

我借助以下.sql

在mysql InnoDB中创建了一个架构
CREATE DATABASE IF NOT EXISTS sailors;
USE sailors;
DROP TABLE IF EXISTS reserves;
DROP TABLE IF EXISTS sailors;
DROP TABLE IF EXISTS boats;

CREATE TABLE sailors
(
sid    INTEGER NOT NULL ,
sname  VARCHAR(20) NOT NULL ,
rating INTEGER NULL ,
age    DECIMAL(5,2) NULL, 
CONSTRAINT sailors_pk PRIMARY KEY (sid)
);

CREATE TABLE boats
(
bid    INTEGER NOT NULL ,
bname  VARCHAR(20) NOT NULL ,
color  VARCHAR(10) NOT NULL ,
CONSTRAINT boats_pk PRIMARY KEY (bid)
);

CREATE TABLE reserves
(
sid    INTEGER NOT NULL ,
bid    INTEGER NOT NULL ,
day    DATE NOT NULL ,
CONSTRAINT reserves_pk PRIMARY KEY (sid,bid,day)
, foreign key (sid) references sailors (sid)
, foreign key (bid) references boats  (bid)
);

INSERT INTO sailors VALUES(22, 'Dustin', 7, 45.0);
INSERT INTO sailors VALUES(29, 'Brutus', 1, 33.0);
INSERT INTO sailors VALUES(31, 'Lubber', 8, 55.5);
INSERT INTO sailors VALUES(32, 'Audy',   8, 25.5);
INSERT INTO sailors VALUES(58, 'Rusty', 10, 35.5);
INSERT INTO sailors VALUES(64, 'Horatio',7, 35.0);
INSERT INTO sailors VALUES(71, 'Zorba', 10, 16.0);
INSERT INTO sailors VALUES(74, 'Horatio',9, 35.0);
INSERT INTO sailors VALUES(85, 'Art',    3, 25.5);
INSERT INTO sailors VALUES(95, 'Bob',    3, 63.5);

INSERT INTO boats VALUES(101, 'Interlake', 'blue');
INSERT INTO boats VALUES(102, 'Interlake', 'red');
INSERT INTO boats VALUES(103, 'Clipper',   'green');
INSERT INTO boats VALUES(104, 'Marine',    'red');
INSERT INTO boats VALUES(105, 'Clipper',   'white');

INSERT INTO reserves VALUES(22, 101, DATE '2012-10-10');
INSERT INTO reserves VALUES(22, 102, DATE '2012-10-10');
INSERT INTO reserves VALUES(22, 103, DATE '2012-08-10');
INSERT INTO reserves VALUES(22, 104, DATE '2012-07-10');
INSERT INTO reserves VALUES(31, 102, DATE '2012-10-11');
INSERT INTO reserves VALUES(31, 103, DATE '2012-06-11');
INSERT INTO reserves VALUES(31, 104, DATE '2012-12-11');
INSERT INTO reserves VALUES(64, 101, DATE '2012-05-09');
INSERT INTO reserves VALUES(64, 102, DATE '2012-08-09');
INSERT INTO reserves VALUES(74, 103, DATE '2012-08-09');

现在我要删除所有关于名为Lubber的水手的表中的所有信息。我做了以下事情:

DELETE FROM sailors
WHERE sname = 'Lubber';

并期望他被删除,但我得到一个错误:

00:27:03    DELETE FROM sailors WHERE sname = 'Lubber'  Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (`sailors`.`reserves`, CONSTRAINT `reserves_ibfk_1` FOREIGN KEY (`sid`) REFERENCES `sailors` (`sid`))    0.016 sec.

那么,我尝试了另一种我认识的方法,但我也失败了。这是方法及其失败。

DELETE sailors, reserves
FROM sailors 
INNER JOIN reserves ON (sailors.sid = reserves.sid)
WHERE sname = 'Lubber';

00:28:22    DELETE sailors, reserves FROM sailors  INNER JOIN reserves ON (sailors.sid = reserves.sid) WHERE sname = 'Lubber'   Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (`sailors`.`reserves`, CONSTRAINT `reserves_ibfk_1` FOREIGN KEY (`sid`) REFERENCES `sailors` (`sid`))    0.000 sec

我真的被卡住了,不知道我还能尝试什么。将不胜感激任何帮助,感谢您的关注。

2 个答案:

答案 0 :(得分:0)

您的卖家表与保留表有关系。通常,当您尝试删除父记录以避免孤立数据时,innodb将抛出错误。以下是一些替代方案

  1. 使用应用程序逻辑

  2. 删除子记录1st
  3. 使用级联删除父项时删除所有子记录。(可能很危险,例如:删除浏览器时可能会丢失所有子记录)

  4. 使用软删除(将is_deleted设置为Yes或No)(强烈推荐)

  5. 您可以对级联执行以下操作,这将删除父级时删除所有子记录

    CREATE TABLE reserves
        (
        sid    INTEGER NOT NULL ,
        bid    INTEGER NOT NULL ,
        day    DATE NOT NULL ,
        CONSTRAINT reserves_pk PRIMARY KEY (sid,bid,day)
        , foreign key (sid) references sailors (sid) ON DELETE CASCADE 
        , foreign key (bid) references boats  (bid) ON DELETE CASCADE 
        )
    

答案 1 :(得分:0)

由于foreign key (sid) references sailors (sid)表上的reserves,以下内容对于维护数据完整性是必要的。理想情况下,这两个语句将在一个事务中发布,甚至更好地从存储过程发出。

DELETE FROM reserves
WHERE sid in (
   SELECT s.sid
   FROM sailors s
   WHERE s.sname = 'Lubber' );

DELETE FROM sailors
WHERE sname = 'Lubber';