2017-11-26 28 views
1

にアクセスするトリガーの作成:のOracle SQL - 私は3つのテーブル持っている複数のテーブル

table_family(
id CHAR(4) PRIMARY KEY, 
name VARCHAR(30) 
) 

table_child(
id CHAR(4) PRIMARY KEY, 
name VARCHAR(30), 
family_parents_id CHAR(4) REFERENCES table_family(id) 
) 

table_babysit(
family_babysitter_id CHAR(4) REFERENCES table_family(id), 
child_babysittee_id CHAR(4) REFERENCES table_child(id), 
hours INTEGER 
) 

を私は自分の子供をベビーシッターから家族を防ぐtable_babysitの挿入前にトリガーを作成しようとしています。したがって、table_babysitにある場合、family_babysitter_idは、その子のfamily_parents_idと同じファミリIDと一致します。これは違法です。

CREATE TRIGGER check_illegal_babysit 
BEFORE INSERT 
ON table_babysit 
FOR EACH ROW 
BEGIN 
JOIN table_family ON table_family.id = family_babysitter_id 
JOIN table_child ON table_child.id = child_babysittee_id 
IF (table_family.id = table_child.family_parents_id) THEN 
RAISE_APPLICATION_ERROR(-20000,'Family cannot babysit their own children'); 
END IF; 
END; 

トリガを書くのが初めてで、トリガで複数のテーブルをジョインできないようです。このトリガーを作成する適切な方法は何でしょうか? TABLE1から、それがトリガー、標準的な手順でステートメント、またはそれは、フォーム 選択に従わなければならない、JOINを採用するだけで、スタンドアロンのクエリのかどうか

答えて

2

... [...には]にtable2のを登録しようjoin_condition ... トリガーと手続き型ステートメントにはINTO指定が必要です。

彼のケースでは、CTEを使用してテーブル1を作成することができます。

-- define trigger (with join) 
create or replace trigger check_illegal_babysit 
before insert 
on table_babysit 
for each row 
declare 
    x varchar2(1); 

begin 
    with s as 
      (select :new.family_babysitter_id sitter 
       , :new.child_babysittee_id sittee 
      from dual 
     )  
    select null 
     into x 
     from s 
      left outer join table_family on(table_family.id = sitter) 
      left outer join table_child on(table_child.id = sittee) 
     where table_family.id = table_child.family_parents_id;    

     raise_application_error(-20000,'Family cannot babysit their own children'); 
exception 
    when no_data_found then null; 
end; 

--- Create test Family and Child rows 
insert into table_family (id, name) values('Fam1','Family1'); 
insert into table_family (id, name) values('Fam2','Family2'); 
insert into table_family (id, name) values('Fam3','Family3'); 

insert into table_child(id,name,family_parents_id) values('c1f1', 'Child1 of Family1', 'Fam1'); 
insert into table_child(id,name,family_parents_id) values('c2f1', 'Child2 of Family1', 'Fam1'); 
insert into table_child(id,name,family_parents_id) values('c3f1', 'Child3 of Family1', 'Fam1'); 
insert into table_child(id,name,family_parents_id) values('c1f2', 'Child1 of Family2', 'Fam2'); 
insert into table_child(id,name,family_parents_id) values('c2f2', 'Child2 of Family2', 'Fam2');  

-- Insert into babysit table to test trigger 
insert into table_babysit(family_babysitter_id, child_babysittee_id) values('Fam2', 'c1f1') ; -- valid 
insert into table_babysit(family_babysitter_id, child_babysittee_id) values('Fam3', 'c2f1') ; -- valid 
insert into table_babysit(family_babysitter_id, child_babysittee_id) values('Fam1', 'c3f1') ; -- invalid 
:しかし、合併症は、ここに参加するために必要な条件は実際にトリガを防ぐしようとしているが、論理を反転させたくないものを選択して動作させることができる状態であることであり

あなたが望むものを達成する他のジョインがあると確信しています。私は現時点では考えられません。しかし、おそらく最も簡単な理解は、2つの単純なストレートフォワード選択を使用することです。だから多分試してみてください:

create or replace trigger check_illegal_babysit 
    before insert 
    on table_babysit 
    for each row 
declare 
     family_id_l table_family.id%type; 
     parents_id_l table_child.family_parents_id%type; 
begin 

    select table_family.id 
     into family_id_l 
     from table_family 
     where id = :new.family_babysitter_id; 

    select family_parents_id 
     into parents_id_l 
     from table_child 
     where id = :new.child_babysittee_id; 

    if (family_id_l = parents_id_l) then 
     raise_application_error(-20000,'Family cannot babysit their own children'); 
    end if; 
end; 
関連する問題