2017-02-10 103 views
0

我试图在更新后触发更新。来自update的特定变量的PL/SQL触发器

我的表:

CREATE TABLE STUDENT (
    STUDENT_ID   INTEGER  PRIMARY KEY, 
    NAME    CHAR(40) NOT NULL, 
    SURNAME    CHAR(40) NOT NULL, 
    TOKEN    CHAR(5)  NOT NULL, 
    STUDYCOURSE   CHAR(20) NOT NULL, 
    NOTE    VARCHAR(255) NULL, 
    WARNING_ID   INTEGER  REFERENCES MAHNUNG (ID), 
    BLOCKED    CHAR(1)  CHECK (Gesperrt IN('J', 'N')); 

create table RENTAL (
    RENTAL_ID   INTEGER  PRIMARY KEY, 
    RENTALDATE   DATE  DEFAULT SYSDATE, 
    RENTALDURATION  INTEGER  NOT NULL, 
    OVERDRAWN   CHAR(1)  CHECK (OVERDRAWN IN('Y', 'N')); 

下了扳机:

CREATE OR REPLACE TRIGGER OVERDRAWN_RETURN 
AFTER UPDATE OF OVERDRAWN ON RENTAL 
    REFERENCING OLD AS OLD AND NEW AS NEW 

BEGIN 
    IF :NEW.OVERDRAWN := 'Y' THEN 
    UPDATE STUDENT SET WARNING_ID = WARNING_ID+1 
    WHERE STUDENT.STUDENT_ID = RENTAL.STUDENT_ID; 
    END IF; 
END OVERDRAWN_RETURN; 
/

什么基本上,我试图做的是递增WARNING_ID当透支更新为 'Y'(是)。 错误报告 -

ORA-04079: invalid trigger specification 
04079. 00000 - "invalid trigger specification" 
*Cause: The create TRIGGER statement is invalid. 
*Action: Check the statement for correct syntax. 

我做错了什么?

+0

顺便说一句,你应该使用'VARCHAR2',而不是'VARCHAR'或'CHAR'。此外,你的大写锁定是打开;) –

回答

1

您在IF语句中使用了赋值运算符(:=)。

CREATE OR REPLACE TRIGGER OVERDRAWN_RETURN 
    AFTER UPDATE OF OVERDRAWN ON RENTAL 
     REFERENCING OLD AS OLD AND NEW AS NEW 

    BEGIN 
     IF :NEW.OVERDRAWN = 'Y' THEN 
     UPDATE STUDENT SET WARNING_ID = WARNING_ID+1 
     WHERE STUDENT.STUDENT_ID = RENTAL.STUDENT_ID; 
     END IF; 
    END OVERDRAWN_RETURN; 
    /
1

除了比较使用:=代替=这@Prashant指出,还有一些其他的问题。你看到的实际错误是因为REFERENCING行,它不应该有AND

但你不能用新,老for语句触发器,所以你需要使它成为一个FOR EACH ROW触发太:

CREATE OR REPLACE TRIGGER OVERDRAWN_RETURN 
AFTER UPDATE OF OVERDRAWN ON RENTAL 
REFERENCING OLD AS OLD NEW AS NEW 
FOR EACH ROW 

BEGIN 
    IF :NEW.OVERDRAWN = 'Y' THEN 
    UPDATE STUDENT SET WARNING_ID = WARNING_ID+1 
    WHERE STUDENT_ID = :NEW.STUDENT_ID; 
    END IF; 
END OVERDRAWN_RETURN; 
/

你指的RENTAL.STUDENT_ID,但超出范围的SQL声明。所以我已经改变了这一点,以指代当前行,与:NEW.STUDENT_ID。但无论哪种方式,您的RENTAL表格没有STUDENT_ID列,但在编辑发布定义时可能刚刚省略。

+0

是的,对不起,我通过ALTER TABLE命令插入STUDENT_ID,并忘记将其直接插入到我的表中。那么是:NEW.STUDENT_ID引用上面的RENTAL更新行? – HandsomeJane

+0

@HandsomeJane - 是的,指''NEW.xxx''表示触发器触发的受影响行中'xxx'的新值。 [阅读更多](http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#LNPLS99955)。如果update语句改变了'STUDENT_ID',那么':OLD.STUDENT_ID'将是表中该行最后设置的旧值,':NEW.STUDENT_ID'将是更新语句中提供的新值,以及表行将在更新完成后包含。在这种情况下,你可能不希望它改变。 –

相关问题