使用触发器确定是否实现插入

时间:2017-04-02 06:51:57

标签: sql oracle

我是SQL和Oracle数据库的初学者,我需要一些关于触发器的帮助。这是一个问题:

我需要创建一个触发器,在将一行插入表Room之前,它将检查这个新行的hotel_id以查看它是否存在于另一个表Hotel中。如果新的hotel_id存在,那么插入;如果没有,请取消此插入。

我的代码:

CREATE OR REPLACE TRIGGER TRIGGER1 
BEFORE INSERT ON ROOM 
FOR EACH ROW 
BEGIN
  if (:new.hotel_id in (select hotel_id from hotel)) then
    --execute the insert;
    else
      --cancel the insert;
  end if;
END;

我不确定SQL是否具有可用于继续或取消操作的语法。如果有,请教我或附上与之相关的链接。

2 个答案:

答案 0 :(得分:2)

正确的方法是使用外键约束。

您可以定义/更改您的房间表,以便在hotel_id栏中引用它。

CREATE TABLE

create table room (
    . . .,
    hotel_id int not null,
    constraint fk_hotel_id foreign key (hotel_id)
        references hotel(hotel_id)
);

ALTER TABLE

alter table room
add constraint fk_hotel_id foreign key (hotel_id)
    references hotel(hotel_id);

如果两个表存在于不同的数据库中,则可以使用trigger。

您可以使用raise_application_error proc中止执行并抛出错误。

create or replace trigger trigger1 
before insert or update
on room for each row
declare
    n integer := 0;
begin
    select count(*) into n
    from hotel
    where hotel_id = :new.hotel_id;

    if n = 0 then
        raise_application_error(-20001, 'Hotel ID doesn't exist');
    end if;

end;

答案 1 :(得分:0)

正如GurV所说,外键更适合这样做

虽然,这是触发方式:

CREATE OR REPLACE TRIGGER TRIGGER1 
BEFORE INSERT ON ROOM 
FOR EACH ROW 
declare myvar INT;
BEGIN
    SELECT 1 INTO myvar FROM Hotel WHERE hotel_id = :NEW.hotel_id FETCH NEXT 1 ROW ONLY;
    exception 
    when no_data_found then
       RAISE_APPLICATION_ERROR (-20000, 'some_error_message');
END;