SQL ON DELTE CASCADE 不起作用

Tim*_*mur 2 sql oracle ddl cascade foreign-keys

我目前正在使用 Oracle SQL Developer 编写数据库,我想对我的外键使用 ON DELETE CASCADE,但它显然不起作用。以下是有关声明。您可能会注意到没有更多的表,只有这两个用于测试。

CREATE TABLE pizza
(   size NUMBER(3),
    price NUMBER(5,2),
    CONSTRAINT pk_pizza PRIMARY KEY (size, price)
);
CREATE TABLE pizzacondiment 
(   condiment VARCHAR(30),
    pizzasize NUMBER(3),
    pizzaprice NUMBER(5,2),
    CONSTRAINT pk_condiments PRIMARY KEY (condiment, pizzasize, pizzaprice)
    CONSTRAINT fk_condiments_pizza FOREIGN KEY (pizzasize, pizzaprice)
    REFERENCES pizza (size, price)
    ON DELETE CASCADE;
);
Run Code Online (Sandbox Code Playgroud)

现在,当我想放下桌上披萨时,输出说:

CREATE TABLE pizza
(   size NUMBER(3),
    price NUMBER(5,2),
    CONSTRAINT pk_pizza PRIMARY KEY (size, price)
);
CREATE TABLE pizzacondiment 
(   condiment VARCHAR(30),
    pizzasize NUMBER(3),
    pizzaprice NUMBER(5,2),
    CONSTRAINT pk_condiments PRIMARY KEY (condiment, pizzasize, pizzaprice)
    CONSTRAINT fk_condiments_pizza FOREIGN KEY (pizzasize, pizzaprice)
    REFERENCES pizza (size, price)
    ON DELETE CASCADE;
);
Run Code Online (Sandbox Code Playgroud)

ale*_*bbs 6

ON DELETE CASCADE适用于行级DML操作,但不会影响DDLlike DROP。我将添加一个示例,说明如何ON DELETE应用然后查看可以对 drop 语句进行的更改,以断开之间的链接pizzapizzacondiment但将孤立对象pizzacondiment留在可查询状态。

创建表后:

CREATE TABLE PIZZA
(
  "SIZE" NUMBER(3),
  PRICE  NUMBER(5, 2),
  CONSTRAINT PK_PIZZA PRIMARY KEY ("SIZE", PRICE)
);

CREATE TABLE PIZZACONDIMENT
(
  CONDIMENT  VARCHAR(30),
  PIZZASIZE  NUMBER(3),
  PIZZAPRICE NUMBER(5, 2),
  CONSTRAINT PK_CONDIMENTS PRIMARY KEY (CONDIMENT, PIZZASIZE, PIZZAPRICE),
  CONSTRAINT FK_CONDIMENTS_PIZZA FOREIGN KEY (PIZZASIZE, PIZZAPRICE)
  REFERENCES PIZZA ("SIZE", PRICE)
  ON DELETE CASCADE
);
Run Code Online (Sandbox Code Playgroud)

并添加一些测试数据:

INSERT INTO PIZZA VALUES (11,1.25);
INSERT INTO PIZZA VALUES (219,111.11);
INSERT INTO PIZZA VALUES (50,7.50);


INSERT INTO PIZZACONDIMENT VALUES ('Spinach',50,7.50);
INSERT INTO PIZZACONDIMENT VALUES ('Peppers',50,7.50);
INSERT INTO PIZZACONDIMENT VALUES ('Onions',50,7.50);
INSERT INTO PIZZACONDIMENT VALUES ('Tomatoes',219,111.11);
INSERT INTO PIZZACONDIMENT VALUES ('Mushrooms',11,1.25);
INSERT INTO PIZZACONDIMENT VALUES ('Olives',11,1.25);
Run Code Online (Sandbox Code Playgroud)

ON DELETE CASCADE当我们删除 size=11 的披萨时,我们可以看到实际效果:

SELECT COUNT(*) AS CONDIMENT_COUNT FROM PIZZACONDIMENT WHERE PIZZASIZE = 11;

CONDIMENT_COUNT  
2                
Run Code Online (Sandbox Code Playgroud)

然后制作delete

DELETE FROM PIZZA WHERE "SIZE" = 11;
1 row deleted.
Run Code Online (Sandbox Code Playgroud)

并再次检查子表:

SELECT COUNT(*) AS CONDIMENT_COUNT FROM PIZZACONDIMENT WHERE PIZZASIZE = 11;

CONDIMENT_COUNT  
0             
Run Code Online (Sandbox Code Playgroud)

正如您所提到的,您希望DROP使用PIZZA表格但留下一个孤儿PIZZACONDIMENT,您可以通过调整DROP语法来做到这一点,使用CASCADE CONSTRAINTS. 这将删除任何会阻止DROP, 留下孤立子表的外键。

DROP TABLE PIZZA CASCADE CONSTRAINTS;

Table PIZZA dropped.
Run Code Online (Sandbox Code Playgroud)

pizzacondiment 是孤立的但仍然可用:

SELECT * FROM PIZZACONDIMENT WHERE CONDIMENT = 'Spinach'; 

CONDIMENT  PIZZASIZE  PIZZAPRICE  
Spinach    50         7.5         
Run Code Online (Sandbox Code Playgroud)