Форум: "Базы";
Текущий архив: 2002.12.16;
Скачать: [xml.tar.bz2];
ВнизПроблема с тригером Найти похожие ветки
← →
Дмитрий Орехов (2002-11-27 16:19) [0]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"
Из-за чего это происходит и что можно сделать?
← →
petr_v_a (2002-11-27 20:13) [1]Oracle Application Developer"s Guide chapter <не помню> "Using Database Triggers".
← →
Yuvich (2002-11-27 20:24) [2]Так делать нельзя.
Надо переписать триггер так:
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 - надо только подставить нужные данные.
← →
Дмитрий Орехов (2002-11-28 07:44) [3]to Yuvich: Это не то. У тебя происходит замена в той же строке, а мне надо еще одну строку.
to petr_v_a: Еще б он у меня был.
← →
Sergey13 (2002-11-28 09:11) [4]2Дмитрий Орехов (27.11.02 16:19)
> а мне надо еще одну строку.
ИМХО, тебя выручит только автономная транзакция. Т.е. в тригере надо
if :new.KodR = "001" then
myFunc(:new.....);
end if;
где в myFunc должна стоять pragma autonomous_transaction и в ней вставлять вторую строку. Иначе - мутация однозначно.
← →
Yuvich (2002-11-28 14:06) [5]> Дмитрий Орехов
Ну тогда надо сделать так:
В тригере уровня записи (FOR EACH ROW) делать проверку на :new.KodR = "001". Если истинно, то надо заполнять внутренний PL/SQL массив. Надо написать еще один тригер уровня таблицы after insert (без FOR EACH ROW) - читать сформированный массив и делать дополнительные инсерты с :new.KodR := "002". Нужен еще один тригер уровня таблицы before insert, что бы этот массив очищать.
← →
Andriano (2002-11-28 14:16) [6]Да как вы вообще собираетесь из тригера BEFORE INSERT выполнять INSERT. Вы же получаете бесконечное зацикливание. Точнее получили бы, если SQL сервер стал бы это выполнять.
Есл у вас такое получиться - научите меня пожалуйста.
← →
Дмитрий Орехов (2002-11-28 14:49) [7]2Yuvich: Я нашел в литературе про этот способ. Но реализовать его мне пока неудается. Дополнительный тригер для очистки массива не нужен. Надо просто обнулять индекс в конце второго триггера.
← →
petr_v_a (2002-11-28 15:01) [8]Дмитрий Орехов (28.11.02 07:44)
> to petr_v_a: Еще б он у меня был.
Есть, например, на http://jedi.kosnet.ru/links/oracle/
Подсказка: есть такие рулезные сайты, www.yandex.ru и www.google.com
← →
Дмитрий Орехов (2002-11-28 15:02) [9]Есть. Я его сделал. Через массив. Спасибо всем.
← →
Yuvich (2002-11-28 17:53) [10]> Дмитрий Орехов
"... Надо просто обнулять индекс в конце второго триггера."
Это и есть очистка массива.
"... Дополнительный тригер для очистки массива не нужен ..."
Вопрос потребностей - может данные еще нужны после тригера?
Это из разряда "что лучше?": while или repeat until.
Если Оракле версии после 8.1.6, то вместо массива можно использовать временную таблицу - с таблицей все ж привычнее.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.12.16;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.006 c