sql - 插入前的 SQL 触发器,将新的工作日期与上一个日期进行比较
问题描述
我正在用这些表创建一个数据库
WORK(WORK_ID, WORK_CODE, DATE_BEGIN, DATE_END)
ASSIGNMENTS( WORK_ID:WORK, WORK_CODE:WORK, EMPL_ID:EMPLOYEE)
EMPLOYEE(EMPL_ID, NAME, SRN)
我想创建一个触发器以确保授予每个员工 1 天的休息时间,因此我需要在插入新分配之前触发触发器并检查 EMPL_ID 上次工作的日期以及新工作的日期工作距离新日期不到 1 天,触发器阻止插入并引发错误。我不知道如何与上次工作日期进行比较。我怎么能做这样的事情,在此先感谢您的帮助!
解决方案
像这样的东西?我删除了多余的列,因为它们无关紧要。
SQL> -- Tables
SQL> create table work
2 (work_id number,
3 work_code number,
4 date_begin date,
5 date_end date,
6 constraint pk_work primary key (work_id, work_code)
7 );
Table created.
SQL> create table employee
2 (empl_id number primary key);
Table created.
SQL> create table assignments
2 (work_id number,
3 work_code number,
4 empl_id number constraint fk_ae references employee (empl_id),
5 constraint fk_aw foreign key (work_id, work_code)
6 references work (work_id, work_code));
Table created.
SQL> insert into work (work_id, work_code, date_begin, date_end)
2 select 1, 500, date '2018-05-20', date '2018-05-25' from dual union
3 select 2, 500, date '2018-06-01', date '2018-06-05' from dual union
4 select 3, 500, date '2018-06-06', date '2018-06-10' from dual;
3 rows created.
SQL> insert into employee(empl_id) values (100);
1 row created.
SQL> -- Trigger
SQL> create or replace trigger trg_bi_ass
2 before insert on assignments
3 for each row
4 declare
5 l_date_begin date;
6 l_date_end date;
7 begin
8 -- Previous work
9 select max(w.date_end)
10 into l_date_end
11 from work w
12 where (w.work_id, work_code) in (select a.work_id, a.work_code
13 from assignments a
14 where a.empl_id = :new.empl_id
15 );
16 -- This work
17 select w.date_begin
18 into l_date_begin
19 from work w
20 where w.work_id = :new.work_id
21 and w.work_code = :new.work_code;
22 -- Compare dates
23 if l_date_begin - l_date_end <= 1 then
24 raise_application_error(-20001, 'Employee has to rest for at least 1 day');
25 end if;
26 end;
27 /
Trigger created.
SQL> -- Testing
SQL> -- This should be OK
SQL> insert into assignments (work_id, work_code, empl_id) values (1, 500, 100);
1 row created.
SQL> -- This should be OK, because there are several days between 2018-06-01 and 2018-05-25
SQL> insert into assignments (work_id, work_code, empl_id) values (2, 500, 100);
1 row created.
SQL> -- This should fails, because there's just 1 day between 2018-06-05 and 2016-06-06
SQL> insert into assignments (work_id, work_code, empl_id) values (3, 500, 100);
insert into assignments (work_id, work_code, empl_id) values (3, 500, 100)
*
ERROR at line 1:
ORA-20001: Employee has to rest for at least 1 day
ORA-06512: at "SCOTT.TRG_BI_ASS", line 21
ORA-04088: error during execution of trigger 'SCOTT.TRG_BI_ASS'
SQL>
推荐阅读
- r - R:如何整合这些数据框?
- javascript - 定位类中除下一个元素之外的所有内容?
- sql - 寻找没有重复的序列 - SQL
- batch-file - 如何使用批处理文件选择性地删除文本文件中的文本?
- java - Else 语句未在 SQL 数据库的 while 循环内执行
- xpath - 如何在 VB6 中将连接字符串评估为索引 XPath 表达式
- string - Java 字符串国际化支持带参数的 RTL
- c++ - 计算机从 1 到 1000 猜测您的号码(必须在 10 次尝试中)
- php - 我需要在控制器中创建一个函数来显示具有由数据库确定的文件名的特定视图。- 拉拉维尔
- php - Codeigniter MySQL 数据集未过滤