CREATE TRIGGER INSERT_MODEL1 FOR MODELS
ACTIVE AFTER INSERT POSITION 0
as
declare variable min_pos integer;
declare variable our_center integer;
declare variable main integer;
declare variable current_cnt integer;
declare variable model_id integer;
declare variable my_param integer;
declare variable main_cnt integer;
begin
our_center=0;
main=0;
model_id = new.modid;
/* считываем параметр, переданый в триггер*/
my_param=0;
if (new.param>0) then my_param = new.param;
/* определяем параметры текущего центра учета */
select centerid, maincenter from centers where visible=1
and working=1
into :our_center, :main;
/* если нет текущего видимого центра учета, то это ошибка
в структуре базы. Об этом надо сообщить */
if ((our_center=0) or (our_center is NULL)) then exception no_vis_center;
main_cnt=our_center;
if (main<>1) then select centerid from centers where maincenter=1 into :main_cnt;
if ((main_cnt=0) or (main_cnt is NULL)) then exception no_main_center;
/* Если это главный центр учета, то устанавливаем флаг обновления на все невиртуальные
центры учета */
if (main=1) then begin
if (my_param>0) then begin /* Это означает что инициатива по добавлению новой модели
исходит от УБ с кодом my_param*/
/* организуем цикл прохода по центрам учета */
for select centerid from centers where working = 1 /* работающий */
and virtual <>1 /* невиртуальный */
and centerid <> :our_center /* не равен главному */
and centerid <> :my_param /* для удаленного ЦУ своя обработка */
into :current_cnt
do begin
/* определяем ближайшую свободную строку для пометки изменения */
min_pos=0;
select MIN(N) from remote where center = :current_cnt /* здесь определяем позицию */
and models = :model_id /* для записи флага обновления */
into :min_pos;
if (min_pos>0) then /* если для этого эл-та справочника существует запись в remote */
update remote set modelsact="A", modelsstate="B" where n = :min_pos;
else begin /* Если нет записи в remote то ищем первую свободную */
select MIN(N) from remote where center = :current_cnt
and models is null
into :min_pos;
if (min_pos>0) then
/* для найденой записи делаем update */
update remote set models = :model_id, modelsact="A", modelsstate="B" where N = :min_pos;
else
/* если записи нет, то добавим новую */
insert into remote(center,models,modelsact,modelsstate)
values(:current_cnt, :model_id,"A","B");
end
end
/* здесь производим обработку для УЦУ, который и был инициатором добавления нового
элемента в ЦБ */
/* определяем ближайшую свободную строку для пометки изменения */
min_pos=0;
select MIN(N) from remote where center = :my_param /* здесь определяем позицию */
and models = :model_id /* для записи флага обновления */
into :min_pos;
if (min_pos>0) then /* если для этого эл-та справочника существует запись в remote */
update remote set modelsact="I", modelsstate="A", modelsold=new.oldid
where n = :min_pos;
else begin /* Если нет записи в remote то ищем первую свободную */
select MIN(N) from remote where center = :my_param
and models is null
into :min_pos;
if (min_pos>0) then
/* для найденой записи делаем update */
update remote set models = :model_id,
modelsact="I",modelsstate="A", modelsold=new.oldid
where N = :min_pos;
else
/* если записи нет, то добавим новую */
insert into remote(center,models,modelsact,modelsstate,modelsold)
values(:my_param, :model_id,"I","A",new.oldid);
end
end
else begin /* Это в том случае, если никакого параметра передано не было
и добавление нового элемента происходит по инициативе ЦБ*/
/* организуем цикл прохода по центрам учета */
for select centerid from centers where working = 1 /* работающий */
and virtual <>1 /* невиртуальный */
and centerid <> :our_center /* не равен главному */
into :current_cnt
do begin
/* определяем ближайшую свободную строку для пометки изменения */
min_pos=0;
select MIN(N) from remote where center = :current_cnt /* здесь определяем позицию */
and models = :model_id /* для записи флага обновления */
into :min_pos;
if (min_pos>0) then /* если для этого эл-та справочника существует запись в remote */
update remote set modelsact="A", modelsstate="B" where n = :min_pos;
else begin /* Если нет записи в remote то ищем первую свободную */
select MIN(N) from remote where center = :current_cnt
and models is null
into :min_pos;
if (min_pos>0) then
/* для найденой записи делаем update */
update remote set models = :model_id, modelsact="A", modelsstate="B" where N = :min_pos;
else
/* если записи нет, то добавим новую */
insert into remote(center,models,modelsact,modelsstate)
values(:current_cnt, :model_id,"A","B");
end
end
end
end else begin
/* здесь алгоритм примерно такой же, только работаем с одним (главным) центром учета */
if ((my_param>0) and (my_param=main_cnt)) then begin /* Это вариант,
когда ЦБ прислала новый элемент */
min_pos=0;
select MIN(N) from remote where center = :main_cnt
and models = :model_id
into :min_pos;
if (min_pos>0) then
update remote set modelsact="I",modelsstate="A" where N = :min_pos;
else begin
select MIN(N) from remote where center = :main_cnt and models is null
into :min_pos;
if (min_pos>0) then
update remote set models = :model_id, modelsact="I", modelsstate="A"
where N = :min_pos;
else
insert into remote(center, models, modelsact, modelsstate)
values(:main_cnt, :model_id,"I","A");
end
end
else begin /* Этот случай, когда УБ сама добавила новый элемент */
min_pos=0;
select MIN(N) from remote where center = :main_cnt
and models = :model_id
into :min_pos;
if (min_pos>0) then
update remote set modelsact="A",modelsstate="B" where N = :min_pos;
else begin
select MIN(N) from remote where center = :main_cnt and models is null
into :min_pos;
if (min_pos>0) then
update remote set models = :model_id, modelsact="A",modelsstate="B"
where N = :min_pos;
else
insert into remote(center, models, modelsact, modelsstate) values(:main_cnt,
:model_id,
"A",
"B");
end
end
end
end
CREATE TRIGGER UPDATE_MODEL FOR MODELS
ACTIVE AFTER UPDATE POSITION 0
as
declare variable min_pos integer;
declare variable our_center integer;
declare variable main integer;
declare variable current_cnt integer;
declare variable main_cnt integer;
declare variable model_id integer;
declare variable my_param integer;
begin
/* Смысл этого триггре такой же как и у INSERT_MODEL1 */
if (new.modid=old.modid) then begin
our_center=0;
main=0;
model_id = old.modid;
if (new.modid>0) then model_id=new.modid;
my_param=0;
if (new.param>0) then my_param = new.param;
select centerid, maincenter from centers where visible=1 into :our_center, :main;
if ((our_center=0) or (our_center is NULL)) then exception no_vis_center;
main_cnt=our_center;
if (main<>1) then select centerid from centers where maincenter=1 into :main_cnt;
if ((main_cnt=0) or (main_cnt is NULL)) then exception no_main_center;
if (main=1) then begin
if (my_param>0) then begin /* значит update пришел от УБ */
for select centerid from centers
where working=1
and virtual<>1
and centerid <> :our_center
and centerid <> :my_param
into :current_cnt do begin
min_pos=0;
select MIN(N) from remote where center = :current_cnt
and models = :model_id
into :min_pos;
if (min_pos>0) then
update remote set modelsact="M",modelsstate="B" where N = :min_pos;
else begin
select MIN(N) from remote where center = :current_cnt
and models is null
into :min_pos;
if (min_pos>0) then
update remote set models = :model_id, modelsact="M",modelsstate="B"
where N = :min_pos;
else
insert into remote(center, models, modelsact,modelsstate)
values ( :current_cnt, :model_id, "M","B");
end
end
min_pos=0;
select MIN(N) from remote where center = :my_param
and models = :model_id
into :min_pos;
if (min_pos>0) then
update remote set modelsact="E",modelsstate="M" where N = :min_pos;
else begin
select MIN(N) from remote where center = :my_param
and models is null
into :min_pos;
if (min_pos>0) then
update remote set models = :model_id, modelsact="E",modelsstate="M"
where N = :min_pos;
else
insert into remote(center, models, modelsact,modelsstate)
values ( :my_param, :model_id, "E","M");
end
end
else begin /* здесь update вызван самой ЦБ */
for select centerid from centers
where working=1
and virtual<>1
and centerid <> :main_cnt
into :current_cnt do begin
min_pos=0;
select MIN(N) from remote where center = :current_cnt
and models = :model_id
into :min_pos;
if (min_pos>0) then
update remote set modelsact="M",modelsstate="B" where N = :min_pos;
else begin
select MIN(N) from remote where center = :current_cnt
and models is null
into :min_pos;
if (min_pos>0) then
update remote set models = :model_id, modelsact="M",modelsstate="B"
where N = :min_pos;
else
insert into remote(center, models, modelsact,modelsstate)
values ( :current_cnt, :model_id, "M","B");
end
end
end
end
else begin
/* значит мы являемся УБ, для этого случая другая обработка */
min_pos=0;
if ((my_param>0) and (my_param=main_cnt)) then begin
/* Этот update пришел от ЦБ то есть со стороны*/
select MIN(N) from remote where center = :main_cnt
and models = :model_id
into :min_pos;
if (min_pos>0) then
update remote set modelsact="E",modelsstate="M" where N = :min_pos;
else begin
select MIN(N) from remote where center = :main_cnt and models is null
into :min_pos;
if (min_pos>0) then
update remote set models = :model_id, modelsact="E",modelsstate="M"
where N = :min_pos;
else
insert into remote(center, models, modelsact, modelsstate)
values ( :main_cnt, :model_id, "E","M");
end
end
else begin /* а этот вызван своей собственной базой */
select MIN(N) from remote where center = :main_cnt
and models = :model_id into :min_pos;
if (min_pos>0) then
update remote set modelsact="M",modelsstate="B" where N = :min_pos;
else begin
select MIN(N) from remote where center = :main_cnt and models is null
into :min_pos;
if (min_pos>0) then
update remote set models = :model_id, modelsact="M",modelsstate="B"
where N = :min_pos;
else
insert into remote(center, models, modelsact, modelsstate)
values ( :main_cnt, :model_id, "M","B");
end
end
end
end
end
|