如果预订评估号码为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”:无效的标识符
答案 0 :(得分:1)
您需要使用NEW
伪记录中的字段,并且由于触发器所针对的表仅具有ID,因此需要使用该ID进行查找:
SELECT CUSTOMER_NAME
INTO custname
FROM customer
WHERE CUSTOMER_ID = :NEW.CUSTOMER_ID;
请注意:
的{{1}}前缀以及列/字段名称的更改。
但是,这对于NEW
分支并不太起作用,因为在这种情况下IF DELETING
伪记录将为空-仅填充NEW
。因此,您需要其他逻辑来根据触发事件获取基于OLD
或OLD
的客户名称,并根据您可能需要在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 DELETING
和UPDATING
。或者,您可以将第一张支票更改为:
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
中可见。