oracle PL/SQL 中的游标

Posted

技术标签:

【中文标题】oracle PL/SQL 中的游标【英文标题】:Cursors in oracle PL/SQL 【发布时间】:2015-04-05 18:15:16 【问题描述】:

我正在尝试做一个触发器,在更新成绩或插入新成绩时更新成绩的状态。 那是我的桌子

create table Enrollment (
   Student_ID char(9) not null,
   Course_ID char(5) not null,
   Registered_Date date,
   Grade NUMBER,
   Status varchar(4), 
   constraint pkEnrollment primary key (Student_ID, Course_ID));

到目前为止,这是我的代码,我不知道有什么问题

create or replace TRIGGER PASS_FAIL 
AFTER INSERT OR UPDATE OF GRADE ON ENROLLMENT
DECLARE
CURSOR change_grade IS 
select GRADE, STATUS from ENROLLMENT FOR UPDATE;
 newgrade ENROLLMENT.GRADE%type;
 newstatus ENROLLMENT.STATUS%type;
BEGIN
  OPEN change_grade;
  LOOP
  FETCH change_grade into newgrade,newstatus;
  IF newgrade>=60 THEN UPDATE ENROLLMENT SET STATUS = 'Pass' WHERE CURRENT OF change_grade;
  ELSE UPDATE ENROLLMENT SET STATUS = 'Fail' WHERE CURRENT OF change_grade;
  END IF;
  EXIT WHEN change_grade%NOTFOUND;
  END LOOP;
  CLOSE change_grade;
END;

当我试图改变我得到的成绩时

UPDATE "FELIX"."ENROLLMENT" SET GRADE = '10' WHERE ROWID = 'AAAGETAABAAALKJAAE' AND ORA_ROWSCN = '3332070'
ORA-04098: trigger 'FELIX.ELIGIBLE_ENROLLMENT' is invalid and failed re-validation


One error saving changes to table "FELIX"."ENROLLMENT":
Row 5: ORA-04098: trigger 'FELIX.ELIGIBLE_ENROLLMENT' is invalid and failed re-validation

提前感谢您的帮助

【问题讨论】:

问题或错误信息是什么? 当我尝试更改成绩时,我得到 UPDATE "FELIX"."ENROLLMENT" SET GRADE = '10' WHERE ROWID = 'AAAGETAABAAALKJAAE' AND ORA_ROWSCN = '3332070' ORA-04098: trigger 'FELIX .ELIGIBLE_ENROLLMENT' 无效且重新验证失败 保存对表“FELIX”的更改时出错。“ENROLLMENT”:第 5 行:ORA-04098:触发器“FELIX.ELIGIBLE_ENROLLMENT”无效且重新验证失败 作为起点,您的触发器是否编译?如果不是,错误信息是什么? 是的他编译成功 您的 ID 列是 CHAR?真的吗? 【参考方案1】:

除非重点是了解光标,否则您的代码似乎过于复杂。

CREATE OR REPLACE TRIGGER PASS_FAIL
   Before INSERT OR UPDATE 
   ON enrollment
   REFERENCING NEW AS New OLD AS Old
   FOR EACH ROW
DECLARE
/******************************************************************************
   NAME:       PASS_FAIL
   PURPOSE:
   USED BY:
   REVISIONS:
   Ver        Date        Author           Description
   ---------  ----------  ---------------  ------------------------------------
   1.0              1. Created this trigger.

   NOTES:  

******************************************************************************/

BEGIN
   if :new.grade > 60 THEN
     :new.status := 'PASS';
   ELSE
     :new.status := 'FAIL';
   END IF; 
EXCEPTION
   WHEN OTHERS
   THEN
      -- Log the error and then re-raise
      RAISE;
END PASS_FAIL;

【讨论】:

上面的触发器无法编译。我得到错误:ORA-04084:无法更改此触发器类型的新值 无论如何,从表中选择作为触发器的一部分可能会有问题。 那么我怎样才能以另一种方式更改状态? @Felix Kulish。抱歉,这应该是之前的触发器。代码。修改 触发器已成功编译,但是当我更改等级时,我得到了与触发器 UPDATE "FELIX"."ENROLLMENT" SET GRADE = '10' WHERE ROWID = 'AAAGETAABAAALKJAAG' AND ORA_ROWSCN 相同的错误= '3332070' ORA-04098: 触发器 'FELIX.ELIGIBLE_ENROLLMENT' 无效且重新验证失败 保存对表“FELIX”的更改时出错。“ENROLLMENT”:第 7 行:ORA-04098:触发器 'FELIX.ELIGIBLE_ENROLLMENT' 无效并且重新验证失败

以上是关于oracle PL/SQL 中的游标的主要内容,如果未能解决你的问题,请参考以下文章

触发器中的 Oracle PL/SQL 游标

Oracle PL/SQL 将游标(来自函数)中的每个值一一分配给另一个游标

如何使用Oracle的游标?

Oracle PL/SQL 引用游标如何

Oracle游标使用总结

如何在 Oracle PL/SQL 过程的开始部分之后声明游标