2017-06-17 18 views
0

PersonsRelationshipsの2つのテーブルがあります。2つのテーブル間のOracle SQLチェック制約

IDAgeのテーブルは現在2つのフィールドしかありません。

Relationshipsは、3つのフィールドがあります:私はしたい何Person_IDRelative_IDRelation

を簡単です:Relationshipsに挿入\アップデートに私は次のことを確認したい:

if Relation == 'child' and Persons[Person_ID].Age < Persons[Relative_ID].Age: 
    Throw Exception 

おかげ

+0

あなたはこれまで何をしていますか? –

+0

私は他の問題を解決しました。私は "Workclass"フィールドを手に入れました。私は10個の値のうちの1つになりたいので、 "Workclasses"テーブルを作成し、persons_workclassフィールドからworkclasses_nameフィールドに外部キー制約を作成しました。 –

答えて

1

トリガーを作成する必要があります。

この

CREATE OR REPLACE TRIGGER my_trg 
       BEFORE INSERT OR UPDATE ON Relationships 
       FOR EACH ROW 
    declare 
    function i_Age(id int) return int is 
    li_res int; 
    begin 
     select p.Age 
     into li_res 
     from Persons p 
     where p.ID= id 
     and rownum=1; 
     return li_res; 
    exception when no_data_found then 
    return NULL; --or Throw Exception depend on your logic if some datas not found 
    end; 

    BEGIN 
     IF INSERTING OR UPDATING THEN 
      IF :NEW.Relation == 'child' and i_Age(:NEW.Person_ID) < i_Age(:NEW.Relative_ID) then 
      NULL; --Throw Exception or your logic 
      END IF; 
     END IF; 
    END; 
+0

ORA-04079:無効なトリガー指定 04079. 00000 - "無効なトリガー指定" *原因:create TRIGGER文が無効です。 *処置:文の構文が正しいことを確認してください。 –

+0

"function"ステートメントの前に "declare"が存在する必要があります。ちなみに1,2,3のようなRelationフィールドの数値は、 "child"、 "married" ..などのルックアップテーブルを使用してください。 –

+0

はい、私はそれを変更しました、私はメモ帳に書いています))ありがとうあなた – Vecchiasignora

1

チェック制約(その技術的な意味でフレーズを使用して)を試してみてください、参照制約を除いて、2つの異なるテーブルからのデータに制約をエンコードすることはできません。

マテリアライズド・ビューを作成し、ビューに制約を設定する方法があります。例えば:もちろん

create materialized view relationship_check_mv 
build immediate 
refresh fast on commit 
as 
    select 1 as flag 
    from persons  p1 
     join 
     relationships r on p1.id = r.person_id 
     join 
     persons  p2 on p2.id = r.relative_id 
    where r.relationship = 'child' 
    and p1.age < p2.age 

、あなたが作成する必要があります、最初などをマテリアライズド・ビュー・ログをので、このビューは、各INVALID関係のために1行を持つことになりますマテリアライズド。その後、たとえばflag = 0のようなマテリアライズド・ビューに対する制約を作成します。 (または、ビット単純:select null as flag from....にMVを変更し、列flagがMVでnot nullを可能にするものである。)relationshipsテーブルに無効な行を挿入しようとする試みが行われるたび

は、マテリアライズド・ビューが更新されます新しい列でMV上のチェック制約がそれを防ぐので、トランザクション全体が失敗します。

0
CREATE OR REPLACE TRIGGER child_parent_age_tr BEFORE INSERT OR UPDATE ON RELATIONSHIPS FOR EACH ROW 
    DECLARE 
     child_age NUMBER; 
     parent_age NUMBER; 

    BEGIN 
     SELECT AGE INTO child_age FROM PERSONS WHERE ID = :NEW.PERSON_ID; 
     SELECT AGE INTO parent_age FROM PERSONS WHERE ID = :NEW.RELATIVE_ID; 
     IF INSERTING OR UPDATING THEN 
      IF :NEW.RELATION = 'child' AND child_age >= parent_age THEN 
       RAISE INVALID_NUMBER; 
      END IF; 
     END IF; 
    END; 
+0

これは、マルチユーザー設定では失敗することに注意してください。これは、現在のセッションでしか見ることのできないデータの検証に依存するためです。他のセッションによってまだコミットされていないデータは表示されません。 –

関連する問題