使用触发器约束
我使用三个表 - 订单,员工和职位。订单有Employee_no,Employee表有Position_no。我想确保Order表中的Employee_Nos是那些在Sales中的员工的编号。 Sales中员工的Position_no是3,4,5,6。我使用Query 1(见下文)添加检查约束。但是,它不喜欢子查询。我可以使用查询2(见下面)来确保订单表中的Employee_No在列表中(列表是销售员工的员工数量)。但是,如果新员工加入,则查询2将不起作用。我知道这可以使用触发器解决,但不知道如何。如果有人能帮助我,我会很高兴。使用触发器约束
我不经常触发触发器,但它基本上就是这样。我可能会有语法不正确。
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;
感谢我的#1的功能要求,我能够创建一个触发器:d – indolent 2011-02-18 05:54:30
这将工作,直到你得到多个会话同时尝试做同样的事情。 – 2011-02-18 09:04:13
@杰弗里 - 你能解释一下吗?我没有看到多会议冲突会是什么,但我不是触发器的专家。 – 2011-02-18 15:47:23
我不会在你的情况下使用触发器。他们很难处理,你需要知道如何正确管理它们。
请考虑以下解决方案。
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
并添加一个约束,它应该是空的。
啊,类型和亚型。
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);
声明交叉表检查约束是Oracle :) – 2011-02-18 00:41:36