Как реализовать триггеры в Oracle - PullRequest
0 голосов
/ 01 мая 2019

Используя Oracle 11g, я пытаюсь получить последний символ имени курса с помощью триггера, а затем, в зависимости от последнего символа, присваивает студенту оценку.

Я пробовал несколько разных подходов к проблеме, я получаю несколько разных ошибок, из-за которых у меня болит голова.Я не уверен, что неправильно подхожу к курсору или вся проблема.

INSERT INTO GRADES (STUDNETID, SECTIONID, SECTIONINFO, COURSEID,COURSENAME, GRADE) VALUES (234501,153, '078',256877 , 'Intro to Holographic',"") ;
INSERT INTO GRADES (STUDNETID, SECTIONID, SECTIONINFO, COURSEID,COURSENAME, GRADE) VALUES (234519,153, '078',256877 ,'Intro to Holographic' ,"") ;
INSERT INTO GRADES (STUDNETID, SECTIONID, SECTIONINFO, COURSEID,COURSENAME ,GRADE) VALUES (234505,153, '078',256877 ,'Intro to Holographic', "") ;
INSERT INTO GRADES (STUDNETID, SECTIONID, SECTIONINFO, COURSEID,COURSENAME, GRADE) VALUES (23405,21, '012A',23532 ,'Starfleet Intro', "") ;
INSERT INTO GRADES (STUDNETID, SECTIONID, SECTIONINFO, COURSEID,COURSENAME, GRADE) VALUES (23419,21, '012A',23532 ,'Starfleet Intro', "") ;
INSERT INTO GRADES (STUDNETID, SECTIONID, SECTIONINFO, COURSEID,COURSENAME, GRADE) VALUES (23401,21, '012A',23532 ,'Starfleet Intro', "") ;
INSERT INTO GRADES (STUDNETID, SECTIONID, SECTIONINFO, COURSEID,COURSENAME, GRADE) VALUES (23418,21, '012A',23532 ,'Starfleet Intro', "") ;
INSERT INTO GRADES (STUDNETID, SECTIONID, SECTIONINFO, COURSEID,COURSENAME, GRADE) VALUES (234520,933,'278',843234 ,'Borg Technolgy', "");
INSERT INTO GRADES (STUDNETID, SECTIONID, SECTIONINFO, COURSEID,COURSENAME, GRADE) VALUES (234505,933,'278',843234 ,'Borg Technolgy' ,"");
INSERT INTO GRADES (STUDNETID, SECTIONID, SECTIONINFO, COURSEID,COURSENAME, GRADE) VALUES (234501,933,'278',843234 ,'Borg Technolgy' ,""); 
INSERT INTO GRADES (STUDNETID, SECTIONID, SECTIONINFO, COURSEID, COURSENAME,GRADE) VALUES (234519,438,'531',542303 , 'Intro to Genetics',""); 

create or replace TRIGGER gradeTrigger
AFTER Update ON Grade For Each Row
  declare 

 cursor courseTitle_cur IS 
  select g.COURSENAME
  from Grade g;

lastChar String (1);
gradeLetter String(1); 
   BEGIN

   for courseTitle_cur in CourseName
                 loop
        SubStr(CourseName, -1):= lastChar;
      end loop;
   If(lastChar = 'A' OR lastChar ='B'OR lastChar = 'C' OR lastChar = 'D' OR lastChar = 'E'OR lastChar = 'F') THEN
 gradeLetter := "A";

ELSIF(lastChar = 'G'OR lastChar = 'H'OR lastChar = 'I'OR lastChar = 'J'OR lastChar = 'K')THEN
 gradeLetter := "B";

ELSIF (LASTCHAR = 'L'or LASTCHAR = 'M'or LASTCHAR = 'N'or LASTCHAR = 'O'or LASTCHAR = 'P')then
 gradeLetter := "C";

ELSIf (LASTCHAR = 'Q' OR LASTCHAR = 'R'OR LASTCHAR = 'S'OR LASTCHAR = 'T')THEN
 gradeLetter := "D";

ELSIf (lastChar = 'U' OR lastChar ='V'OR lastChar = 'W'OR lastChar = 'X'OR lastChar = 'Y' OR lastChar = 'Z')THEN
 gradeLetter := "E";

Return gradeLetter;
end if ; 
   End;

Я получаю сообщения об ошибках типа «Ошибка (16,2): PL / SQL: оператор игнорируется» или «Ошибка (4,10): PL / SQL: ORA-00904: «G». «COURSENAME»: неверный идентификатор «Это очень неприятно, потому что я не могу точно определить, почему он игнорируется или является недействительным.

1 Ответ

2 голосов
/ 01 мая 2019

Я думаю, вы неправильно поняли, как работают триггеры в Oracle.

Каждая обновленная строка имеет состояние до и после - они представлены записями :old и :new соответственно.

Если вы хотите указать, как будет выглядеть значение поля после применения обновления, вам нужно изменить поле в :new записи до применения обновления.

Поэтому, я думаю, ваш триггер должен выглядеть примерно так:

CREATE OR REPLACE TRIGGER grade_trigger
  BEFORE INSERT OR UPDATE ON grades
  FOR EACH ROW
BEGIN
  IF substr(upper(:new.coursename), -1) IN ('A', 'B', 'C', 'D', 'E', 'F')
  THEN
    :new.grade := 'A';
  ELSIF substr(upper(:new.coursename), -1) IN ('G', 'H', 'I', 'J', 'K')
  THEN
    :new.grade := 'B';
  ELSIF substr(upper(:new.coursename), -1) IN ('L', 'M', 'N', 'O', 'P')
  THEN
    :new.grade := 'C';
  ELSIF substr(upper(:new.coursename), -1) IN ('Q', 'R', 'S', 'T')
  THEN
    :new.grade := 'D';
  ELSIF substr(upper(:new.coursename), -1) IN ('U', 'V', 'W', 'X', 'Y', 'Z')
  THEN
    :new.grade := 'E';
  END IF;
END grade_trigger;
/

и вот доказательство того, что оно работает .

...