ТРИГГЕР, который вычисляет СТАТУС студента в таблице - PullRequest
1 голос
/ 06 июля 2019

Мне нужно создать триггер так, чтобы каждый раз, когда новая строка вставлялась в таблицу SUBJECT с данными (STDID, SUBJID, SEMESTER / YEAR, GRADE, FREQ), значение поля STATUS вычислялось и вводилось автоматически , Правила утверждения находятся в таблице ПРАВИЛ, схема которой приведена ниже. Эта таблица имеет только одну строку, но предоставляет возможность динамического изменения. Например, в случае моего университета это будет строка с данными 5,0 (минимальная оценка) и 75% (минимальная частота), но в другом университете может быть 7,0 и 80%. Таблица ПРАВИЛА (minGRADE, minFREQ)

У меня есть две таблицы:

ПРЕДМЕТ

STDID   SUBJID   SEMESTER_YEAR  GRADE    FREQ   STATUS
1111    2         2/2018          6       75    ok
1111    13        2/2018          7       100   ok
1111    4         1/2018          5       90    ok
1111    7         1/2018          10      95    ok
1111    9         2/2018          8       75    ok
1122    2         2/2017          3       75    no
1122    13        2/2017          5       100   ok
1122    4         1/2017          5       90    ok
1122    7         1/2017          10      95    ok
1122    9         2/2017          8       75    ok
1113    2         2/2018          6       75    ok
1113    13        2/2018          7       100   ok
1113    4         1/2018          5       90    ok
1113    7         1/2018          4       95    no
1113    9         2/2018          8       75    ok
1132    2         2/2018          3       75    no
1132    13        2/2018          7       100   ok
1132    4         1/2018          5       90    ok
1132    7         1/2018          4       95    no
1132    9         2/2018          8       75    ok

А другой: СТУДЕНТ

            STDID     NAME      DATA_NASC
            1111    gabriel     12-APR-70
            1112    pedro       12-JUN-70
            1113    lucas       12-MAR-70
            1114    mariana     12-FEB-70
            1115    klemer      12-SEP-70
            1116    jose        12-DEC-70
            1117    vitor       12-NOV-70
            1118    artur       12-APR-70
            1119    bia         12-NOV-70
            1120    julia       12-MAR-70
            1121    rafaela     12-JAN-70
            1122    augusto     12-FEB-70
            1123    eneas       12-JUL-70
            1124    zezinho     12-APR-70
            1125    hugo        12-APR-70
            1126    matheus     12-APR-70
            1127    diana       12-APR-70
            1128    andre       12-APR-70
            1129    reco        12-APR-70

Я застрял на том, как создать этот триггер для автоматического расчета

Ответы [ 2 ]

1 голос
/ 07 июля 2019

Для получения значений STATUS рассмотрите возможность использования VIEW (а не триггера). Вы упомянули таблицу ПРАВИЛ (содержащую minGRADE и т. Д.). Если вы используете Oracle 12c (или новее), вы можете использовать LATERAL JOIN для «вычисления» значений столбца STATUS на лету.

ПРАВИЛА стол

create table rules ( univid, mingrade, minfreq )
as
select 1, 5, 75 from dual ;

Используя определение и данные вашей таблицы SUBJECT, мы можем использовать этот запрос для получения требуемых результатов (уведомление: триггера нет). Мы извлекаем MINGRADE и MINFREQ из таблицы RULES и используем эти значения (через LATERAL JOIN) в CASE основного запроса.

select S.*
, case
    when grade >= mingrade and freq >= minfreq then 'ok'
    else 'not ok'
  end as status
from subject S, lateral ( 
  select mingrade, minfreq from rules where univid = 1
);


-- result
     STDID     SUBJID SEMEST      GRADE       FREQ STATUS
---------- ---------- ------ ---------- ---------- ------
      1111          2 2/2018          6         75 ok    
      1111         13 2/2018          7        100 ok    
      1111          4 1/2018          5         90 ok    
      1111          7 1/2018         10         95 ok    
      1111          9 2/2018          8         75 ok    
      1122          2 2/2017          3         75 not ok
      1122         13 2/2017          5        100 ok    
      1122          4 1/2017          5         90 ok    
      1122          7 1/2017         10         95 ok    
      1122          9 2/2017          8         75 ok    
      1113          2 2/2018          6         75 ok    
      1113         13 2/2018          7        100 ok    
      1113          4 1/2018          5         90 ok    
      1113          7 1/2018          4         95 not ok
      1113          9 2/2018          8         75 ok    
      1132          2 2/2018          3         75 not ok
      1132         13 2/2018          7        100 ok    
      1132          4 1/2018          5         90 ok    
      1132          7 1/2018          4         95 not ok
      1132          9 2/2018          8         75 ok    

20 rows selected.

Мы предполагаем, что все студенты зачислены в университет 1 - см. DBfiddle .

