Oracle SQL ORA-01403:未找到数据错误

时间:2014-03-31 12:59:29

标签: sql oracle date

您好我已经看过其他帖子有相同的错误代码,但我无法弄清楚。 我有这样的表'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

1 个答案:

答案 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的值,但您尝试使用此查询中的值。