#oracle #plsql
#Oracle #plsql
Вопрос:
Ну, у меня есть такая Процедура:
SET SERVEROUTPUT ON;
CREATE OR REPLACE PROCEDURE check_salary (job_id employees.job_id%TYPE, salary employees.salary%TYPE)
IS
maxSal NUMBER;
minSal NUMBER;
BEGIN
SELECT MAX(salary) INTO maxSal FROM employees WHERE job_id = job_id;
SELECT MIN(salary) INTO minSal FROM employees WHERE job_id = job_id;
IF maxSal >= salary OR minSal <= salary THEN
RAISE_APPLICATION_ERROR(-20001,'Invalid slary '||salary||'. Salaries for job '||job_id||' must be between '||minSal||' and '||maxSal);
END IF;
END;
Это PROCEDURE
имеет два параметра. Он проверяет, находится ли значение salary
a job_id
между значением max
и min
значением задания.
Теперь я хочу создать TRIGGER
.
Если INSERT
или UPDATE
вызывается для сотрудников, я хочу выполнить процедуру. Но я не знаю, что я должен написать в качестве параметра в процедуре
CREATE OR REPLACE TRIGGER check_salary_trg
BEFORE INSERT OR UPDATE ON employees
FOR EACH ROW
DECLARE
BEGIN
check_salary(); --Don't know which parameter I should use
END;
Комментарии:
1. Передайте
:new.job_id
и:new.salary
, но я не уверен, получите ли вы ошибку изменения таблицы или нет
Ответ №1:
Вы должны использовать :NEW как новую строку и :OLD как старую строку. Но я думаю, что нецелесообразно создавать триггер, как ПЕРЕД ВСТАВКОЙ. Вы можете создать триггер как ПОСЛЕ ВСТАВКИ ИЛИ ОБНОВЛЕНИЯ. Вот пример :
CREATE OR REPLACE TRIGGER check_salary_trg
AFTER INSERT OR UPDATE ON EMPLOYEE
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
DECLARE
BEGIN
check_salary(:NEW.job_id);
EXCEPTION
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
RAISE;
END check_salary_trg;
Ответ №2:
Вам просто нужно добавить job_id и зарплату
CREATE OR REPLACE TRIGGER check_salary_trg
BEFORE INSERT OR UPDATE ON employees
FOR EACH ROW
DECLARE
BEGIN
check_salary(:new.job_id, :new.salary);
END;
Комментарии:
1. Синтаксис правильный, однако вы получите
ORA-04091: table HR.employees is mutating, trigger/function may not see it
сообщение об ошибке2. @WernfriedDomscheit И как мне избежать этой ошибки?
3. Вам понадобится составной триггер или, предпочтительно, все в сохраненной процедуре PL / SQL.