【问题标题】:trigger for delete row with reference to another deleted row in another table参考另一个表中另一个已删除行的删除行触发器
【发布时间】:2016-04-28 19:37:32
【问题描述】:

我的触发器需要帮助。我正在 Oracle 中触发删除第一个表中的行,外键引用第二个表,其中删除的行的主键值类似于第一个表中的外键。

我有这些表:

CREATE TABLE Room (
   id_room NUMBER(5) NOT NULL,
   .
   .
   price VARCHAR(10) NOT NULL,

   PRIMARY KEY(id_mistnosti),

 );

CREATE TABLE item1 (
  id_room NUMBER(5) NOT NULL,
  .
  .

  FOREIGN KEY(id_room) REFERENCES Room
);

CREATE TABLE item2(
  id_room  NUMBER(5) NOT NULL,
  .
  .
  FOREIGN KEY(id_room ) REFERENCES Room
);

我有桌子房间,里面有 2 个项目,所以当我删除他们的房间时,我需要删除这 2 个项目。

现在我尝试只删除一项:

CREATE OR REPLACE TRIGGER removeRoomsItems
BEFORE DELETE ON Room
FOR EACH ROW
WHEN (:Room.id_mistnosti = :item1.id_mistnosti)
BEGIN
  DELETE FROM item1;
END;
/

我的 SQLdeveloper 写道,错误出现在子句 WHEN 中。 我需要一些关于删除这两个项目的指南。

【问题讨论】:

    标签: sql oracle plsql triggers


    【解决方案1】:

    触发器中的表达式不好。触发器可以是这样的:

    CREATE OR REPLACE TRIGGER removeRoomsItems
    BEFORE DELETE ON Room
    FOR EACH ROW
    BEGIN
      DELETE FROM item1 WHERE id_room = :old.id_room ;
    END;
    

    在pl/sql函数中不要使用WHEN,而是使用IFELSEEND IF ;.

    但是你不需要这个触发器,使用级联FK,所以你需要这样创建表:

    CREATE TABLE item2(
      id_room  NUMBER(5) NOT NULL,
      .
      .
      FOREIGN KEY(id_room ) REFERENCES Room ON DELETE CASCADE;
    );
    

    永远不要使用这样的触发器,这是非常糟糕的方式。

    【讨论】:

    • when 部分是有效的语法。它定义触发器触发的条件。它不是触发器主体的一部分。但是,它确实需要在 for each row 之后
    【解决方案2】:

    在这种情况下,您不需要任何触发器。
    只需使用ON DELETE CASCADE 子句:
    http://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses002.htm

    ON DELETE 子句

    ON DELETE 子句让您确定 Oracle 如何 如果删除一个数据库,数据库会自动维护引用完整性 引用的主键或唯一键值。如果省略此子句,则 Oracle 不允许删除引用的键值 在子表中有依赖行的父表。

    如果您希望 Oracle 删除依赖外键,请指定 CASCADE 价值观。

    如果您希望 Oracle 转换依赖外键,请指定 SET NULL 值为 NULL。

    看这个简单的例子:

    CREATE TABLE Room (
       id_mistnosti int,
       id_room NUMBER(5) NOT NULL,
        price VARCHAR(10) NOT NULL,
       PRIMARY KEY(id_mistnosti)
     );
    
    CREATE TABLE item1 (
      id_room NUMBER(5) NOT NULL,
      item_name varchar(100),
      FOREIGN KEY(id_room) REFERENCES Room ON DELETE CASCADE
    );
    
    CREATE TABLE item2(
      id_room  NUMBER(5) NOT NULL,
      item_name varchar(100),
      FOREIGN KEY(id_room ) REFERENCES Room ON DELETE CASCADE
    );
    
    insert into room values( 1, 1, 100 );
    insert into room values( 2, 2, 200 );
    
    insert into item1 values( 1, 'room 1' );
    insert into item1 values( 1, 'room 11' );
    insert into item1 values( 2, 'room 2' );
    insert into item1 values( 2, 'room 22' );
    
    insert into item2 values( 1, 'room 1' );
    insert into item2 values( 1, 'room 11' );
    insert into item2 values( 2, 'room 2' );
    insert into item2 values( 2, 'room 22' );
    
    commit;
    

    现在:

    SELECT * FROM item2;
    
      ID_ROOM ITEM_NAME
    ---------- ----------
             1 room 1    
             1 room 11   
             2 room 2    
             2 room 22 
    

    删除房间并查看此删除如何影响项目:

    delete from room where id_mistnosti = 1;
    
    select * from item2;
    
       ID_ROOM ITEM_NAME
    ---------- ----------
             2 room 2    
             2 room 22   
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多