使用行触发器将旧日期与新日期进行比较

时间:2019-04-04 05:46:28

标签: oracle plsql row oracle-sqldeveloper database-trigger

嘿,我有这个问题,我似乎无法解决。

我必须创建一个行触发器,以便在我插入新申请时,申请人不能在其上次申请日期之后的30天内申请同一职位。

到目前为止,这是我的代码:我认为我处在正确的轨道上,但我似乎无法将所有内容都串在一起。插入的日期应该会使触发器失效。

CREATE OR REPLACE TRIGGER applicant_date
AFTER INSERT ON APPLIES
FOR EACH ROW
DECLARE applydate applies.appdate%TYPE;

BEGIN
SELECT appdate INTO applydate
FROM applies
where anumber=:New.anumber
and pnumber=:New.pnumber;

IF :New.appdate - applydate < 30 THEN
  RAISE_APPLICATION_ERROR(-20001,
                        'Applicantion within 30 days of last 
application.');
                        END IF;
END;
/

INSERT INTO APPLIES(anumber, pnumber, appdate)
VALUES(000004, 00000007, '13-JAN-2000');

它还要求我输入绑定,而我只是经验不足,无法解决所有问题。无论我输入什么,我都会得到: PLS-00487:对变量'SQLDEVBIND1Z_2'的无效引用

以下是其中的表格:

CREATE TABLE APPLIES(
anumber     NUMBER(6)   NOT NULL, /* Applicant number       */
pnumber     NUMBER(8)   NOT NULL, /* Position number        */
appdate     DATE        NOT NULL, /* Application date       */
CONSTRAINT APPLIES_pkey PRIMARY KEY ( anumber, pnumber, appdate ), 
CONSTRAINT APPLIES_fkey1 FOREIGN KEY ( anumber )
            REFERENCES APPLICANT ( anumber )
            ON DELETE CASCADE,
CONSTRAINT APPLIES_fkey2 FOREIGN KEY ( pnumber )
            REFERENCES POSITION ( pnumber ) 
            ON DELETE CASCADE);

 INSERT INTO APPLIES VALUES( 000001, 00000001, TO_DATE('13-DEC-1999','DD- 
 MON-YYYY') );
 INSERT INTO APPLIES VALUES( 000002, 00000001, TO_DATE('13-DEC-1999','DD- 
 MON-YYYY') );
 INSERT INTO APPLIES VALUES( 000003, 00000002, TO_DATE('14-NOV-1999','DD- 
 MON-YYYY') );
 INSERT INTO APPLIES VALUES( 000004, 00000002, TO_DATE('20-JAN-2000','DD- 
 MON-YYYY') );
 INSERT INTO APPLIES VALUES( 000005, 00000002, TO_DATE('22-JAN-2000','DD- 
 MON-YYYY') );
 INSERT INTO APPLIES VALUES( 000005, 00000003, TO_DATE('09-MAY-1999','DD- 
 MON-YYYY') );
 INSERT INTO APPLIES VALUES( 000006, 00000003, TO_DATE('17-JUN-1999','DD- 
 MON-YYYY') ); 
 INSERT INTO APPLIES VALUES( 000007, 00000003, TO_DATE('18-JUN-1999','DD- 
 MON-YYYY') );
 INSERT INTO APPLIES VALUES( 000007, 00000004, TO_DATE('13-APR-2000','DD- 
 MON-YYYY') );
 INSERT INTO APPLIES VALUES( 000008, 00000004, TO_DATE('13-APR-2000','DD- 
 MON-YYYY') );
 INSERT INTO APPLIES VALUES( 000009, 00000004, TO_DATE('14-APR-2000','DD- 
MON-YYYY') );
 INSERT INTO APPLIES VALUES( 000010, 00000005, TO_DATE('23-SEP-1999','DD- 
MON-YYYY') );
INSERT INTO APPLIES VALUES( 000001, 00000006, TO_DATE('26-OCT-1999','DD- 
MON-YYYY') );
INSERT INTO APPLIES VALUES( 000002, 00000006, TO_DATE('27-OCT-1999','DD- 
MON-YYYY') );
INSERT INTO APPLIES VALUES( 000003, 00000006, TO_DATE('28-OCT-1999','DD- 
MON-YYYY') );
INSERT INTO APPLIES VALUES( 000004, 00000007, TO_DATE('01-JAN-2000','DD- 
MON-YYYY') ); /*row i am trying to trigger*/
INSERT INTO APPLIES VALUES( 000005, 00000007, TO_DATE('03-JAN-2000','DD- 
MON-YYYY') );
INSERT INTO APPLIES VALUES( 000006, 00000007, TO_DATE('04-JAN-2000','DD- 
MON-YYYY') );
INSERT INTO APPLIES VALUES( 000007, 00000007, TO_DATE('07-JAN-2000','DD- 
MON-YYYY') );

非常感谢您,非常感谢。

2 个答案:

答案 0 :(得分:1)

我不知道您遇到了什么错误,而剩下的所有信息都无济于事。

无论如何:AFTER触发器引发变异表错误。如果您切换到BEFORE,则如下所示:

SQL> CREATE OR REPLACE TRIGGER applicant_date
  2     before INSERT
  3     ON APPLIES
  4     FOR EACH ROW
  5  DECLARE
  6     applydate  applies.appdate%TYPE;
  7  BEGIN
  8     SELECT appdate
  9       INTO applydate
 10       FROM applies
 11      WHERE     anumber = :New.anumber
 12            AND pnumber = :New.pnumber;
 13
 14     IF :New.appdate - applydate < 30
 15     THEN
 16        RAISE_APPLICATION_ERROR (-20001,
 17                                 'Applicantion within 30 days of last application.');
 18     END IF;
 19  END;
 20  /

Trigger created.

测试:

SQL> INSERT INTO APPLIES(anumber, pnumber, appdate) VALUES(000004, 00000007, date '2000-01-13');
INSERT INTO APPLIES(anumber, pnumber, appdate) VALUES(000004, 00000007, date '2000-01-13')
            *
ERROR at line 1:
ORA-20001: Applicantion within 30 days of last application.
ORA-06512: at "SCOTT.APPLICANT_DATE", line 12
ORA-04088: error during execution of trigger 'SCOTT.APPLICANT_DATE'


SQL> INSERT INTO APPLIES(anumber, pnumber, appdate) VALUES(000004, 00000007, date '2000-04-13');

1 row created.

SQL>

答案 1 :(得分:0)

如评论中所述,我建议您避免为此要求触发,并建议您将INSERT转换为过程或PL / SQL块的一部分,该过程会基于插入。

DECLARE
  anumber  applies.anumber%type := 4;
  pnumber  applies.pnumber%type := 7;
  appdate  applies.appdate%type :=  to_date('13-JAN-2000','dd-mon-yyyy');
BEGIN
INSERT INTO APPLIES(anumber, pnumber, appdate)

with input(anumber, pnumber, appdate) as
  (
       select anumber, pnumber, appdate from dual  
  ) select * from input i 
        where not exists ( select 1 from applies ap where 
                                i.anumber = ap.anumber
                            and i.pnumber = ap.pnumber
                            and i.appdate - ap.appdate  < 30  ) ;
   IF SQL%ROWCOUNT = 0 THEN
    RAISE_APPLICATION_ERROR(-20001,
    'Application within 30 days of last application.');
   ELSE
     COMMIT;
   END IF;

END;
/

DEMO