Форум: "Базы";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];
ВнизПочему могут глючить триггера в IB6x? Найти похожие ветки
← →
Prohodil Mimo © (2005-01-18 18:07) [0]Проблема такая:
написал несколько триггеров, которые при изменении значений одного поля в одной таблице, меняют значения в определённом поле другой таблицы. В основном всё работает нормально и изменяется всё как положено, но иногда значение не изменяется, то ли триггер не срабатывает, то ли ещё что. Может это быть из за транзакций? (перед изменениями в первой таблице открываю транзакцию, изменяю, закрываю тр.)
хотя в основном же работает.
подскажите куда копать.
спасибо.
← →
Johnmen © (2005-01-18 18:21) [1]Должно работать...
Если интересно более детальное рассмотрение, приводи подробности. В т.ч. структуру таблиц, тела триггеров, описание ключей и индексов...
← →
Desdechado © (2005-01-18 18:40) [2]1. триггеры друг друга каскадно не заставляют срабатывать?
2. закрываю транзакцию - откатываешь или подтверждаешь? или тебе без разницы?
← →
Prohodil Mimo © (2005-01-19 10:18) [3]Johnmen © (18.01.05 18:21) [1]
Если интересно более детальное рассмотрение, приводи подробности
Многовато текста, да и объяснять много. Не охота народ нагружать. Мне бы возможные причины, а там бы я сам проверил.
Desdechado © (18.01.05 18:40) [2]
1. триггеры друг друга каскадно не заставляют срабатывать?
Триггер вызывает ХП, которая либо делает изменения в той же таблице, либо не делает, в зависимости от значений полей. После вызывается ХП изменяющая значения другой таблицы.
2. закрываю транзакцию - откатываешь или подтверждаешь? или тебе без разницы?
Если где либо ошибка - откатываю все изменения. Если всё нормально, то подтверждаю.
DM.pFIBTrAct1.StartTransaction;
Try
{SQL запрос на Insert/Update}
DM.pFIBTrAct1.CommitRetaining;
Except
DM.pFIBTrAct1.RollbackRetaining;
End;
← →
Johnmen © (2005-01-19 10:22) [4]>Триггер вызывает ХП, которая либо делает изменения в той же таблице
Вот и потенциальное место возникновения рекурсии...
← →
Prohodil Mimo © (2005-01-19 11:29) [5]Johnmen © (19.01.05 10:22) [4]
Вот и потенциальное место возникновения рекурсии...
Может влиять? можно поподробнее?
У меня первая таблица с древовидной структурой. При изменении значения поля ветки - значение подымается вверх что бы было нечто подобное:
- 20
- 10
- 2
- 8
- 10
- 5
- 5
Но почему для одной и той же ветки может сработать, а может и нет?
Такое чувство что триггер не всегда успевает выполнить действия, а транзакция закрывается. Но такое разве возможно?
← →
Johnmen © (2005-01-19 11:33) [6]>Prohodil Mimo © (19.01.05 11:29) [5]
Ты не приводишь информации для анализа. Поэтому ничего сказать нельзя...
Кроме того, что
>Но такое разве возможно?
нет, ибо чушь...:)
← →
Prohodil Mimo © (2005-01-19 12:02) [7]Johnmen © (19.01.05 11:33) [6]
>Но такое разве возможно?
нет, ибо чушь...:)
вот и я о том же.
ладно, есть таблица договоров:
CREATE TABLE PROJEKT
(
ID_PR INTEGER Not Null,
PR_NOS VARCHAR(102),
CP_NUM INTEGER,
PR_STUND INTEGER,
PR_CENA DOUBLE PRECISION,
PR_ASTUND DOUBLE PRECISION,
PR_MSTUND DOUBLE PRECISION,
PR_MCENA DOUBLE PRECISION,
PR_CCENA DOUBLE PRECISION,
PR_FCENA DOUBLE PRECISION,
PR_PVCENA DOUBLE PRECISION,
PR_PCENA DOUBLE PRECISION,
PR_TCENA DOUBLE PRECISION,
PRIMARY KEY (ID_PR)
);
под ней таблица конструкций, организована в виде дерева, что бы большие конструкции при желанииможно было розложить на более мелкие.
CREATE TABLE SUB_KON
(
ID_SKON INTEGER Not Null,
ID_PR INTEGER,
SKON_NUM INTEGER,
SKON_NOS VARCHAR(30),
SKON_STUND DOUBLE PRECISION,
SKON_ASTUND DOUBLE PRECISION,
SKON_MONT INTEGER,
SKON_CENA DOUBLE PRECISION,
SKON_FCENA DOUBLE PRECISION,
IETILP_ID INTEGER,
SKON_STUND2 DOUBLE PRECISION,
SKON_CENA2 DOUBLE PRECISION,
SKON_FCENA2 DOUBLE PRECISION,
SKON_CAUTO INTEGER,
SKON_FAKTSTUND DOUBLE PRECISION,
PRIMARY KEY (ID_SKON)
);
триггеры и ХП:
все триггеры на SUB_KON.
CREATE TRIGGER SUB_KON_B_INSERT FOR SUB_KON
BEFORE INSERT
AS BEGIN
NEW.SKON_ASTUND = NEW.SKON_STUND;
IF (NEW.SKON_FAKTSTUND IS NULL) THEN
NEW.SKON_FAKTSTUND = 0;
END;
---------
CREATE TRIGGER SUB_KON_A_INSERT FOR SUB_KON
AFTER INSERT
AS BEGIN
EXECUTE PROCEDURE SET_SKON_CEN_SUM NEW.IETILP_ID, NEW.SKON_MONT, NEW.SKON_CENA, NEW.SKON_STUND, NEW.SKON_FCENA, 0, 0, 0;
IF (NOT NEW.SKON_MONT IS NULL) THEN
EXECUTE PROCEDURE SET_PROJ_CEN_SUM NEW.ID_PR, NEW.IETILP_ID, NEW.SKON_MONT, NEW.SKON_CENA, NEW.SKON_STUND, NEW.SKON_FCENA, 0, 0, 0;
END;
--------
CREATE TRIGGER SUB_KON_B_UPDATE FOR SUB_KON
BEFORE UPDATE
AS BEGIN
IF (NEW.SKON_CAUTO = 1) THEN
BEGIN
NEW.SKON_STUND = NEW.SKON_STUND2;
NEW.SKON_CENA = NEW.SKON_CENA2;
NEW.SKON_FCENA = NEW.SKON_FCENA2;
END
IF (NEW.SKON_STUND <> OLD.SKON_STUND) THEN
NEW.SKON_ASTUND = OLD.SKON_ASTUND+(NEW.SKON_STUND - OLD.SKON_STUND);
END;
-----------
CREATE TRIGGER SUB_KON_A_UPDATE FOR SUB_KON
AFTER UPDATE
AS
DECLARE VARIABLE TEK_SKON_MONT INTEGER;
BEGIN
IF ((NEW.SKON_STUND <> OLD.SKON_STUND) OR (NEW.SKON_CENA <> OLD.SKON_CENA) OR
(NEW.SKON_FCENA <> OLD.SKON_FCENA)) THEN
EXECUTE PROCEDURE SET_SKON_CEN_SUM NEW.IETILP_ID, NEW.SKON_MONT, NEW.SKON_CENA, NEW.SKON_STUND, NEW.SKON_FCENA, OLD.SKON_CENA, OLD.SKON_STUND, OLD.SKON_FCENA;
ELSE
IF ((NEW.SKON_ASTUND <> OLD.SKON_ASTUND) OR (NEW.SKON_FAKTSTUND <> OLD.SKON_FAKTSTUND)) THEN
BEGIN
IF (NEW.SKON_STUND = OLD.SKON_STUND) THEN
EXECUTE PROCEDURE SET_SKON_ASTUND NEW.IETILP_ID, NEW.SKON_MONT, NEW.SKON_ASTUND, OLD.SKON_ASTUND, NEW.SKON_FAKTSTUND, OLD.SKON_FAKTSTUND;
EXECUTE PROCEDURE SET_PROJ_ASTUND NEW.ID_PR, NEW.IETILP_ID, NEW.SKON_MONT, NEW.SKON_ASTUND, OLD.SKON_ASTUND, NEW.SKON_FAKTSTUND, OLD.SKON_FAKTSTUND;
END
IF ((NEW.SKON_STUND <> OLD.SKON_STUND) OR (NEW.SKON_CENA <> OLD.SKON_CENA) OR (NEW.SKON_FCENA <> OLD.SKON_FCENA)) THEN
EXECUTE PROCEDURE SET_PROJ_CEN_SUM NEW.ID_PR, NEW.IETILP_ID, NEW.SKON_MONT, NEW.SKON_CENA, NEW.SKON_STUND, NEW.SKON_FCENA, OLD.SKON_CENA, OLD.SKON_STUND, OLD.SKON_FCENA;
END;
-----------
CREATE TRIGGER SUB_KON_A_DELETE FOR SUB_KON
AFTER DELETE
AS BEGIN
EXECUTE PROCEDURE SET_SKON_CEN_SUM OLD.IETILP_ID, OLD.SKON_MONT, 0, 0, 0, OLD.SKON_CENA, OLD.SKON_STUND, OLD.SKON_FCENA;
IF (NOT OLD.SKON_MONT IS NULL) THEN
EXECUTE PROCEDURE SET_PROJ_CEN_SUM OLD.ID_PR, OLD.IETILP_ID, OLD.SKON_MONT, 0, 0, 0, OLD.SKON_CENA, OLD.SKON_STUND, OLD.SKON_FCENA;
END;
---------
CREATE PROCEDURE SET_SKON_CEN_SUM(IETILPID INTEGER, SKONMONT INTEGER,
SKONCENA DOUBLE PRECISION, SKONSTUND DOUBLE PRECISION, SKONFCENA DOUBLE PRECISION,
OLDSKONCENA DOUBLE PRECISION, OLDSKONSTUND DOUBLE PRECISION, OLDSKONFCENA DOUBLE PRECISION)
AS
DECLARE VARIABLE TEK_SKON_MONT INTEGER;
BEGIN
SKONCENA = :SKONCENA - OLDSKONCENA;
SKONFCENA = :SKONFCENA - OLDSKONFCENA;
SKONSTUND = :SKONSTUND - OLDSKONSTUND;
IF (:SKONCENA IS NULL) THEN
SKONCENA = 0;
IF (:SKONFCENA IS NULL) THEN
SKONFCENA = 0;
IF (:SKONSTUND IS NULL) THEN
SKONSTUND = 0;
IF (:IETILPID > 0) THEN
BEGIN
SELECT SKON_MONT
FROM SUB_KON
WHERE ID_SKON = :IETILPID
INTO :TEK_SKON_MONT;
END
IF ((:IETILPID > 0) AND (NOT :TEK_SKON_MONT IS NULL) AND (:TEK_SKON_MONT = SKONMONT)) THEN
BEGIN
UPDATE SUB_KON
SET SKON_STUND2 = SKON_STUND2 + :SKONSTUND,
SKON_CENA2 = SKON_CENA2 + :SKONCENA,
SKON_FCENA2 = SKON_FCENA2 + :SKONFCENA
WHERE ID_SKON = :IETILPID;
END
END;
----------
CREATE PROCEDURE SET_PROJ_CEN_SUM(IDPR INTEGER, IETILPID INTEGER, SKONMONT INTEGER,
SKONCENA DOUBLE PRECISION, SKONSTUND DOUBLE PRECISION, SKONFCENA DOUBLE PRECISION,
OLDSKONCENA DOUBLE PRECISION, OLDSKONSTUND DOUBLE PRECISION, OLDSKONFCENA DOUBLE PRECISION)
AS
DECLARE VARIABLE TEK_SKON_MONT INTEGER;
BEGIN
SKONCENA = :SKONCENA - OLDSKONCENA;
SKONFCENA = :SKONFCENA - OLDSKONFCENA;
SKONSTUND = :SKONSTUND - OLDSKONSTUND;
IF (:SKONCENA IS NULL) THEN
SKONCENA = 0;
IF (:SKONFCENA IS NULL) THEN
SKONFCENA = 0;
IF (:SKONSTUND IS NULL) THEN
SKONSTUND = 0;
IF (:IETILPID > 0) THEN
BEGIN
SELECT SKON_MONT
FROM SUB_KON
WHERE ID_SKON = :IETILPID
INTO :TEK_SKON_MONT;
END
IF ((:TEK_SKON_MONT IS NULL) OR (:IETILPID = 0)) THEN
IF (:SKONMONT = 0) THEN
BEGIN
UPDATE PROJEKT
SET PR_STUND = PR_STUND + :SKONSTUND,
PR_CENA = PR_CENA + :SKONCENA,
PR_FCENA = PR_FCENA + :SKONFCENA
WHERE ID_PR = :IDPR;
END
ELSE
IF (:SKONMONT = 1) THEN
BEGIN
UPDATE PROJEKT
← →
Prohodil Mimo © (2005-01-19 12:02) [8]SET PR_MSTUND = PR_MSTUND + :SKONSTUND,
PR_MCENA = PR_MCENA + :SKONCENA,
PR_FCENA = PR_FCENA + :SKONFCENA
WHERE ID_PR = :IDPR;
END
ELSE
IF (:SKONMONT = 2) THEN
BEGIN
UPDATE PROJEKT
SET PR_PCENA = PR_PCENA + :SKONCENA,
PR_FCENA = PR_FCENA + :SKONFCENA
WHERE ID_PR = :IDPR;
END
ELSE
IF (:SKONMONT = 3) THEN
BEGIN
UPDATE PROJEKT
SET PR_PVCENA = PR_PVCENA + :SKONCENA,
PR_FCENA = PR_FCENA + :SKONFCENA
WHERE ID_PR = :IDPR;
END
ELSE
IF (:SKONMONT = 4) THEN
BEGIN
UPDATE PROJEKT
SET PR_TCENA = PR_TCENA + :SKONCENA,
PR_FCENA = PR_FCENA + :SKONFCENA
WHERE ID_PR = :IDPR;
END
END;
похоже не всегда срабатывает PROCEDURE SET_PROJ_CEN_SUM.
← →
Johnmen © (2005-01-19 13:18) [9]>Prohodil Mimo ©
Да...Тут разобраться глазами просто почти нереально...:)
Но очень и очень смущают присутствующие рекурсии...
М.б. стОит погонять всю эту конструкцию, вставив в необходимые места контрольные точки - сброс в лог таблицу интересующих параметров, с дальшейшим анализом этих данных.
Также можно потрассировать под IBExpert"ом.
← →
Prohodil Mimo © (2005-01-19 15:37) [10]Johnmen © (19.01.05 13:18) [9]
значит считаете одной из возможных причин - рекурсию?
лады, попробую что-нибудь.
Спасибо.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.037 c