您好我已经看过其他帖子有相同的错误代码,但我无法弄清楚。 我有这样的表'NOLEGGIO'以这种方式创建:
CREATE TABLE NOLEGGIO(
idNoleggio INT PRIMARY KEY,
dataNoleggio DATE,
dataRestituzione DATE,
dataRestituito DATE,
CF CHAR(16) NOT NULL,
prezzo NUMBER(4),
--SEVERAL CONSTRAINTS...
我现在要做的就是设置'dataRestituzione'的触发器:=:NEW.dataNoleggio + INTERVAL'3'天; (这意味着returnDate:=:NEW.rentalDATE)如果成员资格的日期是<而不是特定的日期。 我告诉你我的'TESSERATO'表(tesserato代表会员资格)
CREATE TABLE TESSERATO(
numTessera INT NOT NULL UNIQUE,
dataTesseramento DATE,
dataScadenza DATE,
CF CHAR(16) PRIMARY KEY,
-- CONSTRAINT...
如果我在触发器之外执行查询(接下来)它可以工作(因为我在我正在查看的字段中有数据)但是如果我在触发器中插入此查询,则它不起作用!
这是触发器:
CREATE OR REPLACE TRIGGER TR_NOLEGGIO
BEFORE INSERT ON NOLEGGIO
FOR EACH ROW
DECLARE
DATAT DATE;
BEGIN
:NEW.idNoleggio := id_noleggio.NEXTVAL;
SELECT T.dataTesseramento INTO DATAT
FROM NOLEGGIO N JOIN TESSERATO T ON N.CF=T.CF
WHERE DATAT < TO_DATE('27/02/2014','DD/MM/YYYY');
/* Here I've even tried to do something like:
IF DATAT < TO_DATE.... THEN . But it doesn't work either.
However the query that actually works if I execute outside the trigger is the SELECT above.
*/
:NEW.dataRestituzione := :NEW.dataNoleggio + INTERVAL '3' DAY;
END;
/
它说没有数据发现错误,而行中有数据而不是!! (事实上,在触发器外面进行选择会匹配几行)。
这绝对让我发疯!无法理解我做错了什么。 提前感谢任何参与其中的人。
为两个表插入staments
-- NOLEGGIO
INSERT INTO NOLEGGIO VALUES(001,'18-OTT-2013','20-OTT-2013',NULL,'P3SDTI85A15H501H',10);
INSERT INTO NOLEGGIO VALUES(002,'15-NOV-2013','19-NOV-2013',NULL,'CNTNDR89T42F839M',700);
--idRental,dateRental,dateReturn,dateReturned,SSN,price)
-- TESSERATO
INSERT INTO TESSERATO(dataTesseramento,dataScadenza,CF) VALUES('07-set-2013','07-set-2014','RDLVRT70M08F205K');
-- SEVERAL INSERTS MORE
-- N.B. the numTessera is made with a sequence in another trigger
答案 0 :(得分:1)
以下评论的新答案
我为此准备了一个测试脚本。如果在日期要求集中存在有效成员资格,则用于触发器的新代码似乎可以正确更新返回日期。您可以随意获取触发器代码并丢弃其余部分,我刚刚将其包含在内,因为它是我用来验证触发器应该执行更新的时间:
注意:我在此测试中删除表以使其可重新运行,因此我建议在测试环境中使用完整脚本
/**************** R U N O N C E ********************/
--CREATE OR REPLACE SEQUENCE id_noleggio
-- MINVALUE 0
-- MAXVALUE 1000000000
-- START WITH 1
-- INCREMENT BY 1
-- CACHE 20;
/********************************************************/
/****************** R E R U N A B L E ****************/
drop table NOLEGGIO;
drop table TESSERATO;
CREATE TABLE NOLEGGIO(
idNoleggio INT PRIMARY KEY,
dataNoleggio DATE,
dataRestituzione DATE,
dataRestituito DATE,
CF CHAR(16) NOT NULL,
prezzo NUMBER(4));
CREATE TABLE TESSERATO(
numTessera INT NOT NULL UNIQUE,
dataTesseramento DATE,
dataScadenza DATE,
CF CHAR(16) PRIMARY KEY);
-- TESSERATO
INSERT INTO TESSERATO(numTessera, dataTesseramento, dataScadenza, CF) VALUES(1, '15-NOV-2013','15-NOV-2014','ABCDEFGHI0000001');
INSERT INTO TESSERATO(numTessera, dataTesseramento, dataScadenza, CF) VALUES(2, '01-MAR-2014','01-MAR-2015','ABCDEFGHI0000002');
-- SEVERAL INSERTS MORE
-- N.B. the numTessera is made with a sequence in another trigger
CREATE OR REPLACE TRIGGER TR_NOLEGGIO
BEFORE INSERT ON NOLEGGIO
FOR EACH ROW
DECLARE
CUT_OFF_DATE DATE := TO_DATE('27/02/2014','DD/MM/YYYY');
MEMBER_EXISTS VARCHAR2(1) := 'N';
DATAT DATE;
BEGIN
:NEW.idNoleggio := id_noleggio.NEXTVAL;
-- membership exists
SELECT 'Y', T.dataTesseramento
INTO MEMBER_EXISTS, DATAT
FROM TESSERATO T
WHERE T.CF = :NEW.CF
AND T.dataTesseramento < CUT_OFF_DATE;
-- if value returned from query above is not null...
if MEMBER_EXISTS = 'Y' then
:NEW.dataRestituzione := :NEW.dataNoleggio + INTERVAL '3' DAY;
end if;
exception
when no_data_found then
-- e.g. if there are no records in the TESSERATO table with the same CF value
null; -- no action required, this will just stop an error being flagged
END;
/
-- test trigger
-- should set dataRestituzione (a valid membership exists within date requirements)
INSERT INTO NOLEGGIO VALUES(004, '01-Mar-2014', NULL, NULL, 'ABCDEFGHI0000001', 20); -- should set dataRestituzione
-- should not set dataRestituzione (membership too recent)
INSERT INTO NOLEGGIO VALUES(004, '01-Mar-2014', NULL, NULL, 'ABCDEFGHI0000002', 30);
-- should not set dataRestituzione (no record of membership in TESSERATO table)
INSERT INTO NOLEGGIO VALUES(1, '18-OCT-2013', NULL, NULL, 'P3SDTI85A15H501H', 10);
INSERT INTO NOLEGGIO VALUES(2, '15-NOV-2013', NULL, NULL, 'CNTNDR89T42F839M', 700);
--idRental,dateRental,dateReturn,dateReturned,SSN,price)
-- look at results
select * from TESSERATO;
select * from NOLEGGIO;
我认为您之前尝试执行此操作的方式的关键问题是您正在加入NOLEGGIO表以检索尚未插入的数据。
上一个答案
尝试链接该行:
WHERE DATAT < TO_DATE('27/02/2014','DD/MM/YYYY');
为:
WHERE T.dataTesseramento < TO_DATE('27/02/2014','DD/MM/YYYY');
在您为其分配值之前,看起来您正在将此变量用于where条件,即在查询完成之前它不知道DATAT
的值,但您尝试使用此查询中的值。