SQL数据库触发器ORA-00904

时间:2018-07-02 17:09:29

标签: oracle plsql database-trigger

如果预订评估号码为2,我试图在审核表中输入客户名称,开始日期和发货名称。当我使用的名称在预订表中时,我收到无效的标识符错误。现在,我只是想在审计表中获取客户名称,因此在其他列中为null。

这是我无法看到我要去哪里的代码:

CREATE OR REPLACE TRIGGER EVALUATION
BEFORE INSERT OR UPDATE OR DELETE ON BOOKING
FOR EACH ROW 
WHEN (NEW.BOOKING_EVALUATION = 2)
DECLARE

custname  VARCHAR(20);
sdate    DATE;
shname   VARCHAR(50);

BEGIN

SELECT CUSTOMER_NAME INTO custname FROM customer WHERE CUSTOMER_NAME = NEW.CUSTOMER_NAME;


IF INSERTING THEN
INSERT INTO EVALUATIONAUDIT (VOYAGES_ID,CUSTOMER_NAME,START_DATE,SHIP_NAME,BOOKING_EVALUATION)
VALUES(:NEW.VOYAGES_ID,custname,NULL,NULL,:NEW.BOOKING_EVALUATION);
END IF;


IF UPDATING THEN
INSERT INTO EVALUATIONAUDIT (VOYAGES_ID,CUSTOMER_NAME,START_DATE,SHIP_NAME,BOOKING_EVALUATION)
VALUES(:OLD.VOYAGES_ID,custname,NULL,NULL,:OLD.BOOKING_EVALUATION);
END IF;


IF DELETING THEN
INSERT INTO EVALUATIONAUDIT (VOYAGES_ID,CUSTOMER_NAME,START_DATE,SHIP_NAME,BOOKING_EVALUATION)
VALUES(:OLD.VOYAGES_ID,custname,NULL,NULL,:OLD.BOOKING_EVALUATION);
END IF;
END;
/

这是我得到的错误:

  

9/1 PL / SQL:忽略了SQL语句
  9/67 PL / SQL:ORA-00904:“ NEW”。“ CUSTOMER_NAME”:无效的标识符

1 个答案:

答案 0 :(得分:1)

您需要使用NEW伪记录中的字段,并且由于触发器所针对的表仅具有ID,因此需要使用该ID进行查找:

SELECT CUSTOMER_NAME
INTO custname
FROM customer
WHERE CUSTOMER_ID = :NEW.CUSTOMER_ID;

请注意:的{​​{1}}前缀以及列/字段名称的更改。

但是,这对于NEW分支并不太起作用,因为在这种情况下IF DELETING伪记录将为空-仅填充NEW。因此,您需要其他逻辑来根据触发事件获取基于OLDOLD的客户名称,并根据您可能需要在NEW分支中使用OLD来获取客户名称那里也有老客户ID。

出于相同的原因,UPDATING支票也无法在删除上使用。

所以您可以这样做:

WHEN (NEW.BOOKING_EVALUATION = 2)

取决于您是否要记录更新,如果旧的,新的或CREATE OR REPLACE TRIGGER EVALUATION BEFORE INSERT OR UPDATE OR DELETE ON BOOKING FOR EACH ROW DECLARE custname VARCHAR(20); BEGIN IF INSERTING AND :NEW.BOOKING_EVALUATION = 2 THEN SELECT CUSTOMER_NAME INTO custname FROM customer WHERE CUSTOMER_ID = :NEW.CUSTOMER_ID; INSERT INTO EVALUATIONAUDIT (VOYAGES_ID,CUSTOMER_NAME,START_DATE,SHIP_NAME,BOOKING_EVALUATION) VALUES(:NEW.VOYAGES_ID,custname,NULL,NULL,:NEW.BOOKING_EVALUATION); END IF; IF (UPDATING OR DELETING) AND :OLD.BOOKING_EVALUATION = 2 THEN SELECT CUSTOMER_NAME INTO custname FROM customer WHERE CUSTOMER_ID = :OLD.CUSTOMER_ID; INSERT INTO EVALUATIONAUDIT (VOYAGES_ID,CUSTOMER_NAME,START_DATE,SHIP_NAME,BOOKING_EVALUATION) VALUES(:OLD.VOYAGES_ID,custname,NULL,NULL,:OLD.BOOKING_EVALUATION); END IF; END; / 是2。此版本仅查看BOOKING_EVALUATION中的OLD,因为其他值为您正在使用插入内容,但可以轻松地进行检查,也可以再次拆分UPDATING OR DELETINGUPDATING。或者,您可以将第一张支票更改为:

DELETING

这取决于要捕获的方案以及要为其记录的值。


如果遇到编译错误,请运行... BEGIN IF (INSERTING OR UPDATING) AND :NEW.BOOKING_EVALUATION = 2 THEN ... 或查询show errors视图以查看实际的故障。如果您收到ORA-04098,则错误所指的触发器无效-它是在编译时或者(自从我认为不太可能)自上次成功编译以来表结构已更改。

您可能已经创建了多个触发器。查看

的输出
user_errors

查看此表上有多少个触发器(尽管它可以在其他地方)以及它们被称为什么-如果有多个触发器,则查看是否有一个较早尝试使用另一个名称需要删除。

看看

select trigger_name, status from user_triggers where table_name = 'BOOKING';

查看您已定义的所有触发器,并查找所有无效的触发器。然后,如果从名称上看不出来,您可以返回到select object_name, status from user_objects where object_type = 'TRIGGER'; 视图,查看他们所针对的表。

尽管无效,但原因将在user_triggers中可见。