2011-02-17 67 views
1

我使用三个表 - 订单,员工和职位。订单有Employee_no,Employee表有Position_no。我想确保Order表中的Employee_Nos是那些在Sales中的员工的编号。 Sales中员工的Position_no是3,4,5,6。我使用Query 1(见下文)添加检查约束。但是,它不喜欢子查询。我可以使用查询2(见下面)来确保订单表中的Employee_No在列表中(列表是销售员工的员工数量)。但是,如果新员工加入,则查询2将不起作用。我知道这可以使用触发器解决,但不知道如何。如果有人能帮助我,我会很高兴。使用触发器约束

+1

声明交叉表检查约束是Oracle :) – 2011-02-18 00:41:36

回答

0

我不经常触发触发器,但它基本上就是这样。我可能会有语法不正确。

CREATE OR REPLACE TRIGGER check_order_employee_no 
    ON INSERT INTO orders 
    BEFORE EACH ROW 
    AS 
    match_count INTEGER; 
    BEGIN 
    SELECT COUNT(*) 
     INTO match_count 
     FROM employee 
     WHERE employee_no = :new.employee_no 
     AND position IN (3,4,5,6); 
    IF match_count = 0 THEN 
     raise_application_error(-20000, 'Employee # for order must be for a Sales employee'); 
    END IF; 
    END check_order_employee_no; 
+0

感谢我的#1的功能要求,我能够创建一个触发器:d – indolent 2011-02-18 05:54:30

+0

这将工作,直到你得到多个会话同时尝试做同样的事情。 – 2011-02-18 09:04:13

+0

@杰弗里 - 你能解释一下吗?我没有看到多会议冲突会是什么,但我不是触发器的专家。 – 2011-02-18 15:47:23

5

我不会在你的情况下使用触发器。他们很难处理,你需要知道如何正确管理它们。

请考虑以下解决方案。

create materialized view check_sales 
refresh complete on commit as 
select 1 dummy 
from ORDERS where 
EMPLOYEE_NO IS NOT IN (SELECT EMPLOYEE_NO FROM EMPLOYEE WHERE POSITION IN (3,4,5,6)) 

alter table check_sales 
add constraint check_sales_empty 
check (1=0) deferrable; 

我现在没有Oracle来测试我的解决方案,但我认为你有这个想法。您选择不正确的订单到check_sales并添加一个约束,它应该是空的。

4

啊,类型和亚型。

SALES员工是EMP的子类型。假设EMP主键是EMP_ID。 您可以在EMP中创建一个新列SALES_EMP_ID,并在检查约束中创建一个新列,以便仅在员工处于SALES位置时设置此列,并且如果设置,则该值必须等于EMP_ID。另一个强制执行唯一性的约束。

然后,您可以创建从ORDERS到EMP的参照完整性约束.SALES_EMP_ID 请参见下面的演示。只有前两个插入T_EMP才能成功 - 其他人测试检查约束。插入到T_ORDERS中的只有第一个(推销员)会成功。任意复杂的(即从外键约束分开)

drop table t_emp purge; 

CREATE TABLE t_emp 
    (emp_id number primary key, emp_name varchar2(20), 
    dept_name varchar2(10), 
    sales_emp_id number, 
    constraint sales_emp_id_sales_ck check 
     ((sales_emp_id is null and dept_name != 'SALES') or 
     (dept_name = 'SALES' and sales_emp_id = emp_id and sales_emp_id is not null)), 
    constraint sales_emp_id_uk unique (sales_emp_id)); 

insert into t_emp values (1,'Alan','SALES',1); 
insert into t_emp values (2,'Bill','ACCOUNTS',null); 
insert into t_emp values (3,'Chuck','ACCOUNTS',3); 
insert into t_emp values (4,'Dan','SALES',null); 
insert into t_emp values (5,'Ellen','SALES',6); 

select * from t_emp; 

create table t_orders 
    (ord_id number primary key, 
    salesman number, 
    constraint salesman_fk foreign key (salesman) references t_emp(sales_emp_id)); 

insert into t_orders values (1,1); 
insert into t_orders values (2,2);