Работа триггера

Омич
Дата: 21.10.2005 11:01:05
Имеется таблица:
CREATE TABLE TREE (
    IDCLIENT   IDUSER NOT NULL, 
    IDPARENT   IDUSER,
    CCOUNT     INTEGER DEFAULT 0, /* кол-во прямых потомков */
    LEVEL1     INTEGER DEFAULT 0, /* уровень вложенности */
);
При изменении хозяина ветки, то есть IDPARENT, у детей срабатывает триггер,
который пересчитывает CCOUNT и LEVEL1 потомков:
CREATE TRIGGER TREE_BU FOR TREE
ACTIVE BEFORE UPDATE POSITION 0
AS
begin
 if (old.IDPARENT <> new.IDPARENT) then
   begin
    UPDATE tree D SET D.CCOUNT = D.CCOUNT - 1 WHERE D.IDCLIENT = old.IDPARENT;
    UPDATE tree D SET D.CCOUNT = D.CCOUNT +1 WHERE D.IDCLIENT = new.IDPARENT;
    SELECT MAX(D1.level1)+1 FROM tree D1 WHERE D1.IDCLIENT = new.IDPARENT INTO new.level1;
   end
end

Не пойму почему он не персчитывает значения, если у потомков есть свои потомки.
Другими словами, не ведётся персчёт "детей" 2-го поколения и т.д. Для первого поколения всё проходит без проблем.
Что-то необходимо изменить в триггере?
Zmeishe
Дата: 21.10.2005 11:08:13
Потому, что у потомков-потомков
old.IDPARENT = new.IDPARENT

Тебе надо другой триггер, который обработает
if (old.LEVEL1 <> new.LEVEL1) then
Zmeishe
Дата: 21.10.2005 11:14:58
И вообще, эти триггеры должны быть AFTER, а не BEFORE
В ссылке, которую я тебе дал - есть примеры триггеров.
Омич
Дата: 21.10.2005 11:18:38
Возможно, глупый вопрос:
Получается два триггера на одну и ту же операцию?
Kull Damned
Дата: 21.10.2005 11:21:44
Получается два триггера на одну и ту же операцию?
Да хоть 84 :) Вчитайся в декларацию триггера.

Posted via ActualForum NNTP Server 1.3

Zmeishe
Дата: 21.10.2005 11:25:13
CREATE TRIGGER BI_ACOUNTS FOR ACOUNTS
ACTIVE BEFORE INSERT POSITION 0
as
DECLARE VARIABLE C INTEGER;
begin
  SELECT A.KID_LEVEL
  FROM ACOUNTS A
  WHERE (A.KOD = NEW.PARENT)
  INTO :C;
  C = :C + 1;
  IF(NEW.KID_LEVEL <> :C) THEN NEW.KID_LEVEL = :C;
end


CREATE TRIGGER AI_ACOUNTS FOR ACOUNTS
ACTIVE AFTER INSERT POSITION 0
AS
BEGIN
  UPDATE ACOUNTS A
  SET A.KID_COUNT = A.KID_COUNT + 1
  WHERE (A.KOD = NEW.PARENT);
END

/*-----------------------------------------------------------------------*/

CREATE TRIGGER BU_ACOUNTS FOR ACOUNTS
ACTIVE BEFORE UPDATE POSITION 0
as
DECLARE VARIABLE C INTEGER;
begin
 IF(NEW.PARENT <> OLD.PARENT) THEN BEGIN
  SELECT S.KID_LEVEL
  FROM ACOUNTS S
  WHERE (S.KOD = NEW.PARENT)
  INTO :C;
  C = :C + 1;
  IF(NEW.KID_LEVEL <> :C) THEN NEW.KID_LEVEL = :C;
 END
end

CREATE TRIGGER AU_ACOUNTS FOR ACOUNTS
ACTIVE AFTER UPDATE POSITION 0
AS
DECLARE VARIABLE C INTEGER;
BEGIN

 IF(NEW.PARENT <> OLD.PARENT) THEN BEGIN
     UPDATE ACOUNTS A
      SET A.KID_COUNT = A.KID_COUNT - 1
      WHERE (A.KOD = OLD.PARENT);
     UPDATE ACOUNTS A
      SET A.KID_COUNT = A.KID_COUNT + 1
      WHERE (A.KOD = NEW.PARENT);
   END

  IF(NEW.KID_LEVEL <> OLD.KID_LEVEL) THEN BEGIN
   C = NEW.KID_LEVEL + 1;
   UPDATE ACOUNTS S
   SET S.KID_LEVEL = :C
   WHERE (S.PARENT = NEW.KOD) AND (NEW.KOD <> NEW.PARENT);
  END 

END
/*------------------------------------------------------------------------*/

CREATE TRIGGER AD_ACOUNTS FOR ACOUNTS
ACTIVE AFTER DELETE POSITION 0
AS
BEGIN
  UPDATE ACOUNTS A
  SET A.KID_COUNT = A.KID_COUNT - 1
  WHERE (A.KOD = OLD.PARENT);
END
Омич
Дата: 21.10.2005 12:33:35
2 Zmeishe
Очередной раз твоя помощь как нельзя кстати, спасибо.
По сути всё за меня сделал.
Kull Damned
Дата: 21.10.2005 12:37:25
По сути всё за меня сделал.
Вот это как раз и плохо. :(

Posted via ActualForum NNTP Server 1.3

Zmeishe
Дата: 21.10.2005 12:44:24
Омич
2 Zmeishe
Очередной раз твоя помощь как нельзя кстати, спасибо.
По сути всё за меня сделал.

Пользуйся Йуный садовод! Я и не такие деревья сажал.
Например два в одном флаконе (таблице).
там два ID_PARENT, два KID_COUNT, два KID_LEVEL, а ID - один и NAME один!
О как! Типа два ствола к одному пеньку прикручены.
Омич
Дата: 21.10.2005 14:00:59
Kull Damned
По сути всё за меня сделал.
Вот это как раз и плохо. :(

Может быть и так... но в качестве оправдания, что ли:
я всегда готов учиться, а этот форум оказался для меня лучшим учителем.