SQLRU.net
Разработка приложений баз данных

Начало » Использование СУБД » Firebird, HQbird, InterBase » Глюки Firebird4 ? (Firebird 2 и 4 работают по разному)
Глюки Firebird4 ? [сообщение #611] Tue, 20 September 2022 16:47 Переход к следующему сообщению
anbsoft в настоящее время не в онлайне  anbsoft
Сообщений: 4
Зарегистрирован: September 2022
Junior Member
Давно работал с Firebird 2.0
Решил попробовать перейти на новую версию (4).
Некоторые триггеры стали работать некорректно.
Примерно понимаю почему так, но пока не знаю что с этим делать.
Привожу код тестовой базы:
В таблице клиентов ведется долг клиента.
В таблице затрат проходят затраты по нему.
Некоторые затраты могут проходить пакетом (При проведении родительской затраты, автоматически проводятся дочернии).
Вставляем список затрат и подтверждаем их переводом State в 1
Поля Info и Test1 добавлены для понимания того, что происходит.

CREATE DATABASE 'Base2.fdb' USER 'SYSDBA' PASSWORD 'masterkey';

CREATE TABLE Klient
(
ID Integer NOT NULL,
Name VarChar(50),
Dolg NUMERIC(15,2) DEFAULT 0,
PRIMARY KEY (ID)
);

CREATE GENERATOR GEN_Klient;

SET TERM ^ ;
CREATE TRIGGER SET_Klient FOR Klient
ACTIVE BEFORE INSERT POSITION 0
AS
declare variable IDTemp Integer;
BEGIN
IF ((NEW.ID=0) OR (NEW.ID IS NULL)) THEN BEGIN
NEW.ID=GEN_ID(GEN_Klient,1);
END
END^
SET TERM ; ^

INSERT INTO Klient (ID, Name, Dolg) VALUES (0,'Test', 0);

CREATE TABLE Zatrat
(
ID Integer NOT NULL,
Parent Integer default 0,
IDKlient Integer,
State Integer default 0,
Suma NUMERIC(15,2) DEFAULT 0,
Info VarChar(100),
Test1 Integer,
PRIMARY KEY (ID)
);

CREATE GENERATOR GEN_Zatrat;
CREATE GENERATOR GEN_Test;


SET TERM ^ ;
CREATE TRIGGER SET_Zatrat FOR Zatrat
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF ((NEW.ID=0) OR (NEW.ID IS NULL)) THEN BEGIN
NEW.ID=GEN_ID(GEN_Klient,1);
END
END^

CREATE TRIGGER Edit_Zatrat FOR Zatrat
ACTIVE BEFORE UPDATE POSITION 0
AS
declare variable S1 VarChar(20);
declare variable S2 VarChar(20);
BEGIN
IF ((OLD.State<>1) AND (NEW.State=1)) THEN BEGIN
select Dolg from klient where (ID=NEW.IDKlient) into :S1;
UPDATE Klient SET Dolg=Dolg-OLD.Suma WHERE (ID=NEW.IDKlient);
select Dolg from klient where (ID=NEW.IDKlient) into :S2;
NEW.Info=' - ' || coalesce(OLD.Info, '') || ' ' || S1 || ' ' || S2;
NEW.Test1=GEN_ID(GEN_Test,1);
END
IF ((OLD.State=1) AND (NEW.State<>1)) THEN BEGIN
UPDATE Klient SET Dolg=Dolg+OLD.Suma WHERE (ID=NEW.IDKlient);
END
END^

CREATE TRIGGER Edit_Doc FOR Zatrat
ACTIVE AFTER UPDATE POSITION 0
AS
BEGIN
IF ((NEW.Parent<>0) AND (NEW.State<>OLD.State)) THEN BEGIN
UPDATE Zatrat SET State=NEW.State WHERE (Parent=NEW.Parent) AND (State<>NEW.State) AND (ID<>NEW.ID);
END
END^

SET TERM ; ^

INSERT INTO Zatrat (ID, Parent, IDKlient, State, Suma) VALUES (1,1,1,0,10);
INSERT INTO Zatrat (ID, Parent, IDKlient, State, Suma) VALUES (2,1,1,0,30);
INSERT INTO Zatrat (ID, Parent, IDKlient, State, Suma) VALUES (3,1,1,0,50);
INSERT INTO Zatrat (ID, Parent, IDKlient, State, Suma) VALUES (4,1,1,0,200);

UPDATE Zatrat SET State=1 where (ID=1);

SELECT * FROM Klient;

ID NAME DOLG
== ======== ========
1 Test -290.00

Select * FROM Zatrat ORDER BY ID;

ID PARENT IDKLIENT STATE SUMA INFO TEST1
== ====== ======== ===== ====== =================== =====
1 1 1 1 10.00 - 0.00 -10.00 1
2 1 1 1 30.00 - -10.00 -40.00 2
3 1 1 1 50.00 - -40.00 -90.00 3
4 1 1 1 200.00 - -90.00 -290.00 4

COMMIT WORK;

В Firebird 4 результаты совсем друние:

SELECT * FROM Klient;

ID NAME DOLG
== ======== ========
1 Test -740.00

Select * FROM Zatrat ORDER BY ID;

ID PARENT IDKLIENT STATE SUMA INFO TEST1
== ====== ======== ===== ====== =================== =====
1 1 1 1 10.00 - 0.00 -10.00 1
2 1 1 1 30.00 - -10.00 -40.00 2
3 1 1 1 50.00 - -490.00 -540.00 6
4 1 1 1 200.00 - -540.00 -740.00 7

Видно, что между обновлением 2 и 3 строки еще трижды проходит обновление, но никаких следов не оставляет.
Как побороть эту напасть?
Re: Глюки Firebird4 ? [сообщение #612 является ответом на сообщение #611] Wed, 21 September 2022 00:37 Переход к предыдущему сообщениюПереход к следующему сообщению
SD в настоящее время не в онлайне  SD
Сообщений: 328
Зарегистрирован: August 2022
Senior Member
Ужасный бред. Ты когда-нибудь слышал о транзакциях, их изолированности и атомарности? Очевидно нет, иначе не маялся бы "вставкой и подтверждением". Ну и об изменениях в этой области в четвёрке тоже стоит почитать.
Re: Глюки Firebird4 ? [сообщение #613 является ответом на сообщение #612] Wed, 21 September 2022 04:56 Переход к предыдущему сообщениюПереход к следующему сообщению
fraks в настоящее время не в онлайне  fraks
Сообщений: 108
Зарегистрирован: June 2022
Географическое положение: Новосибирск
Senior Member
На FB-2.5.8 работает так же как FB-2.0

Сталкивался с подобной задачей, поэтому бредом не назову, вполне жизненно.
Правда про корректность решения ничего пока не могу сказать.

Для тех кто не в теме - сначала вставляем рыбу затрат, проверяем как оно все выглядит, и потом "подтверждаем" - проводим по долгу клиента.
Получается что родительский расход - это типа шапка документа, а все что под ним - это строки документа.
Re: Глюки Firebird4 ? [сообщение #614 является ответом на сообщение #611] Wed, 21 September 2022 05:23 Переход к предыдущему сообщениюПереход к следующему сообщению
fraks в настоящее время не в онлайне  fraks
Сообщений: 108
Зарегистрирован: June 2022
Географическое положение: Новосибирск
Senior Member
anbsoft писал(а) Tue, 20 September 2022 20:47

Select * FROM Zatrat ORDER BY ID;

ID PARENT IDKLIENT STATE  SUMA  INFO                TEST1 
== ====== ======== ===== ====== =================== ===== 
 1      1        1     1  10.00  -  0.00 -10.00         1 
 2      1        1     1  30.00  -  -10.00 -40.00       2 
 3      1        1     1  50.00  -  -40.00 -90.00       3 
 4      1        1     1 200.00  -  -90.00 -290.00      4 

COMMIT WORK;

В Firebird 4 результаты совсем другие:

SELECT * FROM Klient;

ID NAME         DOLG 
== ======== ========
 1 Test     -740.00 

Select * FROM Zatrat ORDER BY ID;

ID PARENT IDKLIENT STATE  SUMA  INFO                TEST1 
== ====== ======== ===== ====== =================== ===== 
 1      1        1     1  10.00  -  0.00 -10.00         1 
 2      1        1     1  30.00  -  -10.00 -40.00       2 
 3      1        1     1  50.00  -  -490.00 -540.00     6 
 4      1        1     1 200.00  -  -540.00 -740.00     7 
Видно, что между обновлением 2 и 3 строки еще трижды проходит обновление, но никаких следов не оставляет.
Я бы добавил таблицу лога, на таблицу Zatrat повесил бы триггер на update, что бы записывал параметры каждого update и поразмышлял бы, глядя на этот лог.
Очевидно, что "никаких следов не оставляет" по той причине что какая-то запись апдейтится неоднократно, и это предположительно запись с ID=3.

Какой уровень изоляции в транзакции через которую выполняется вставка данных?
Re: Глюки Firebird4 ? [сообщение #615 является ответом на сообщение #614] Wed, 21 September 2022 05:30 Переход к предыдущему сообщениюПереход к следующему сообщению
fraks в настоящее время не в онлайне  fraks
Сообщений: 108
Зарегистрирован: June 2022
Географическое положение: Новосибирск
Senior Member
И еще.
В триггерах не обрабатывается ситуация когда поля

ZATRAT.PARENT
ZATRAT.STATE

содержат NULL.
Если поля не предполагают отсутствия значения - то я бы объявлял их как NOT NULL.
Объявление DEFAULT ничего не гарантирует.
Re: Глюки Firebird4 ? [сообщение #616 является ответом на сообщение #615] Wed, 21 September 2022 05:43 Переход к предыдущему сообщениюПереход к следующему сообщению
fraks в настоящее время не в онлайне  fraks
Сообщений: 108
Зарегистрирован: June 2022
Географическое положение: Новосибирск
Senior Member
Честно говоря, вообще перестал понимать как это работает.
Триггеры на ZATRAT - на BEFORE/AFTER UPDATE, и они очевидно работают.
Но в скрипте нет ни одного UPDATE, только INSERT!

Я ранее думал что событие INSERT не включает в себя UPDATE.
Re: Глюки Firebird4 ? [сообщение #617 является ответом на сообщение #616] Wed, 21 September 2022 06:16 Переход к предыдущему сообщениюПереход к следующему сообщению
fraks в настоящее время не в онлайне  fraks
Сообщений: 108
Зарегистрирован: June 2022
Географическое положение: Новосибирск
Senior Member
Блин, семен-семеныч...

UPDATE Zatrat SET State=1 where (ID=1);
Re: Глюки Firebird4 ? [сообщение #618 является ответом на сообщение #611] Wed, 21 September 2022 07:08 Переход к предыдущему сообщениюПереход к следующему сообщению
fraks в настоящее время не в онлайне  fraks
Сообщений: 108
Зарегистрирован: June 2022
Географическое положение: Новосибирск
Senior Member
Лог для отслеживания событий в таблице.

CREATE GENERATOR GEN_ZATRAT_LOG_ID;

CREATE TABLE ZATRAT_LOG (
    ID        INTEGER NOT NULL,
    IDZ       INTEGER,
    PARENT    INTEGER,
    IDKLIENT  INTEGER,
    STATE     INTEGER,
    SUMA      NUMERIC(15,2),
    INFO      VARCHAR(100),
    TEST1     INTEGER,
    A         VARCHAR(5)
);


ALTER TABLE ZATRAT_LOG ADD PRIMARY KEY (ID);

SET TERM ^ ;

CREATE OR ALTER TRIGGER ZATRAT_LOG_BI FOR ZATRAT_LOG
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.id is null) then
    new.id = gen_id(gen_zatrat_log_id,1);
end
^

CREATE OR ALTER TRIGGER ZATRAT_AIUD_LOG FOR ZATRAT
ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 0
as
declare variable sa varchar(3);
begin
  sa = '';
  if (inserting) then sa = sa || 'I';
  if (updating ) then sa = sa || 'U';
  if (deleting ) then sa = sa || 'D';
  --
  insert into ZATRAT_LOG (idz, parent, idklient, state, suma, info, test1, a)
  values(NEW.id, NEW.parent, NEW.idklient, NEW.state, NEW.suma,  NEW.info,  NEW.test1,  :sa);
end
^

SET TERM ; ^
Re: Глюки Firebird4 ? [сообщение #619 является ответом на сообщение #618] Wed, 21 September 2022 07:10 Переход к предыдущему сообщениюПереход к следующему сообщению
fraks в настоящее время не в онлайне  fraks
Сообщений: 108
Зарегистрирован: June 2022
Географическое положение: Новосибирск
Senior Member
Ну и косяк триггеров только на update.
Если вставить запись сразу с State=1 то она не учтется в долге, а при изменении статуса долг только испортит, т.к. вычтется то что и не добавлялось.
Re: Глюки Firebird4 ? [сообщение #620 является ответом на сообщение #619] Wed, 21 September 2022 12:04 Переход к предыдущему сообщениюПереход к следующему сообщению
anbsoft в настоящее время не в онлайне  anbsoft
Сообщений: 4
Зарегистрирован: September 2022
Junior Member
Это не рабочая база, а тестовый пример для демонстрации глюка.
Кроме того, при выполнении
UPDATE Zatrat SET State=1 where (ID=1);
и
UPDATE Zatrat SET State=1 where (ID=3);
Результат долга получится разный.
Настроек по транзвкциям для примера никаких, скрипт запускался из командной строки
"%ProgramFiles%\Firebird\Firebird_4_0\isql" -e -s 3 -input base4.sql -output Result4.txt -m
Пока придумал костыль, но сам факт неоднозначности работы напрягает.
Re: Глюки Firebird4 ? [сообщение #621 является ответом на сообщение #613] Wed, 21 September 2022 15:13 Переход к предыдущему сообщениюПереход к следующему сообщению
SD в настоящее время не в онлайне  SD
Сообщений: 328
Зарегистрирован: August 2022
Senior Member
fraks писал(а) Wed, 21 September 2022 03:56

Для тех кто не в теме - сначала вставляем рыбу затрат, проверяем как оно все выглядит, и потом "подтверждаем" - проводим по долгу клиента.
Вот только обычно это таки делается в разных транзакциях, а здесь разные триггера на одно событие, то есть всё исполняется в рамках одного запроса.

И да, как сказал бы Влад, "нет такой версии".
Как раз в видимости собственных изменений в пределах PSQL блока был баг, который правился.

[Обновления: Wed, 21 September 2022 15:14]

Известить модератора

Re: Глюки Firebird4 ? [сообщение #622 является ответом на сообщение #611] Thu, 22 September 2022 00:46 Переход к предыдущему сообщениюПереход к следующему сообщению
kdv в настоящее время не в онлайне  kdv
Сообщений: 89
Зарегистрирован: June 2022
Member
Вот этот триггер - просто адище. Update этой же таблицы в after update???

CREATE TRIGGER Edit_Doc FOR Zatrat
ACTIVE AFTER UPDATE POSITION 0
AS
BEGIN
  IF ((NEW.Parent<>0) AND (NEW.State<>OLD.State)) THEN 
    BEGIN
      UPDATE Zatrat SET State=NEW.State WHERE (Parent=NEW.Parent) AND (State<>NEW.State) AND (ID<>NEW.ID);
    END
END
Re: Глюки Firebird4 ? [сообщение #626 является ответом на сообщение #613] Thu, 22 September 2022 11:21 Переход к предыдущему сообщениюПереход к следующему сообщению
sim_84 в настоящее время не в онлайне  sim_84
Сообщений: 287
Зарегистрирован: June 2022
Senior Member
fraks писал(а) Wed, 21 September 2022 04:56
На FB-2.5.8 работает так же как FB-2.0

Сталкивался с подобной задачей, поэтому бредом не назову, вполне жизненно.
Правда про корректность решения ничего пока не могу сказать.

Для тех кто не в теме - сначала вставляем рыбу затрат, проверяем как оно все выглядит, и потом "подтверждаем" - проводим по долгу клиента.
Получается что родительский расход - это типа шапка документа, а все что под ним - это строки документа.
Проблема не в обновление статуса родительских записей, а в том что для них идёт расчёт нарастающих сумм. Нельзя в триггерах использовать логику, которая зависит от порядка срабатывания, например расчёт нарастающих сумм. Мутации оракуля в принципе как раз от этого и защищают, правда заодно режут и кучу других полезных возможностей.
Re: Глюки Firebird4 ? [сообщение #636 является ответом на сообщение #626] Fri, 23 September 2022 10:57 Переход к предыдущему сообщениюПереход к следующему сообщению
fraks в настоящее время не в онлайне  fraks
Сообщений: 108
Зарегистрирован: June 2022
Географическое положение: Новосибирск
Senior Member
sim_84 писал(а) Thu, 22 September 2022 15:21

Проблема не в обновление статуса родительских записей, а в том что для них идёт расчёт нарастающих сумм. Нельзя в триггерах использовать логику, которая зависит от порядка срабатывания, например расчёт нарастающих сумм. Мутации оракуля в принципе как раз от этого и защищают, правда заодно режут и кучу других полезных возможностей.
ИМХО,
А тут и нет зависимости от порядка срабатывания.
Изменение долга клиента делается в приращениях, и так же читаются в первичке, не селектом а из NEW.
Тут проблема что по некоторым записям триггер срабатывает несколько раз.
Re: Глюки Firebird4 ? [сообщение #637 является ответом на сообщение #636] Fri, 23 September 2022 11:12 Переход к предыдущему сообщениюПереход к следующему сообщению
basid в настоящее время не в онлайне  basid
Сообщений: 79
Зарегистрирован: June 2022
Географическое положение: Asia/Irkutsk
Member
Так он потому и "срабатывает несколько раз", что "зависит от порядка срабатывания".
По-моему - так (Винни-Пух голосом Евгения Леонова).
Re: Глюки Firebird4 ? [сообщение #648 является ответом на сообщение #637] Mon, 26 September 2022 09:08 Переход к предыдущему сообщениюПереход к следующему сообщению
fraks в настоящее время не в онлайне  fraks
Сообщений: 108
Зарегистрирован: June 2022
Географическое положение: Новосибирск
Senior Member
basid писал(а) Fri, 23 September 2022 15:12
Так он потому и "срабатывает несколько раз", что "зависит от порядка срабатывания".
ИМХО он срабатывает несколько раз потому что в каких-то случаях не видит собственных изменений (внесенных этой же транзакцией и этим же запросом, вызвавшим цепочку update).
И вопрос - топикстартер наткнулся на косяк, или же поведение в 2.0 и 2.5 считается косячным.

Или по дефолту в четверке запускается транзакция с таким уровнем изоляции, которая не видит собственных изменений?
Re: Глюки Firebird4 ? [сообщение #649 является ответом на сообщение #648] Mon, 26 September 2022 09:39 Переход к предыдущему сообщениюПереход к следующему сообщению
sim_84 в настоящее время не в онлайне  sim_84
Сообщений: 287
Зарегистрирован: June 2022
Senior Member
Цитата:
Или по дефолту в четверке запускается транзакция с таким уровнем изоляции, которая не видит собственных изменений?
не бывает таких уровней изолированности.

В 4.0 появился Read Committed Read Consistency, которая может запускать рестарты на конфликтах, а потому один и тот же запрос может выполняться несколько раз, но тут не тот случай. Рестарты в основном вредят в транзакции, если есть не транзакционные операторы (дергание генератора, UDR/UDF отправки почты ...) или автономные транзакции. В остальных случаях они на результат не влияют.

А вот начиная с 3.0 появилась стабильность курсора, которая скорее всего здесь и играет свою роль.

Теперь по коду самого триггера. Ну чего сказать, кто-то его не аккуратно написал так, что одна и та же запись обновляется несколько раз. Ибо по parent в одну и ту же запись из разных вызовов триггеров можно прийти несколько раз.
Расчёт на то что State изменит первый update и он будет виден остальным не верны. Ибо проверка видимости происходит в разных вызовах триггера, но при этом на одном большом update. Тут как раз срабатывает новшество тройки, а не 4.0. Сам по себе курсор update Zatrat стабилен, то есть пока обновляется одна запись, состояние остальных записей из курсора будет неизменным, даже если они обновляются в вызываемых триггерах.

[Обновления: Mon, 26 September 2022 12:30]

Известить модератора

Re: Глюки Firebird4 ? [сообщение #650 является ответом на сообщение #648] Mon, 26 September 2022 10:26 Переход к предыдущему сообщениюПереход к следующему сообщению
hvlad в настоящее время в онлайне  hvlad
Сообщений: 292
Зарегистрирован: August 2022
Senior Member
fraks писал(а) Mon, 26 September 2022 09:08
Или по дефолту в четверке запускается транзакция с таким уровнем изоляции, которая не видит собственных изменений?
Нет таких уровней изоляции
Re: Глюки Firebird4 ? [сообщение #656 является ответом на сообщение #650] Tue, 27 September 2022 12:37 Переход к предыдущему сообщениюПереход к следующему сообщению
anbsoft в настоящее время не в онлайне  anbsoft
Сообщений: 4
Зарегистрирован: September 2022
Junior Member
Кто-нибудь может описать алгоритм работы для 4 версии?
Для 2.0 вроде все логично и понятно:
Рассмотрю пошагово:
Изначально у всех четырех строк State=0 (0,0,0,0) Dolg=0
1) Выполняю UPDATE Zatrat SET State=1 WHERE (ID=1); (1,0,0,0) Dolg=10
2) Срабатывает триггер для 1 строки, выполняется изменение State для 2 строки (1,1,0,0) Dolg=40
3) Срабатывает триггер для 2 строки:
а) 1 строку пропускает, так как у нее State=1
б) выполняется изменение State для 3 строки (1,1,1,0) Dolg=90
4) Срабатывает триггер для 3 строки:
а) 1 и 2 строку пропускает, так как у них State=1
б) выполняется изменение State для 4 строки (1,1,1,1) Dolg=290
5) Срабатывает триггер для 4 строки:
а) 1,2 и 3 строку пропускает, так как у них State=1
6) заканчивает работу триггер для 4 строки
7) заканчивает работу триггер для 3 строки
Cool продолжает работу триггер для 2 строки и пропускает 4 строку, так как там State=1, заканчивает работу
9) продолжает работу триггер для 1 строки и пропускает 3 и 4 строку, так как там State=1, заканчивает работу
10) обновление завершено State (1,1,1,1) Dolg=290

В 4.0 создается впечатление, что рекурсивно запущенные триггеры видят не все уже проведенные изменения.
Re: Глюки Firebird4 ? [сообщение #657 является ответом на сообщение #656] Tue, 27 September 2022 13:10 Переход к предыдущему сообщениюПереход к следующему сообщению
hvlad в настоящее время в онлайне  hvlad
Сообщений: 292
Зарегистрирован: August 2022
Senior Member
anbsoft писал(а) Tue, 27 September 2022 12:37
Кто-нибудь может описать алгоритм работы для 4 версии?
Для 2.0 вроде все логично и понятно:
Рассмотрю пошагово:
Изначально у всех четырех строк State=0 (0,0,0,0) Dolg=0
1) Выполняю UPDATE Zatrat SET State=1 WHERE (ID=1); (1,0,0,0) Dolg=10
2) Срабатывает триггер для 1 строки, выполняется изменение State для 2 строки (1,1,0,0) Dolg=40
3) Срабатывает триггер для 2 строки:
а) 1 строку пропускает, так как у нее State=1
б) выполняется изменение State для 3 строки (1,1,1,0) Dolg=90
4) Срабатывает триггер для 3 строки:
а) 1 и 2 строку пропускает, так как у них State=1
б) выполняется изменение State для 4 строки (1,1,1,1) Dolg=290
5) Срабатывает триггер для 4 строки:
а) 1,2 и 3 строку пропускает, так как у них State=1
6) заканчивает работу триггер для 4 строки
7) заканчивает работу триггер для 3 строки
Cool продолжает работу триггер для 2 строки и пропускает 4 строку, так как там State=1, заканчивает работу
Не вникал в DDL, но вот тут, похоже, работает стабильный курсор, не позволяющий апдейту видеть изменения, сделанные "внутренними" триггерами.

