Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Мутирующая таблица, Создание строчного триггера 
:(
    Опции темы
Rutti
Дата 5.5.2021, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 225
Регистрация: 25.7.2004

Репутация: нет
Всего: нет



Ребята, нужна ваша помощь!

Необходимо обойти проблему мутирующей таблицы “mutating table”.

Имеются таблицы: Employees (где содержатся сведения о сотрудниках, в частности идентификатор должности и зарплата) и Jobs (где содержатся сведения о должностях, в частности идентификатор должности и минимальная зарплата).

Необходимо создать строчный (не составной) триггер, связанный с таблицей Jobs, который будет вызывать процедуру из пакета EMP_PKG.SET_SALARY(job_id, salary), когда минимальный уровень зарплаты для той или иной должности будет изменяться.

Варианты ниже не работают:
1)
Код

CREATE OR REPLACE TRIGGER upd_minsalary_trg
AFTER UPDATE OF min_salary ON jobs
FOR EACH ROW
WHEN (OLD.min_salary != NEW.min_salary)
BEGIN
    emp_pkg.set_salary(:NEW.job_id, :NEW.min_salary);
END upd_minsalary_trg;


2)
Код

CREATE OR REPLACE TRIGGER upd_minsalary_trg
BEFORE UPDATE OF min_salary ON jobs
FOR EACH ROW
BEGIN
    emp_pkg.set_salary(:NEW.job_id, :NEW.min_salary);
END upd_minsalary_trg;



Я никак не пойму, как создать такой триггер.
Помогите, пожалуйста!
PM MAIL   Вверх
Akina
Дата 6.5.2021, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20570
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: нет
Всего: 453



Цитата(Rutti @  5.5.2021,  23:26 Найти цитируемый пост)
Варианты ниже не работают:

Расшифруйте эту фразу. Возникает какая-то ошибка (какая? где текст сообщения об ошибке)? С чего Вы вообще решили, что они "не работают"? 

Цитата(Rutti @  5.5.2021,  23:26 Найти цитируемый пост)
будет вызывать процедуру из пакета EMP_PKG.SET_SALARY(job_id, salary), когда минимальный уровень зарплаты для той или иной должности будет изменяться.

Ну, допустим, вызвал... как это должно проявиться? какой эффект? как Вы вообще определяете, выполнялась эта процедура или нет?




--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Rutti
Дата 6.5.2021, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 225
Регистрация: 25.7.2004

Репутация: нет
Всего: нет



Цитата(Akina @  6.5.2021,  13:58 Найти цитируемый пост)
Расшифруйте эту фразу. 

Была ошибка "ORA-04091: таблица Jobs изменяется, триггер/функция может не заметить это".

Цитата(Akina @  6.5.2021,  13:58 Найти цитируемый пост)
как это должно проявиться? какой эффект?

Должна обновится зарплата в таблице Employees для тех сотрудников, у кого зарплата меньше минимальной в таблице Jobs после выполнения, например, команды 
Скрытый текст
Код

UPDATE jobs
SET min_sal = min_sal + 1000
WHERE job_id = 'X';


Задача частично решена. Триггеры работают, но только с использованием флаг-переменной, которая проверяется в триггерах, предназначенных для заполнения локальной индексированной таблицы до того, как начнется модификация данных.

Триггер 1)
Скрытый текст
Код

CREATE OR REPLACE TRIGGER init_jobspkg_trg
BEFORE INSERT OR UPDATE
ON jobs
BEGIN
jobs_pkg.is_init := TRUE;
jobs_pkg.initialize;
END;


Триггер 2)
Скрытый текст
Код

CREATE OR REPLACE TRIGGER after_init_jobspkg_trg
AFTER INSERT OR UPDATE
ON jobs
BEGIN
jobs_pkg.is_init := FALSE;
END;


Триггер 3)
Скрытый текст
Код

CREATE OR REPLACE TRIGGER employee_initjobs_trg
BEFORE INSERT OR UPDATE ON employees
BEGIN
IF jobs_pkg.is_init = FALSE THEN
jobs_pkg.initialize;
END IF;
END;


