Текущий архив: 2003.03.17;
Скачать: CL | DM;
Вниз
SQL и триггер Найти похожие ветки
← →
Geka (2003-02-25 10:19) [0]Есть база Т1 и Т2
CREATE TABLE Т1
(
KOD NUMBER(10) PRIMARY KEY,
NOMER VARCHAR2(10) NOT NULL,
KOD_OTDEL NUMBER(3),
DATA_BEGIN DATE NOT NULL
);
ALTER TABLE T1 ADD CONSTRAINT FK1_T1
FOREIGN KEY (KOD_OTDEL) REFERENCES T2;
И триггер:
CREATE TRIGGER ATC.T1_INS BEFORE INSERT
ON ATC.T1
FOR EACH ROW
WHEN ( NEW.KOD IS NULL )
Begin
select max(KOD) + 1 into :new.KOD from ATC.T1;
if :new.KOD is null then
:new.KOD := 1;
end if;
End;
Если я добавляю данные
insert into history_nomer(nomer, kod_otdel, data_begin)
values ("111",1,to_date("25022003","ddmmyyyy")
то все работает.
А если я данные беру из другой таблицы,
insert into history_nomer(nomer, kod_otdel, data_begin)
select t.nomer,t.kod_otdel,to_date("25022003","ddmmyyyy")
from T3 t
where length(t.nomer)=4 and t.nomer like "2%"
то пишет ошибку
[1]: (Error): ORA-04091: table ATC.T1 is mutating, trigger/function may not see it ORA-06512: at "ATC.T1_INS", line 2 ORA-04088: error during execution of trigger "ATC.T1_INS"
Не могу понять где ошибка...
← →
Geka (2003-02-25 10:25) [1]Базы на Оракле
← →
Johnmen (2003-02-25 10:38) [2]1. см. директиву прекомпилятора PRAGMA
2. Так не получают очередное значение !!! см. Последовательности
3. Разберись с терминологией (база/таблица)
← →
Geka (2003-02-25 10:39) [3]Можно конкретный ответ, вопрос, по-моему, подробный
← →
Hawk2 (2003-02-25 10:43) [4]С Ораклом не знаком, но вот запрос мне твой не нравится:
insert into history_nomer(nomer, kod_otdel, data_begin)
select t.nomer,t.kod_otdel, to_date("25022003","ddmmyyyy")
from T3 t
where length(t.nomer)=4 and t.nomer like "2%"
ты делаешь выборку из таблицы Т3, но в ней нет поля to_date("25022003","ddmmyyyy"). Возможно поэтому и ругается. И кроме этого межет быть еще куча проблем, несоответствие типа полей или может быть даже их длины и т.д.
← →
passm (2003-02-25 10:43) [5]Geka © (25.02.03 10:19)> На DB2 смотрится несколько по другому, но суть та же. Посмотри - может, поможет :)
CREATE TRIGGER ACT.T2_INS
BEFORE INSERT ON ACT.T1
REFERENCES NEW AS NEWROW
FOR EACH ROW
MODE DB2SQL
BEGIN ATHOMIC
SET NEWROW.COD = (SELECT COALESCE(MAX(Q1.COD), 0) + 1 FROM ACT.T1 AS Q1);
END
COALESCE(X1, X2) = X1 если X1 IS NOT NULL иначе = X2
← →
Johnmen (2003-02-25 10:47) [6]>Geka © (25.02.03 10:39)
>Можно конкретный ответ, вопрос, по-моему, подробный
Подробность вопроса не означает его конкретности...
А, во-вторых, я дал конкретный и исчерпывающий ответ.
А если тебе лень смотреть документацию - это твои проблемы...:)
← →
Geka (2003-02-25 10:50) [7]Hawk2
Это не поле, это так в Оракл дату заносят, ну как строку например.
passm
Ну у меня вроде примерно так и написано(вроде логика такая же)
Прикол в том, что на остальных таблицах такие же триггеры работают. Правда там не было необходимости забрасывать данные пачками :-)
← →
Geka (2003-02-25 10:54) [8]К вопросу о других
CREATE TABLE Т2
(
KOD NUMBER(3) PRIMARY KEY ,
NAME VARCHAR(100) NOT NULL
);
CREATE TABLE T3
(
NOMER VARCHAR2(10) PRIMARY KEY ,
KOD_OTDEL NUMBER(3, 0) NOT NULL,
ABONENT VARCHAR2(100) NOT NULL
);
Примерно так
← →
Sergey13 (2003-02-25 11:14) [9]2Geka © (25.02.03 10:19)
Все правильно. Ты в тригере пытаешься читать таблицу которая изменяется в данный момент - т.е. саму себя. Классическая мутация. Тут надо смотреть на логику приложения. Во первых я бы разделил понятие кода и последовательного номера документа. Первый может быть непоследовательным и его значение надо брать из последовательности а не вычислять. Второе надо (если надо) делать в отдельной процедуре после вставки записи в таблицу.
Удивительно не то что во втором твоем запросе не работает, а то что работает в первом. Потому что работать это будет только если давать KOD напрямую в VALUES, когда срабатывает условие в тригере.
← →
Hawk2 (2003-02-25 11:20) [10]Я понимаю что тебе нужно внести дату, но в операторе SELECT перечисляются поля таблицы, и строку to_date("25022003","ddmmyyyy"), программа воспринимает не как функцию, а как поле и пытается найти его в таблице Т3. Скажи если я не прав, может в оракле SQL поддерживает такие возможности? Но все же попробуй в запросе убрать эту строчку, что получется.
← →
Внук (2003-02-25 11:21) [11]ORA-04091 table string.string is mutating, trigger/function may not see it
Cause: A trigger (or a user defined PL/SQL function that is referenced in this statement) attempted to look at (or modify) a table that was in the middle of being modified by the statement which fired it.
Action: Rewrite the trigger (or function) so it does not read that table.
Вот это почитайте внимательно
http://otn.oracle.com/pls/tahiti/tahiti.drilldown?word=mutating&verb=Mutating&expand_all=1&method=LIKE&remark=Verb+hint
← →
Sergey13 (2003-02-25 11:31) [12]2Hawk2 (25.02.03 11:20)
> Скажи если я не прав,
Ты не прав.
← →
Hawk2 (2003-02-25 11:57) [13]То Sergey13: Спасибо.
Страницы: 1 вся ветка
Текущий архив: 2003.03.17;
Скачать: CL | DM;
Память: 0.47 MB
Время: 0.008 c