Если вы имеете дело с несколькими правилами (для нескольких университетов), вы все равно можете использовать этот подход - без кодирования триггера. В приведенном ниже примере мы {1} создаем таблицу регистрации, которая содержит отображения STUDENT-UNIVERSITY. Для простоты мы просто «зачисляем» студентов с четными студентами в универ 1, студенты с нечетными студентами переходят в универ 2. {2} Мы добавляем правило для уни 2 в таблицу ПРАВИЛ.

-- ENROLMENTS table
create table enrolments( studentid, universityid )
as
select
  stdid, mod( stdid, 2 ) + 1
from subject ;

-- add a RULE
insert into rules ( univid, mingrade, minfreq ) values ( 2, 7, 80 ) ;

-- the RULES table now contains ...
SQL> select * from rules ;

    UNIVID   MINGRADE    MINFREQ
---------- ---------- ----------
         1          5         75
         2          7         80

Этот следующий запрос даст нам значения STATUS в соответствии с ПРАВИЛАМИ, определенными для uni 1 и uni 2 соответственно. (Если есть больше университетов / правил, просто добавьте записи и правила. Никаких триггеров.)

Запрос

select unique
  S.*
, case
    when grade >= mingrade and freq >= minfreq then 'ok'
    else 'not ok'
  end as status
, R.univid   as "R.uni"        -- output: the universityid
, R.mingrade as "R.mingrade"   -- and the rules
, R.minfreq  as "R.minfreq"    -- for both universities - just for "illustration"
from subject S
, lateral(
  select universityid from enrolments where S.stdid = studentid
) E 
join rules R on E.universityid = R.univid
;

Результат

STDID  SUBJID  SEMESTER_YEAR  GRADE  FREQ  STATUS  R.uni  R.mingrade  R.minfreq  
1122   13      2/2017         5      100   ok      1      5           75         
1122   2       2/2017         3      75    not ok  1      5           75         
1113   9       2/2018         8      75    not ok  2      7           80         
1132   9       2/2018         8      75    ok      1      5           75         
1113   4       1/2018         5      90    not ok  2      7           80         
1113   13      2/2018         7      100   ok      2      7           80         
1132   7       1/2018         4      95    not ok  1      5           75         
1132   4       1/2018         5      90    ok      1      5           75         
1132   2       2/2018         3      75    not ok  1      5           75         
1111   2       2/2018         6      75    not ok  2      7           80         
1122   7       1/2017         10     95    ok      1      5           75         
1113   7       1/2018         4      95    not ok  2      7           80         
1111   4       1/2018         5      90    not ok  2      7           80         
1111   7       1/2018         10     95    ok      2      7           80         
1111   13      2/2018         7      100   ok      2      7           80         
1122   9       2/2017         8      75    ok      1      5           75         
1111   9       2/2018         8      75    not ok  2      7           80         
1132   13      2/2018         7      100   ok      1      5           75         
1113   2       2/2018         6      75    not ok  2      7           80         
1122   4       1/2017         5      90    ok      1      5           75         


20 rows selected. 

DBfiddle здесь .

0 голосов
/ 06 июля 2019

Используйте триггер BEFORE INSERT для обработки входящих значений записи перед их записью. Это позволяет установить SUBJECT.STATUS на основе входящих значений столбца SUBJECT.

Триггеры используют псевдоним :NEW для представления значений столбца, которые должны быть записаны с помощью оператора INSERT. Вы можете запросить или изменить входящие значения. Этот триггер выполняет оба действия: запрашивает оценку и частоту, а также изменяет статус.

CREATE OR REPLACE TRIGGER SUBJECT_STATUS
  BEFORE INSERT
  ON SUBJECT
  FOR EACH ROW

DECLARE
  stat SUBJECT.STATUS%TYPE;
  minGrade RULES.MINIMUM_GRADE%TYPE;
  minFreq RULE.MINIMUM_FREQ%TYPE;

BEGIN

  -- Read minimum grade and frequency into variables
  SELECT MINIMUM_GRADE, MINIMUM_FREQ
    INTO minGrade, minFreq
    FROM RULES;

  IF :NEW.GRADE >= minGrade AND :NEW.FREQ >= minFreq THEN
    -- If the student achieves minimum grade and frequency then status is "ok"
    :NEW.STATUS := 'ok';
  ELSE
    -- If not then status is "no"
    :NEW.STATUS := 'no';
  END IF;

END;

Примечания:

  • В этом коде предполагается, что в вашей таблице RULES есть столбцы MINIMUM_GRADE и MINIMUM_FREQ для минимальной оценки и частоты соответственно. Если ваши фактические имена столбцов отличаются, используйте их вместо этого.

  • Код также использует атрибут Oracle %TYPE для определения типа переменной на основе базового типа столбца. Таким образом, если столбец SUBJECT.STATUS равен VARCHAR2(2), то переменная stat будет VARCHAR2(2). Если это CHAR(2), то stat будет CHAR(2). Если это VARCHAR2(500), то stat будет VARCHAR2(500). И так далее.

  • Я не объяснил объявление CREATE TRIGGER вверху. Если у вас есть какие-либо вопросы по этому поводу, пожалуйста, оставьте записку, и я буду рад объяснить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...