Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.5 MB
Время: 0.019 c
3-53894
Destroyer
2003-02-25 08:51
2003.03.17
Автоинкрементное поле


8-54118
Berser
2002-12-06 01:20
2003.03.17
Запись звука с тел лин с помощью AsuncPro


3-53945
Choo
2003-02-26 15:07
2003.03.17
Репликация БД


9-53826
Николай Быков
2002-10-14 19:40
2003.03.17
Чего здесь не хватает?


14-54235
@lex
2003-02-27 16:52
2003.03.17
Посчитать угол по 3 точкам