触发编译错误原因

时间:2014-04-08 17:48:51

标签: sql oracle triggers compiler-errors

大家好我有两个触发器我本来是要创建但我在两个

上都有编译错误

第一个应该将0的评估记录到审计表中,第二个应该是为了防止删除日期小于今天的条目。

SQL> CREATE TABLE EVALUATION_AUDIT
2  (C_NAME VARCHAR (15), CO_ID NUMBER(7), E_DATE DATE,
3  V_ID NUMBER (7), C_EVALUATION NUMBER(1));

Table created.

SQL> CREATE OR REPLACE TRIGGER ZERO_EVAL
 2  BEFORE INSERT OR UPDATE OF C_EVALUATION ON CUSTOMER_EVENT
 3  FOR EACH ROW
 4  WHEN (NEW.C_EVALUATION = 0)
 5  BEGIN
 6  SELECT C_NAME, CO_ID, E_DATE, V_ID, C_EVALUATION
 7  FROM CUSTOMER_EVENT CE, CUSTOMER C, EVENT E
 8  WHERE CE.C_ID = C.C_ID
 9  AND CE.EVENT_ID = E.EVENT_ID
10  AND C_EVALUATION = NEW.C_EVALUATION;
11  INSERT INTO EVALUATION AUDIT
12  VALUES (:NEW.C_NAME, :NEW.CO_ID, :NEW.E_DATE, :NEW.V_ID, :NEW.C_EVALUATION);
13  END;
14  /

Warning: Trigger created with compilation errors.


SQL> CREATE OR REPLACE TRIGGER PASTEVENTS
  2  BEFORE DELETE
  3  ON EVENT
  4  FOR EACH ROW
  5  BEGIN
  6  IF :OLD.E_DATE =< SYSDATE
  7  THEN RAISE_APPLICATION_ERROR (-20002, 'CAN NOT DELETE PAST EVENT RECORDS');
  8  
  9  END IF;
 10  END;
 11  /

Warning: Trigger created with compilation errors.

2 个答案:

答案 0 :(得分:1)

正如Justin所说,当你得到任何存储的PL / SQL created with compilation errors时,输入show errors,或者你可以查询user_errors表来查看对象上所有未完成的错误。< / p>

从快速扫描中,当您在选择中引用NEW.C_EVALUATION时,第一个触发器缺少冒号:

AND C_EVALUATION = :NEW.C_EVALUATION;

你需要选择一些东西,虽然我不确定这里是否有必要,因为你有:NEW psuedorecord的值;不确定你为什么选择它?

第二个操作符不正确,=<而不是<=

IF :OLD.E_DATE <= SYSDATE

通常使用表别名为列名称添加前缀以避免歧义,例如, SELECT C.C_NAME, ...如果该列来自CUSTOMER表等,您可能会遇到另一个错误,即多个表上有相同的列。最好在INSERT列出列名称,即INSERT INTO EVALUATION_AUDIT (C_NAME, ...) VALUES (...)。缺少@Dba发现的下划线!

答案 1 :(得分:1)

在您的第一个触发器代码中,您不需要从表中SELECT,因为您只是将表CUSTOMET_EVENT中的值插入EVALUATION_AUDIT。您也错过了并在第11行的_中的table_name中强调了EVALUATION_AUDIT

CREATE OR REPLACE TRIGGER zero_eval
BEFORE INSERT OR UPDATE OF c_evaluation ON customer_event
FOR EACH ROW
WHEN (NEW.c_evaluation = 0)
BEGIN
     INSERT INTO evaluation_audit(c_name, co_id, e_date, v_id, c_evaluation)
     VALUES (:NEW.c_name, :NEW.co_id, :NEW.e_date, :NEW.v_id, :NEW.c_evaluation);
END;
/

在您的第二个代码中,它应该是<=而不是=<

CREATE OR REPLACE TRIGGER pastevents
BEFORE DELETE
ON event
FOR EACH ROW
BEGIN
     IF :OLD.e_date <= SYSDATE THEN 
          raise_application_error (-20002, 'CAN NOT DELETE PAST EVENT RECORDS');
     END IF;
END;
/