嘿,我有这个问题,我似乎无法解决。
我必须创建一个行触发器,以便在我插入新申请时,申请人不能在其上次申请日期之后的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') );
非常感谢您,非常感谢。
答案 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;
/