即使在创建INSTEAD OF UPDATE TRIGGER之后,更新视图也不合法

时间:2016-12-15 23:35:16

标签: sql oracle plsql triggers

我的ADMITED_TABLE表包含(NOSTUDENT,COURSECODE,SEMESTER,NOGROUPE,MARK)列。

我想做什么:

当更新完成时,我想增加关注 学生们通过oldavg和newavg之间的差异来标记。

Eg: newavg - oldavg = 10.
    every student of that cours get  MARK+10  

Remarque :在这种情况下是否可以更新无列值 AVGMARK只是AVG(MARK)的名字?

UPDATE AverageByGroup SET AVGMARK = (AVGMARK + 10) -- error is her
WHERE COURSCODE = 'AAAA' 
AND   NOGROUPE = 111
AND   SEMESTER = 0000;  

结果:

我应该在ADMITED_TABLE中看到有关旧标记+ 10的学生

错误:

SQL : ORA-01732: data manipulation operation not legal on this view
01732. 00000 -  "data manipulation operation not legal on this view"

我的观点有效且我的TRIGGER编译没有错误

-- CREATION OF THE VIEW

CREATE OR REPLACE VIEW AverageByGroup  AS
SELECT COURSCODE, NOGROUPE, SEMESTER, AVG(MARK) AS AVGMARK
FROM ADMITED_TABLE GROUP BY COURSECODE,NOGROUPE,SEMESTER;

-- TRIGGER INSTEAD OF UPDATE
CREATE OR REPLACE TRIGGER changeStudentsMarks
INSTEAD OF UPDATE ON AverageByGroupe  
FOR EACH ROW

DECLARE

    -- UPDATE CURSOR
    CURSOR c_students IS
    SELECT * FROM ADMITED_TABLE WHERE 
                    COURSCODE  = :NEW.COURSCODE
                    AND NOGROUPE = :NEW.NOGROUPE
                    AND SEMESTER    = :NEW.SEMESTER 
                    FOR UPDATE OF MARK;

    rec_students c_students%ROWTYPE;

    v_actual_avg  INTEGER;
    V_new_avg     INTEGER; 
    v_diff        INTEGER;

BEGIN
    -- Affectationa
    v_actual_avg    :=  :OLD.AVGMARK;
    v_new_avg       :=  :NEW.AVGMARK; 
    v_diff          :=  v_new_avg - v_actual_avg;

    OPEN c_students;
    LOOP
        FETCH c_students INTO rec_students;
        EXIT WHEN c_students%NOTFOUND;

        v_maj_note_etudiant :=  rec_etudiants.NOTE + v_diff -- add the diffrence to student mark

        UPDATE ADMITED_TABLE
        SET MARK  =  MARK + v_maj_note_etudiant
        WHERE CURRENT OF c_students;
    END LOOP;
    CLOSE c_students;
END;
/

1 个答案:

答案 0 :(得分:1)

来自documentation

  

如果视图包含伪列或表达式,那么您只能   使用不引用任何语句的UPDATE语句更新视图   伪列或表达式。

因此,您无法更新从AVG函数派生的列。