Форум программистов, компьютерный форум, киберфорум
Oracle
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 08.03.2015
Сообщений: 12
1

Мутация триггера запрещающего изменять данные

27.05.2016, 20:29. Показов 2002. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Нужна помощь с триггером, он должен запрещать изменять дату формирования заказа и кол-во заказанных книг, если заказ не выполнен, а если заказ выполнен, то ничего менять нельзя.

Мне еще нужно вытащить из дата_отправ sysdate только по году, а не как сейчас со всей датой.

Данный код компилится, но происходит мутация ТАБЛИЦЫ, (неправильно написал заголовок) при изменении поля дата_заказа:
error ORA-04091: table ДЕТАЛИ_ПРОДАЖ is mutating, trigger/function may not see it ORA-06512: at "BEFOREUPDATEDETALIPRODAZH", line 5 ORA-04088: error during execution of trigger 'BEFOREUPDATEDETALIPRODAZH'

Триггер:
Oracle 11 SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE OR REPLACE TRIGGER BeforeUpdateDetaliProdazh
before UPDATE OF Дата_Заказа ON Детали_Продаж 
FOR each ROW
DECLARE
 cant_change_datazak EXCEPTION;
 PRAGMA EXCEPTION_INIT(cant_change_datazak, -2290); 
BEGIN
IF :NEW.Дата_Отпр IS NULL OR :NEW.Дата_Отпр >= SYSDATE THEN UPDATE Детали_Продаж SET Детали_Продаж.Дата_Отпр = SYSDATE + 1; 
ELSIF :NEW.Дата_Отпр <= SYSDATE THEN RAISE cant_change_datazak;
END IF;
EXCEPTION
    WHEN cant_change_datazak THEN
    dbms_output.put_line('Нельзя изменить дату заказа, т.к. заказ еще не выполнен!');
    :NEW.Дата_Отпр:=:old.Дата_Отпр;
    :NEW.Дата_Заказа:=:old.Дата_Заказа;
    :NEW.Кол_во_зак:=:old.Кол_во_зак;
END;
Сама таблица: Вложение 697854

Соответственно, вопрос, как исключить эту мутацию, что и как нужно сделать? Желательно с подробным объяснением.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.05.2016, 20:29
Ответы с готовыми решениями:

Почему не вставляются данные в таблицу после срабатывания триггера
create or replace trigger statist before insert on kniga_prodaga declare cursor cur is ...

не получается изменять данные в базе
сделал приложение сервер и приложение клиент, клиент нормально подключается к серверу и отображает...

Не могу изменять данные в ODBC
Не могу изменять данные в ODBC......в чем проблемм ??? Подскажите плиззз.....Показывать -...

Как хранить и изменять данные в WP 8.1
Есть необходимость запоминать введенные пользователем данные, где-то их хранить, и самое главное,...

9
476 / 239 / 114
Регистрация: 12.05.2016
Сообщений: 647
27.05.2016, 21:03 2
Лучший ответ Сообщение было отмечено Dubfire752 как решение

Решение

Цитата Сообщение от Dubfire752 Посмотреть сообщение
if :new.Дата_Отпр is null or :new.Дата_Отпр >= sysdate then update Детали_Продаж set Детали_Продаж.Дата_Отпр = sysdate + 1;
elsif :new.Дата_Отпр <= sysdate then raise cant_change_datazak;
end if;
Зачем тут апдейт ?? Просто меняйте значение :NEW.Дата_Отпр и оно запишется в таблицу вместо того, что пришло в триггер. Для этого триггеры и нужны.

Oracle 11 SQL
1
2
3
4
5
IF :NEW.Дата_Отпр IS NULL OR :NEW.Дата_Отпр >= SYSDATE THEN 
   :NEW.Дата_Отпр := SYSDATE + 1;
ELSIF :NEW.Дата_Отпр <= SYSDATE THEN 
   RAISE cant_change_datazak;
END IF;
1
0 / 0 / 0
Регистрация: 08.03.2015
Сообщений: 12
27.05.2016, 21:16  [ТС] 3
Спасибо большое, а можете ли сделать чтобы для даты_отпр sysdate считывался только по году? а потом уже к полной дате прибавлялся 1 день.
0
476 / 239 / 114
Регистрация: 12.05.2016
Сообщений: 647
27.05.2016, 22:35 4
Цитата Сообщение от Dubfire752 Посмотреть сообщение
для даты_отпр sysdate считывался только по году?
Не понял фразу. Пример приведите, что значит "считывался только по году"
0
0 / 0 / 0
Регистрация: 08.03.2015
Сообщений: 12
28.05.2016, 10:59  [ТС] 5
примерно как-то так: to_char(sysdate,'yyyy') или через extract(year from sysdate), только незнаю как правильно это в триггере написать в IF.
0
763 / 664 / 194
Регистрация: 24.11.2015
Сообщений: 2,158
28.05.2016, 20:13 6
Цитата Сообщение от Dubfire752 Посмотреть сообщение
незнаю как правильно это .... написать
А Вы напишите неправильно, потому что все равно непонятно, чего Вы хотите.
0
0 / 0 / 0
Регистрация: 08.03.2015
Сообщений: 12
29.05.2016, 14:35  [ТС] 7
Переделал код, даже оставил sysdate без изменений.
Oracle 11 SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE OR REPLACE TRIGGER BeforeUpdateDetaliProdazh
before UPDATE OF Дата_Заказа ON Детали_Продаж 
FOR each ROW
DECLARE
 cant_change_datazak EXCEPTION;
 PRAGMA EXCEPTION_INIT(cant_change_datazak, -2290); 
