错误ora-00922:触发器上的操作丢失或无效

时间:2018-02-17 14:09:17

标签: oracle database-trigger

我试图设置一个简单的触发器,当从注册中删除某些内容时,它也会从乐谱和学生表中删除。我觉得我已经正确设置了所有内容,但我一直收到此错误:错误ora-00922:丢失或无效操作。我已经对错误进行了一些研究,但我没有随处可见。我在sql developer中这样做。我是半新的sql所以任何帮助将不胜感激。我的代码如下:

delimiter //
create or replace TRIGGER enrolls_trigger

AFTER DELETE ON ENROLLS

FOR EACH ROW

BEGIN

DELETE FROM scores

WHERE scores.sid= old.sid

AND scores.term = old.term AND scores.lineno = old.lineno

AND scores.compname = old.compname AND scores.points = old.points;

DELETE FROM students

WHERE students.sid = old.sid;

END//

2 个答案:

答案 0 :(得分:0)

你的语法有点偏。要引用DML事务的先前值,请使用:old。

-- delimiter
CREATE OR REPLACE TRIGGER enrolls_trigger AFTER
    DELETE ON enrolls
    FOR EACH ROW
BEGIN
    DELETE FROM scores
    WHERE
        scores.sid =:old.sid
        AND scores.term =:old.term
        AND scores.lineno =:old.lineno
        AND scores.compname =:old.compname
        AND scores.points =:old.points;

    DELETE FROM students
    WHERE
        students.sid =:old.sid;

END;
--delimiter

此外,如果您正在使用SQL Developer,那么您希望拥有一个&#39 ;;'在触发器主体上的END关键字之后。

Trigger Docs

为了获得更好的帮助,请包含您的TABLE DDL。我创建了这些以便于使用。

CREATE TABLE enrolls (
    sid        INTEGER,
    term       INTEGER,
    lineno     INTEGER,
    compname   VARCHAR2(10),
    points     INTEGER
);

CREATE TABLE scores (
    sid        INTEGER,
    term       INTEGER,
    compname   VARCHAR2(10),
    points     INTEGER,
    lineno     INTEGER
);

CREATE TABLE students (
    sid   INTEGER
);

答案 1 :(得分:0)

我建议采用另一种方法 - 使用ON DELETE CASCADE选项创建的外键约束。看看下面的例子。

感谢Jeff提供了我稍微修改过的CREATE TABLE语句,即只添加了必要的约束。请注意,我只选择SID列作为从SCORES表到ENROLLS的外键。顺便说一下,在SCORES表中重复那么多列的重点是什么?我建议你只保留外键约束列(例如SID),并省略其他列。

最后,我们开始:创建表格:

SQL> CREATE TABLE enrolls (
  2      sid        INTEGER constraint pk_en primary key,
  3      term       INTEGER,
  4      lineno     INTEGER,
  5      compname   VARCHAR2(10),
  6      points     INTEGER
  7  );

Table created.

SQL> CREATE TABLE scores (
  2      sid        INTEGER,
  3      term       INTEGER,
  4      lineno     INTEGER,
  5      compname   VARCHAR2(10),
  6      points     INTEGER,
  7      constraint fk_sco_en foreign key (sid)
  8        references enrolls
  9        on delete cascade
 10  );

Table created.

SQL> CREATE TABLE students (
  2      sid   INTEGER,
  3      constraint fk_stu_en foreign key (sid)
  4        references enrolls
  5        on delete cascade
  6  );

Table created.

SQL>

插入样本数据:

SQL> insert into enrolls  (sid, term) values (100, 1);

1 row created.

SQL> insert into enrolls  (sid, term) values (200, 2);

1 row created.

SQL> insert into scores   (sid, term) values (100, 1);

1 row created.

SQL> insert into scores   (sid, term) values (200, 2);

1 row created.

SQL> insert into students (sid)       values (100);

1 row created.

SQL> insert into students (sid)       values (200);

1 row created.

SQL>
SQL> select * From students;

       SID
----------
       100
       200

SQL> select * From scores;

       SID       TERM     LINENO COMPNAME       POINTS
---------- ---------- ---------- ---------- ----------
       100          1
       200          2

SQL> select * From enrolls;

       SID       TERM     LINENO COMPNAME       POINTS
---------- ---------- ---------- ---------- ----------
       100          1
       200          2

SQL>

现在:如果我从ENROLLS表中删除一行,Oracle将完成其余的工作:

SQL> delete from enrolls where sid = 100;

1 row deleted.

SQL> select * From students;

       SID
----------
       200

SQL> select * From scores;

       SID       TERM     LINENO COMPNAME       POINTS
---------- ---------- ---------- ---------- ----------
       200          2

SQL> select * From enrolls;

       SID       TERM     LINENO COMPNAME       POINTS
---------- ---------- ---------- ---------- ----------
       200          2

SQL>

请参阅? SID = 100已从所有表中删除,无需任何其他编码(即无需触发)。