Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.02.20;
Скачать: CL | DM;

Вниз

Почему могут глючить триггера в 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.043 c
1-1107855373
_Тима
2005-02-08 12:36
2005.02.20
Автоматическое исправление имен в редакторе кода


1-1107852549
Denis
2005-02-08 11:49
2005.02.20
Как проскроллить RichEdit до выделеного участка текста?


14-1106953523
GanibalLector
2005-01-29 02:05
2005.02.20
Набережных С. - мастер!


4-1104940427
Fanny
2005-01-05 18:53
2005.02.20
Как узнать, есть ли права на запись в реестр?


14-1106519472
GanibalLector
2005-01-24 01:31
2005.02.20
Харьков...встреча