插入前的SQL触发器,用于将新工作日期与上一个工作日期进行比较

插入前的SQL触发器,用于将新工作日期与上一个工作日期进行比较,sql,oracle,date,triggers,Sql,Oracle,Date,Triggers,我正在用这些表创建一个数据库 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天的休息时间,因此我需要在插入新任务之前触发触发器,并检查员工ID上次工作的日期,如果新工作的日期与新日期的距离小于1天,则触发器会阻止插入并引发错

我正在用这些表创建一个数据库

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天的休息时间,因此我需要在插入新任务之前触发触发器,并检查员工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>