powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Мутирование таблицы
25 сообщений из 44, страница 1 из 2
Мутирование таблицы
    #39455709
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. При записи пациента на прием проводится проверка на наличие у него приемов в промежутке (+-20 мин). Если есть, то запретить вставку. При вставке проблем не возникает, но при обновлении поля выдает ошибку о мутировании таблицы. Что это за ошибка и почему она возникает, я понимаю, но вот куда мне деть SELECT? Как обойти мутирование? Или на что его заменить?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
create or replace trigger Available_Patient
before insert or update on APPOINTMENT
FOR EACH ROW follows check_schedule
DECLARE
count_app_of_pat NUMBER(10);
Available_Patients BOOLEAN :=FALSE;
ST DATE;
FN DATE;
POINTER DATE;
begin
SELECT Count(*) into count_app_of_pat 
FROM APPOINTMENT 
WHERE :new.policy_number = policy_number AND
data_appointment = :new.data_appointment AND
ABS(to_date(:new.time, 'hh24:mi') - to_date(time, 'hh24:mi'))*24*60<20;

Available_Patients := count_app_of_pat=0;

IF NOT (Available_Patients) THEN 
raise_application_error(-20011,'Пациент в это время на приеме!');
END IF;
END;
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455710
Q.Tarantino
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
оракл так и пишет - "таблица мутирована"?
а номер ошибки там прилагается?
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455712
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Q.Tarantino, авторORA-04091: table name is mutating, trigger/function may not see it
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455756
Фотография Vladimir Filin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pastkhuf,
Oracle 11R2:
If you must use a trigger to update a mutating table, you can avoid the mutating-table error in either of these ways:

- Use a compound DML trigger (see "Using Compound DML Triggers to Avoid Mutating-Table Error").

- Use a temporary table.
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455757
Фотография Vladimir Filin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir Filin,
Mutating-Table Restriction
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#g1699708

Using Compound DML Triggers to Avoid Mutating-Table Error
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#CHDFEBFJ
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455765
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vladimir Filin,
Я эту теорию заранее просмотрел, у меня проблема с практикой. Я не знаю, как в моем случаем писать составной триггер?
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455768
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vladimir Filin, мне ее обновлять даже не надо, просто посчитать количество определенных строк
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455769
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vladimir Filin, если записать в before statement, то вообще триггер никак не будет реагировать на вставку, а after всегда выдает ошибку, даже если в таблице нет строк
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
create or replace trigger testone
  for update on appointment
  compound trigger
    count_app_of_pat NUMBER(10);
    patient number(10);
    dat date;
    timeapp varchar2(5);
    
     before each row is
     begin
     dat := :new.data_appointment;
     timeapp := :new.time;
     patient := :new.policy_number;
     end before each row;
     
     after statement is
     begin
     SELECT Count(*) into count_app_of_pat  
     FROM APPOINTMENT 
     WHERE patient = policy_number AND
     data_appointment = dat AND
     ABS(to_date(timeapp, 'hh24:mi') - to_date(time, 'hh24:mi'))*24*60<20;

     IF NOT (count_app_of_pat=0) THEN 
     raise_application_error(-20011,'Пациент в это время на приеме!');
     END IF;
     end after statement;

end testone;
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455834
tru55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТОП популярных вопросов конечно уже прочитал?
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455849
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tru55,
Да, конечно, поэтому и пишу, что не получается
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455927
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
почему мне никто не хочет помочь, может я тему неудачно назвал...
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455928
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pastkhuf,

А с чем связана реализация на уровне триггера?
Сколько сессий одновременно могут добавлять записи по одному пациенту?
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455936
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
env,
задача: если у пациента есть уже прием, то его нельзя записать на прием в интервале 20 мин до и после.
Я считаю в триггере эти строки, если их количество не равно 0, но запретить вставку.

Несколько сессий
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455947
Anatoly B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
pastkhuf,
Код: plsql
1.
     IF NOT (count_app_of_pat=0) THEN 


Почему сравнение с нулем?
проапдейтили/вставили одну запись, запросом ее нашли,сравнили с нулем....
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39455962
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly B,
я делаю то же самое. Если количество запей в интервале 20 мин не равно нулю, то запрещаю вставку. Там с логикой все хорошо, проблема в том, что оракл не дает возможность считывать данные из той же таблицы. То есть если бы я считал что-то из другой таблицы, ошибки бы не было
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39456069
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pastkhuf,

Выполняйте команду SELECT в триггере типа AFTER уровня statement (не for each row!).
Для такого триггера уже будет согласованное состояние данных таблицы и вы сможете избежать описываемых ошибок.
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39456115
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pastkhufЕсли количество запей в интервале 20 мин, включая только что вставленную и потому попавшую в сравнение запись, pastkhufне равно нулю
Да, действительно, с чего бы тут ошибке быть...
Ведь тут
pastkhufс логикой все хорошо, проблема в том, что оракл не дает
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39456117
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SQL*Plus,
Ну мне же нужно предотвратить вставку, если пациент в это время на приеме!
Даже если так, я ж в составном триггере выполняю SELECT в after statement?
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39456132
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
env,
прошу прощения, признаю ошибку, но я имел введу в первом запросе не ошибки, когда я SELECT выполнял до вставки. Теперь все работает, спасибо всем большое!
Я правильно понимаю: after statemen срабатывает после вставки, тогда, если возникает ошибка, то результат откатывается?
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39456169
XMLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
envpastkhuf,

А с чем связана реализация на уровне триггера?
Сколько сессий одновременно могут добавлять записи по одному пациенту?
100500 сессий. Как это влияет на выбор уровня триггера.
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39456180
XMLerenvpastkhuf,

А с чем связана реализация на уровне триггера?
Сколько сессий одновременно могут добавлять записи по одному пациенту?
100500 сессий. Как это влияет на выбор уровня триггера.это влияет на выбор уровня изоляции, блокировки таблицы или иных до/вместо триггерных действий по обеспечению целостности.
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39456192
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pastkhufналичие у него приемов в промежутке (+-20 мин)достаточно уникального индекса.
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39456204
Фотография Vladimir Filin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pastkhuf Теперь все работает, ...
Вот и славно! После торжественного омывания нового триггера в достойной жидкости, есть смысл спокойно почитать пару (как минимум) тем про подобные задачки. На усмотрение pastkhuf, разумеется.
dbms_photoshop.... Читай эту тему Задачка

Владимир Бегун Базовая идея тут . Это не триггер, но для некоторых случаев позволяет решить задачку. Кодирование, обход мутаций и обеспечение целостности данных при конкурентном изменении данных в таблице -- это ряд вещей, над которыми приходится задумываться решая эту и подобные ей задачи используя DIY-методы.
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39456211
XMLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
непересекающиеся интервалы иных до/вместо триггерных действий по обеспечению целостности.
Триггер- инструмент, обеспечение целостности- целевая функция. Инструменты могут быть разные, уникальный индекс- на мой взгляд, предпочтительнее.
...
Рейтинг: 0 / 0
Мутирование таблицы
    #39456215
pastkhuf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-2-,
недостаточно. Если я хочу записаться на 11:30, то у меня не должно быть приемов с 11:10 по 11:50
...
Рейтинг: 0 / 0
25 сообщений из 44, страница 1 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Мутирование таблицы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]