Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с тригером [D5]


Дмитрий Орехов ©   (2002-11-27 16:19:00) 

CREATE OR REPLACE TRIGGER Trig_Norma_V_Ins
BEFORE INSERT ON NORMA_V
FOR EACH ROW
BEGIN
if :new.KodR="001" then
INSERT INTO Norma_V(Year, MM, KodC, KodR, KodY, KodP, KodT,
"PLAN", Fact)
values(:new.Year, :new.MM, :new.KodC, "002", :new.KodY,
:new.KodP, :new.KodT, :new."PLAN", :new.Fact);
end if;
END Trig_Norma_V_Ins;

То есть при вставке строки с KodR="001" должна создаваться такая же строка с KodR="002". При вставке вручную все идет нормально. Проблема возникает при вставки в программе Insert"ом нескольких строк. Выдается сообщение
ORA-04091: table Norma_V mutating, trigger/function may not see it
ORA-06512: at "TRIGGER Trig_Norma_V_Ins", line 3
ORA-04088: error during execution of trigger "TRIGGER Trig_Norma_V_Ins"
Из-за чего это происходит и что можно сделать?


Yuvich   (2002-11-28 17:53:00) [1]

> Дмитрий Орехов
"... Надо просто обнулять индекс в конце второго триггера."
Это и есть очистка массива.

"... Дополнительный тригер для очистки массива не нужен ..."
Вопрос потребностей - может данные еще нужны после тригера?
Это из разряда "что лучше?": while или repeat until.

Если Оракле версии после 8.1.6, то вместо массива можно использовать временную таблицу - с таблицей все ж привычнее.


Дмитрий Орехов   (2002-11-28 15:02:00) [2]

Есть. Я его сделал. Через массив. Спасибо всем.


petr_v_a   (2002-11-28 15:01:00) [3]

Дмитрий Орехов (28.11.02 07:44)
> to petr_v_a: Еще б он у меня был.

Есть, например, на http://jedi.kosnet.ru/links/oracle/
Подсказка: есть такие рулезные сайты, www.yandex.ru и www.google.com


Дмитрий Орехов   (2002-11-28 14:49:00) [4]

2Yuvich: Я нашел в литературе про этот способ. Но реализовать его мне пока неудается. Дополнительный тригер для очистки массива не нужен. Надо просто обнулять индекс в конце второго триггера.


Andriano   (2002-11-28 14:16:00) [5]

Да как вы вообще собираетесь из тригера BEFORE INSERT выполнять INSERT. Вы же получаете бесконечное зацикливание. Точнее получили бы, если SQL сервер стал бы это выполнять.

Есл у вас такое получиться - научите меня пожалуйста.


Yuvich   (2002-11-28 14:06:00) [6]

> Дмитрий Орехов

Ну тогда надо сделать так:

В тригере уровня записи (FOR EACH ROW) делать проверку на :new.KodR = "001". Если истинно, то надо заполнять внутренний PL/SQL массив. Надо написать еще один тригер уровня таблицы after insert (без FOR EACH ROW) - читать сформированный массив и делать дополнительные инсерты с :new.KodR := "002". Нужен еще один тригер уровня таблицы before insert, что бы этот массив очищать.


Sergey13   (2002-11-28 09:11:00) [7]

2Дмитрий Орехов (27.11.02 16:19)
> а мне надо еще одну строку.
ИМХО, тебя выручит только автономная транзакция. Т.е. в тригере надо
if :new.KodR = "001" then
myFunc(:new.....);
end if;
где в myFunc должна стоять pragma autonomous_transaction и в ней вставлять вторую строку. Иначе - мутация однозначно.


Дмитрий Орехов   (2002-11-28 07:44:00) [8]

to Yuvich: Это не то. У тебя происходит замена в той же строке, а мне надо еще одну строку.
to petr_v_a: Еще б он у меня был.


Yuvich   (2002-11-27 20:24:00) [9]

Так делать нельзя.
Надо переписать триггер так:
CREATE OR REPLACE TRIGGER Trig_Norma_V_Ins
BEFORE INSERT ON NORMA_V
FOR EACH ROW
BEGIN
if :new.KodR = "001" then
:new.KodR := "002"
end if;
END Trig_Norma_V_Ins;


insert сделает сам Oracle - надо только подставить нужные данные.


petr_v_a   (2002-11-27 20:13:00) [10]

Oracle Application Developer"s Guide chapter <не помню> "Using Database Triggers".


Наверх

Титульная страница Поиск, карта сайта Написать письмо