Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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.048 c
4-1105008771
Брат
2005-01-06 13:52
2005.02.20
Поместить окно поверх остальных


3-1106560989
CTAPbIi
2005-01-24 13:03
2005.02.20
Обновление данных в DBGrid.


4-1103998049
Flext@r
2004-12-25 21:07
2005.02.20
Получение списка выполняемых задач винды


6-1102608173
Erlan
2004-12-09 19:02
2005.02.20
Проблемы с NMHttp


1-1107409966
fynjy1984
2005-02-03 08:52
2005.02.20
DBGridEh и копирование





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский