Как реализовать триггеры в Oracle

Используя 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": недопустимый идентификатор" Это очень расстраивает, потому что я не могу точно определить, почему его игнорируют или он недействителен.

Мы не знаем, как выглядят ваши столы. Пожалуйста, отредактируйте свой вопрос и включите структуру ваших таблиц GRADE и COURSENAME, включая все имена полей и типы данных. Спасибо. А пока: в PL/SQL нет типа данных String. Используйте VARCHAR2(x). Строковые константы в PL/SQL следует заключать в одинарные, а не в двойные кавычки. Вы не можете присвоить значение функции, такой как SUBSTR. И триггеры не имеют возвращаемого значения.

Bob Jarvis - Reinstate Monica 01.05.2019 04:25

@BobJarvis Я отредактировал сообщение, указав то, что я вставляю в таблицу. Спасибо за совет по строковым ограничениям в PL/SQL.

Starfire 02.05.2019 01:25

Согласно вашему редактированию, таблица называется GRADES, а не GRADE. Кроме того, название поля — GRADE, а не GRADELETTER. Вы можете попробовать сделать эти замены и посмотреть, будет ли работать лучше.

Bob Jarvis - Reinstate Monica 02.05.2019 02:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вы неправильно поняли, как работают триггеры в 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;
/

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

Oracle выдает мне ошибку о плохой привязке, также я чувствую, что должен использовать курсор для этого @Boneist

Starfire 02.05.2019 01:32

@Boneist: глядя на недавнее редактирование вопроса OP, кажется, что имя таблицы GRADES, а не GRADE. Кроме того, название поля — GRADE, а не GRADELETTER. К черту эти придирчивые тупые компьютеры..! :-)

Bob Jarvis - Reinstate Monica 02.05.2019 02:26

@Starfire Я обновил свой ответ и дал вам демонстрацию рабочего триггера. Как вы думаете, зачем нужен курсор? Это кажется плохим — зачем вам обновлять всю таблицу каждый раз, когда вы обновляете каждую строку?

Boneist 02.05.2019 09:13

@Boneist Я думал, что мне понадобится курсор для просмотра записей. Теперь, когда я вижу, как он работает, я вижу, что функция ДЛЯ КАЖДОЙ СТРОКИ покрывает это.

Starfire 02.05.2019 22:03

Другие вопросы по теме