使用行触发器比较旧日期和新日期
Using a row trigger to compare old dates to new dates
嘿伙计们,我有一个我似乎无法解决的问题。
我必须创建一个行触发器,这样当我插入一个新的申请时,申请人不能在上次申请该职位后的 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') );
非常感谢您,非常感谢。
我不知道你收到的错误与你的消息的其余部分有什么关系。
无论如何:AFTER
触发器引发 变异 table 错误。如果你切换到 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>
如评论中所述,我建议您避免使用 Trigger 满足此要求,并建议您将 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;
/
嘿伙计们,我有一个我似乎无法解决的问题。
我必须创建一个行触发器,这样当我插入一个新的申请时,申请人不能在上次申请该职位后的 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') );
非常感谢您,非常感谢。
我不知道你收到的错误与你的消息的其余部分有什么关系。
无论如何:AFTER
触发器引发 变异 table 错误。如果你切换到 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>
如评论中所述,我建议您避免使用 Trigger 满足此要求,并建议您将 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;
/