2012-01-07 73 views
4

表:親屬我可以對SQL中列中不同值的計數有一個約束嗎?

  • emp_id
  • dep_id(複合主鍵)

我們有一個僱員限制到三個家屬。

+0

爲什麼不創建一個觸發器呢? – Nonym 2012-01-07 14:59:26

+0

這可能會有所幫助:http://stackoverflow.com/questions/5522320/what-is-the-best-way-to-enforce-a-subset-relationship-with-integrity-constrain – 2012-01-07 15:02:17

回答

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; 

然而,這種方法可能不是一個大的,繁忙的生產數據庫高性能,在這種情況下,你可以去使用觸發器和檢查約束的方法,加上一個額外的在員工表列:

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

我不滿意..我的需求需要一個簡單的約束(在創建表的時候)...一種內外的方法......我認爲在行級別是不可能的,或者是這樣嗎? – 2012-01-09 03:51:54

+0

你是對的:你的要求無法實現。建立一個簡單的約束來執行這個規則是不可能的。 – 2012-01-09 10:53:15

+0

onedaywhen的答案的修訂版本應該能夠解決問題。 – Tripartio 2015-03-24 14:35:39

3

添加一個新的整數NOT NULL列occurrence,增加一個檢查約束occurrence BETWEEN 1 AND 3,對emp_idoccurrence複合添加唯一約束,選擇添加輔助特效維持occurrence值。

相關問題