BEGIN
IF :NEW.Дата_Отпр IS NULL OR :NEW.Дата_Отпр >= SYSDATE THEN 
   :NEW.Дата_Отпр := SYSDATE + 1;
   :NEW.Дата_Заказа:=:OLD.Дата_Заказа;
   :NEW.Кол_во_зак:=:OLD.Кол_во_зак;
ELSIF :NEW.Дата_Отпр <= SYSDATE THEN 
   RAISE cant_change_datazak;
END IF;
EXCEPTION
    WHEN cant_change_datazak THEN
    dbms_output.put_line('Нельзя изменить дату заказа, т.к. заказ еще не выполнен!');
    :NEW.Дата_Отпр:=:old.Дата_Отпр;
    :NEW.Дата_Заказа:=:old.Дата_Заказа;
    :NEW.Кол_во_зак:=:old.Кол_во_зак;
END;
И теперь, начал изменять первую строку таблицы, изменил Дату_Отпр с июня месяца на май. Выдает следующую ошибку:
Мутация триггера запрещающего изменять данные

Что делать?
0
476 / 239 / 114
Регистрация: 12.05.2016
Сообщений: 647
29.05.2016, 21:21 8
У вас выдает ошибку совсем другой триггер с другим названием.
А не тот, который вы тут привели. Почитайте внимательно сообщение.

Естественно "заглянуть" к вам в другой триггер сами мы не в состоянии. Все телепаты в отпуске.
0
0 / 0 / 0
Регистрация: 08.03.2015
Сообщений: 12
29.05.2016, 22:32  [ТС] 9
я дропнул тот триггер, просто мне говорили мутацию исправить можно только создав другой триггер, с глобальной переменной, как то так, а так вроде все работает, но мне нужно было брать в условии не всю дату, а только год, к примеру так:
Oracle 11 SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE OR REPLACE TRIGGER BeforeUpdateDetaliProdazh
before UPDATE OF Дата_Заказа ON Детали_Продаж 
FOR each ROW
DECLARE
 cant_change_datazak EXCEPTION;
 PRAGMA EXCEPTION_INIT(cant_change_datazak, -2290); 
BEGIN
IF :NEW.Дата_Отпр IS NULL OR :NEW.Дата_Отпр >= EXTRACT(YEAR FROM SYSDATE) THEN 
   :NEW.Дата_Отпр := SYSDATE + 1;
   :NEW.Дата_Заказа:=:OLD.Дата_Заказа;
   :NEW.Кол_во_зак:=:OLD.Кол_во_зак;
ELSIF :NEW.Дата_Отпр <= SYSDATE THEN 
   RAISE cant_change_datazak;
END IF;
EXCEPTION
    WHEN cant_change_datazak THEN
    dbms_output.put_line('Нельзя изменить дату заказа, т.к. заказ еще не выполнен!');
    :NEW.Дата_Отпр:=:old.Дата_Отпр;
    :NEW.Дата_Заказа:=:old.Дата_Заказа;
    :NEW.Кол_во_зак:=:old.Кол_во_зак;
END;
но выдает ошибку по 5 строке.
0
476 / 239 / 114
Регистрация: 12.05.2016
Сообщений: 647
29.05.2016, 23:10 10
Год сравнить можно так:

SQL
1
2
3
4
5
   IF TRUNC(:NEW.DT,'YY') =  TRUNC(SYSDATE,'YY') THEN
      год в датах совпадает
   ELSE
      год в датах не совпадает
   END IF;
Но вы сначала всё-таки по русски опишите скажите смысл ваших манипуляций с датами (отбора только года).
Вот бумажку возьмите и прям ручкой напишите:

"Я хочу чтобы для всех заказов, у которых дата отправления такая-то, происходило то-то"

А уже потом пробуйте эти русские фразы воплощать в коде. А то нахреначат условий, потом сами не могут объяснить зачем.

Глядя на ваш код:
Вы правда хотите для всех заказов, у которых дата отправления пустая или попадает в текущий год, исправить её на "завтра" ??

Но тогда у вас второе условие (ELSIF) вообще никогда не сработает (вернее сработает только если попробовать на ПРОШЛЫЙ год поменять дату отправления ...
1
29.05.2016, 23:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.05.2016, 23:10
Помогаю со студенческими работами здесь

Как изменять данные, отображаемые в Chart?
Доброго времени суток. Вопрос о Chart. Нужно чтобы при нажатии на определенную кнопку график...

Запретить пользователю изменять данные в файле
Добрый день. Подскажите, пожалуйста, как правильно осуществить и (или) в каком направлении...

Как периодически изменять данные в таблице?
Есть 2 таблицы А И Б. В таблицу А автоматически считываются и записываются данные датчиков. Нужно...

Как изменять данные во внешних базах ?
Создал связь c Access 97 через связанные серверы, теперь хочу изменить данные в таблице ACCESS...

Можно ли на печатной форме изменять данные?
Мне нужно на печатной форме, которая отправляется в файле PDF клиенту, как предварительный макет на...

Как изменять данные в array.map?
Использую данный код, но вот данные не преобразуются не пойму почему Order.find() ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru