2012-01-07 4 views
4

表:親族SQLの列の個別の値の数に制限を設けることはできますか?

  • emp_id
  • dep_id(複合主キー)

は、我々は3つの扶養に1人の従業員を制限する必要があります。

+0

代わりにトリガーを作成してみませんか? – Nonym

+0

これは参考になるかもしれません:http://stackoverflow.com/questions/5522320/what-is-the-best-way-to-enforce-a-subset-relationship-with-integrity-constrain –

答えて

8

これはチェック制約のみを使用して行うことはできませんが、here on my blogを示すように、マテリアライズドビューとチェック制約を使用する方法があります。あなたの例では、これは次のようになります。

create materialized view emp_dep_mv 
build immediate 
refresh complete on commit as 
select emp_id, count(*) cnt 
from relatives 
group by emp_id; 

alter table emp_dep_mv 
add constraint emp_dep_mv_chk 
check (cnt <= 3) 
deferrable; 

しかし、このアプローチは、その場合には、あなたがトリガーとチェック制約を使用するアプローチに加え、余分のために行くことができ、大規模な、忙しい本番データベースでのパフォーマンスではないかもしれませんemployees表の列:

alter table employees add num_relatives number(1,0) default 0 not null; 

-- Populate for existing data 
update employees 
set num_relatives = (select count(*) from relatives r 
        where r.emp_id = e.emp_id) 
where exists (select * from relatives r 
       where r.emp_id = e.emp_id); 

alter table employees add constraint emp_relatives_chk 
check (num_relatives <= 3); 

create trigger relatives_trg 
after insert or update or delete on relatives 
for each row 
begin 
    if inserting or updating then 
     update employees 
     set num_relatives = num_relatives + 1 
     where emp_id = :new.emp_id; 
    end if; 
    if deleting or updating then 
     update employees 
     set num_relatives = num_relatives - 1 
     where emp_id = :old.emp_id; 
    end if; 
end; 
+0

私は満足していません..私の要件は、最初の行程(テーブル作成中)で単純な制約が必要です...インサイドアウトアプローチ...行レベルでは不可能だと思いますか? –

+0

あなたは正しいです:あなたの要件を満たすことができません。このルールを適用するための単純な制約を作成することは不可能です。 –

+0

onedaywhenの答えの改訂版は、そのトリックを行う必要があります。 – Tripartio

3

は、新しいINTEGER NOT NULL列occurrenceを追加チェック制約occurrence BETWEEN 1 AND 3を追加し、emp_idoccurrenceの化合物にユニーク制約を追加し、必要に応じてoccurrence値を維持するために、ヘルパーprocsのを追加します。

関連する問題