anbsoft
9) продолжает работу триггер для 1 строки и пропускает 3 и 4 строку, так как там State=1, заканчивает работу
10) обновление завершено State (1,1,1,1) Dolg=290

В 4.0 создается впечатление, что рекурсивно запущенные триггеры видят не все уже проведенные изменения.
Всё это есть мина замедленного действия, независимо от версии FB.
Оно зависит от физического порядка записей в таблице, это раз.
Для нескольких сотен записей тут будет переполнение стека, это два.
Бизнес логика в триггерах была, есть и будет - ЗЛО, так делать НЕЛЬЗЯ.
Re: Глюки Firebird4 ? [сообщение #658 является ответом на сообщение #656] Tue, 27 September 2022 13:12 Переход к предыдущему сообщениюПереход к следующему сообщению
МП в настоящее время не в онлайне  МП
Сообщений: 769
Зарегистрирован: August 2022
Географическое положение: бурятский тун...
Senior Member
anbsoft
В 4.0 создается впечатление, что рекурсивно запущенные триггеры видят не все уже проведенные изменения.
RTFM: “Cursor Stability” Effects
Re: Глюки Firebird4 ? [сообщение #659 является ответом на сообщение #656] Tue, 27 September 2022 15:06 Переход к предыдущему сообщениюПереход к следующему сообщению
sim_84 в настоящее время не в онлайне  sim_84
Сообщений: 287
Зарегистрирован: June 2022
Senior Member
ты не учитываешь тот факт, что update это тоже курсор. И обновляет он у тебя отнюдь не одну запись.

Подсказываю

UPDATE Zatrat SET State=NEW.State WHERE (Parent=NEW.Parent) AND (State<>NEW.State) AND (ID<>NEW.ID);
Эквивалентно

FOR 
  SELECT *
  FROM Zatrat
  WHERE (Parent=NEW.Parent) AND (State<>NEW.State) AND (ID<>NEW.ID) 
  AS CURSOR C
DO
  UPDATE SET State=NEW.State WHERE CURRENT OF C;
Не зависимо чего там наменяли триггеры при апдейте первой и последующих записей, сам SELECT выдаст точно такое количество строк и их результаты, как будто UPDATE записей в триггерах вообще не было.

[Обновления: Tue, 27 September 2022 15:12]

Известить модератора

Re: Глюки Firebird4 ? [сообщение #660 является ответом на сообщение #659] Tue, 27 September 2022 15:49 Переход к предыдущему сообщению
anbsoft в настоящее время не в онлайне  anbsoft
Сообщений: 4
Зарегистрирован: September 2022
Junior Member
sim_84 писал(а) Tue, 27 September 2022 15:06
Не зависимо чего там наменяли триггеры при апдейте первой и последующих записей, сам SELECT выдаст точно такое количество строк и их результаты, как будто UPDATE записей в триггерах вообще не было.
Спасибо, теперь понял.
Предыдущая тема: BIN_AND() в Firebird 4.0?
Следующая тема: fb3.0 -> 2.5: found 11.2, support 12.2.
Переход к форуму:
  


Текущее время: Fri Mar 29 00:58:15 GMT+3 2024

Общее время, затраченное на создание страницы: 0.01465 секунд