Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Мутирование таблицы / 25 сообщений из 44, страница 1 из 2
18.05.2017, 22:39
    #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
18.05.2017, 22:45
    #39455710
Q.Tarantino
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Мутирование таблицы
оракл так и пишет - "таблица мутирована"?
а номер ошибки там прилагается?
...
Рейтинг: 0 / 0
18.05.2017, 22:50
    #39455712
pastkhuf
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Мутирование таблицы
Q.Tarantino, авторORA-04091: table name is mutating, trigger/function may not see it
...
Рейтинг: 0 / 0
19.05.2017, 03:01
    #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
19.05.2017, 03:08
    #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
19.05.2017, 05:09
    #39455765
pastkhuf
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Мутирование таблицы
Vladimir Filin,
Я эту теорию заранее просмотрел, у меня проблема с практикой. Я не знаю, как в моем случаем писать составной триггер?
...
Рейтинг: 0 / 0
19.05.2017, 05:17
    #39455768
pastkhuf
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Мутирование таблицы
Vladimir Filin, мне ее обновлять даже не надо, просто посчитать количество определенных строк
...
Рейтинг: 0 / 0
19.05.2017, 05:34
    #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
19.05.2017, 09:25
    #39455834
tru55
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Мутирование таблицы
ТОП популярных вопросов конечно уже прочитал?
...
Рейтинг: 0 / 0
19.05.2017, 09:51
    #39455849
pastkhuf
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Мутирование таблицы
tru55,
Да, конечно, поэтому и пишу, что не получается
...
Рейтинг: 0 / 0
19.05.2017, 10:59
    #39455927
pastkhuf
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Мутирование таблицы
почему мне никто не хочет помочь, может я тему неудачно назвал...
...
Рейтинг: 0 / 0
19.05.2017, 11:03
    #39455928
env
env
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Мутирование таблицы
pastkhuf,

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

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


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

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

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

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

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


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