Триггер для поиска суммы одного поля в другой таблице и ошибка, если она превышает определенное значение в Oracle - PullRequest
0 голосов
/ 01 мая 2011

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

moduleprogress, который содержит поля:

studentid
modulecode
moduleyear

modules, который содержит поля:

modulecode
credits

Мне нужен триггер для запуска, когда пользователь пытается вставить или обновить данные в таблице moduleprogress.

Для триггера необходимо:

  1. посмотрите на студента, который пользователь ввел, и посмотрите на все модули, которые он взял в модуле год "1".
  2. взять код модуля, введенный пользователем, посмотреть на таблицу модулей и найти сумму поля кредитов для всех этих модулей (каждый модуль стоит 10 или 20 кредитов).
  3. если значениевыше 120 (годовой кредитный лимит), то это должно быть ошибка;если нет, ввод в порядке.

Имеет ли это смысл?Возможно ли это?


@ a_horse_with_no_name

Это похоже на то, что это будет работать, но я буду использовать базу данных только для ввода данных вручную, поэтому возникает ошибкана входе.Я пытаюсь получить аналогичный этому триггер для решения проблемы (триггер не работает) и забываю, что «UOS_» стоит перед всем.Просто помогает мне с моей базой данных и другими функциями.

CREATE OR REPLACE TRIGGER  "UOS_TESTINGS"     
BEFORE UPDATE OR INSERT ON UOS_MODULE_PROGRESS    
REFERENCING NEW AS NEW OLD AS OLD    
DECLARE    
    MODULECREDITS INTEGER;    
BEGIN    
    SELECT    
            m.UOS_CREDITS,    
            mp.UOS_MODULE_YEAR,    
            SUM(m.UOS_CREDITS)    
    INTO    MODULECREDITS    
    FROM    UOS_MODULE_PROGRESS mp JOIN UOS_MODULES m    
    ON      m.UOS_MODULE_CODE = mp.UOS_MODULE_CODE    
    WHERE   mp.UOS_MODULE_YEAR = 1;    


    IF MODULECREDITS >= 120 THEN    
        RAISE_APPLICATION_ERROR(-20000, 'Students are only allowed to take upto 120 credits per year');    
    END IF;    
END;  

Я получаю сообщение об ошибке:

8 23 PL / SQL: ORA-00947: недостаточно значений
4 1 PL / SQL: оператор SQL игнорируется

1 Ответ

0 голосов
/ 02 мая 2011

Я не уверен, что понимаю ваше описание, но, насколько я понимаю, это можно решить с помощью материализованного представления, которое может обеспечить лучшее поведение транзакций, чем триггер:

CREATE MATERIALIZED VIEW LOG 
  ON moduleprogress WITH ROWID (modulecode, studentid, moduleyear) 
  INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW LOG 
  ON modules with rowid (modulecode, credits) 
  INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW mv_module_credits
REFRESH FAST ON COMMIT WITH ROWID
AS
SELECT pr.studentid,
       SUM(m.credits) AS total_credits
FROM moduleprogress pr 
  JOIN modules m ON pr.modulecode = m.modulecode
WHERE pr.moduleyear = 1
GROUP BY pr.studentid;

ALTER TABLE mv_module_credits
   ADD CONSTRAINT check_total_credits CHECK (total_credits <= 120)

Но : в зависимости от размера таблицы это может быть медленнее, чем решение на основе чистого триггера.

Единственный недостаток этого решения заключается в том, что ошибка будет выдана во время фиксации, а не во время вставки (потому что MV обновляется только при фиксации, и тогда проверяется ограничение проверки)

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