В связи с этим вопрос немного изменился: можно ли каким-то образом преобразовать Триггер 1) и Триггер 2) в один (не compound) statement триггер BEFORE INSERT OR UPDATE (без введения дополнительных объектов в базу данных)?
PM MAIL   Вверх
Akina
Дата 7.5.2021, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20570
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: нет
Всего: 453



Цитата(Rutti @  6.5.2021,  18:54 Найти цитируемый пост)
Была ошибка "ORA-04091: таблица Jobs изменяется, триггер/функция может не заметить это".

Что, функция emp_pkg.set_salary вносит изменения в таблицу jobs ???? ну кто так делает! не изменяйте ничего из функций, делайте это в процедуре. Функция должна максимум что возвращать - признак, что требуется обновление, и, возможно, данные для такого обновления...

Цитата(Rutti @  6.5.2021,  18:54 Найти цитируемый пост)
Должна обновится зарплата в таблице Employees для тех сотрудников, у кого зарплата меньше минимальной в таблице Jobs после выполнения, например, команды 

Вообще не понимаю. Что, на Employees тоже висит триггер, который, в свою очередь, обновляет jobs (иначе откуда бы взяться показанной ошибке)? Ну тогда Вы вообще учинили нечто непотребное - кольцевую зависимость в триггерах.

В общем, я бы сказал так - бросайте к чертям собачьим свои затеи с запросами при таком объёме логики на стороне сервера, пока не поздно, и переходите на хранимые процедуры. Заодно и все триггеры можно похерить, а их логику реализовать в тех же процедурах, но вменяемым и корректным способом.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Rutti
Дата 7.5.2021, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 225
Регистрация: 25.7.2004

Репутация: нет
Всего: нет



Требуется работать именно в таких условиях.

Есть строчный (не составной) AFTER UPDATE триггер на Jobs, который срабатывает после обновления минимальной з/п в Jobs. В этом триггере вызывается процедура на обновление з/п в таблице Employees. Также есть BEFORE триггер (1) для инициализации локальной индексированной таблицы - копии Jobs (процедура инициализации разработана в пакете).

На таблицу Employees есть триггер check_salary, в котором вызывается процедура для проверки соответствия з/п диапазону [min_sal;max_sal]. При этом также есть BEFORE триггер (2), вызывающий процедуру инициализации локальной индексированной таблицы для Jobs.

Возникает мутация, которая, как я понимаю, связана с тем, что идет обращение к индексированной таблице одновременно и со стороны триггера на Jobs, и со стороны триггера на Employees (но почему?).

Для решения этой проблемы я использую булевскую переменную в том самом пакете, где и процедура инициализации. Значение флага устанавливаю в триггере (1), а потом сбрасываю. В триггере (2) проверяю, что он сброшен. При этом, триггер на Jobs приходится переделать из statement BEFORE INSERT OR UPDATE в составной (добавляю раздел AFTER, где сбрасываю значение булевской переменной). Как-то можно избежать этого составного триггера (желательно без добавления новых объектов в БД)? 
PM MAIL   Вверх
LSD
Дата 8.5.2021, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15708
Регистрация: 24.3.2004

Репутация: 18
Всего: 537



Это БА такие требования выкатил тригер А и именно строчный, триггер Б и т.д.?

Объясни, что нужно делать-то с точки зрения бизнеса. Отменить изменения, проапдейтить зарплату, письмо бухам отослать.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Oracle"
Zloxa
LSD

Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:

  • при создании темы давайте ей осмысленное название, описывающее суть проблемы
  • указывайте используемую версию базы, способ соединения и язык программирования
  • при ошибках обязательно приводите код ошибки и сообщение сервера
  • приводите код в котором возникла ошибка, по возможности дайте тестовый пример демонстрирующий ошибку
  • при вставке кода используйте соответсвующие теги: [code=sql] [/code] для подсветки SQL и PL/SQL кода, [code=java] [/code] - для Java, и т.д.

  • документация по Oracle: 9i, 10g, 11g
  • книги по Oracle можно поискать здесь
  • действия модераторов можно обсудить здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Oracle | Следующая тема »


 




[ Время генерации скрипта: 0.1258 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.