在删除级联失败

时间:2015-10-03 12:01:08

标签: sql oracle oracle11g

我有两张桌子,首先是我的帐户表

DROP TABLE "Account" CASCADE CONSTRAINTS; 
CREATE table "Account" (
  "Id" NUMBER(5) NOT NULL,
  "Name" VARCHAR2(32) NOT NULL,
  "User" VARCHAR2(16) NOT NULL,
  "Email" VARCHAR2(32) NOT NULL,
  "Password" VARCHAR2(16) NOT NULL,
  "Level" VARCHAR2(16) NOT NULL,
  CONSTRAINT "Account_pk" PRIMARY KEY ("Id")
);

ALTER TABLE "Account"
  ADD UNIQUE ("Name", "User", "Email");

DROP SEQUENCE Account_seq;
CREATE SEQUENCE Account_seq START WITH 0
  INCREMENT BY 1
  MINVALUE 0
  MAXVALUE 10000;

然后插入一些虚拟数据

INSERT INTO "Account" ("Id", "Name", "User", "Email", "Password", "Level") VALUES (Account_seq.NEXTVAL, 'Jan', 'Jan1993', 'jan1993@hotmail.com', 'password', 'user');
INSERT INTO "Account" ("Id", "Name", "User", "Email", "Password", "Level") VALUES (Account_seq.NEXTVAL, 'Piet', 'Piet1978', 'piet1978@gmail.com', 'password', 'admin');

我有一个评论表

DROP TABLE "Review" CASCADE CONSTRAINTS; 
CREATE table "Review" (
  "Id" NUMBER(5) NOT NULL,
  "ReactionId" NUMBER(5) NOT NULL,
  "UserId" NUMBER(5) NOT NULL,
  "Score" NUMBER(1) NOT NULL,
  "Date" DATE NOT NULL,
  CONSTRAINT "Review_pk" PRIMARY KEY ("Id")
);

ALTER TABLE "Review"
  ADD CONSTRAINT "Review_Reaction_fk"
  FOREIGN KEY ("ReactionId")
  REFERENCES "Reaction" ("Id")
  ON DELETE CASCADE;

ALTER TABLE "Review"
  ADD CONSTRAINT "Review_User_fk"
  FOREIGN KEY ("UserId")
  REFERENCES "Account" ("Id")
  ON DELETE CASCADE;

DROP SEQUENCE Review_seq;
CREATE SEQUENCE Review_seq START WITH 0
  INCREMENT BY 1
  MINVALUE 0
  MAXVALUE 10000;

我再次插入一些虚拟数据

INSERT INTO "Review" ("Id", "ReactionId", "UserId", "Score", "Date") VALUES (Review_seq.NEXTVAL, 1, 2, 1, SYSDATE);
INSERT INTO "Review" ("Id", "ReactionId", "UserId", "Score", "Date") VALUES (Review_seq.NEXTVAL, 2, 1, 0, SYSDATE);

当我删除I​​d = 1的用户时,它会删除Review表中的所有数据。但它应该只删除UserId = 1 ...

的数据

2 个答案:

答案 0 :(得分:1)

唯一可能的原因,我猜是神秘的约束,

"Review_Reaction_fk"

它将Reaction' s "Id"称为外键。

ALTER TABLE "Review"
  ADD CONSTRAINT "Review_Reaction_fk"
  FOREIGN KEY ("ReactionId")
  REFERENCES "Reaction" ("Id") ----> Here
  ON DELETE CASCADE;

也许,反应表引用"Account"表,它会删除记录," Review"指。

答案 1 :(得分:0)

在关系数据库的最初几年中,“on delete cascade”选项是一个非常好的想法。您不必担心关注链接回到它们的起源。只需删除实体,系统就会为您完成所有繁重的工作。

然而,存在一些严重的缺点。一个人的意外后果:“等等!我不是故意删除所有其他东西。”然后是锁定。在删除行之前,必须将其锁定。但是如果对该行有FK引用,则必须搜索并锁定这些引用。如果任何那些具有FK引用,则会发生另一级别的“搜索和锁定”。一次又一次,直到一切都被安全锁定。麻烦的是,这并不需要花费很多时间才能使整个数据库停止运行。一切都被锁定或等待释放锁。

我很高兴我不是DBA。这些时候我真的非常高兴我不是DBA!

你所拥有的一些问题可能会让你相信“删除级联”通常是一个坏主意。只是花时间编写代码来搜索关系链并以智能方式删除它们,你可能要好得多。它还会让你有机会展示一些“你确定吗?”为用户提供第二次机会机会。以防万一。