Стук в подвале. Ждем более-менее реального описания проблемы.
Я сам дурак судя по всему + стечение обстоятельств, поскольку локально точно
такая же база работает нормально. Посему возник у меня вопрос, но для начала
упрощённо опишу ситуацию в которую я попал:
1) Есть 3 таблицы, отображающие уровни вложенности, например:
CREATE TABLE MASTER(
ID INTEGER NOT NULL PRIMARY KEY,
);
CREATE TABLE DETAIL(
ID INTEGER NOT NULL PRIMARY KEY,,
MASTER_ID INTEGER NOT NULL REFERENCES MASTER (ID) ON UPDATE CASCADE
);
CREATE TABLE SUB_DETAIL(
ID INTEGER NOT NULL PRIMARY KEY,,
MASTER_ID INTEGER NOT NULL REFERENCES MASTER (ID) ON UPDATE CASCADE,
DETAIL_ID INTEGER NOT NULL REFERENCES DETAIL (ID) ON UPDATE CASCADE
);
таким образом MASTER - это объекты первого уровня, DETAIL второго, SUB_DETAIL
третьего
2) В таблице SUB_DETAIL поле MASTER_ID избыточно с точки зрения нормализации,
но поскольку оно мне часто нужно в запросах, я решил его добавить и заполнять
автоматически в триггере примерно так:
CREATE TRIGGER SUB_DETAIL_BIU0 FOR SUB_DETAIL
ACTIVE BEFORE INSERT OR UPDATE POSITION 0
AS
BEGIN
SELECT MASTER_ID FROM DETAIL WHERE ID = NEW.DETAIL_ID INTO NEW.MASTER_ID;
END
3)Здесь идут мои догадки. Подозреваю что нет чётко определённого времени вызова системных триггеров, выполняющих ON UPDATE CASCADE. Поэтому локально у меня они вызывались скорее всего до вызова SUB_DETAIL_BIU0, а удалённо после. По этой же причине я могу предположить что удаление и создание ограничений, а также b/r меняли позиции вызовов системных триггеров относительно SUB_DETAIL_BIU0, так что в некоторых случаях я попадал на ситуацию что
SELECT MASTER_ID FROM DETAIL WHERE ID = NEW.DETAIL_ID INTO NEW.MASTER_ID;
возвращало мне старое значение из таблицы DETAIL до того как системный триггер
обновлял его по каскаду в DETAIL.
Собственно вопрос в том прав ли я в своих догадках.
Ну и другой аспект: если я прав, то очень нехорошо получается что время вызова
(или позиция вызова) системного триггера, реализующено ON UPDATE CASCADE может
меняться. Фактически успех выполнения апдейта зависит от того в какой
последовательности выполняться триггеры для ключей
MASTER_ID INTEGER NOT NULL REFERENCES MASTER (ID) ON UPDATE CASCADE
DETAIL_ID INTEGER NOT NULL REFERENCES DETAIL (ID) ON UPDATE CASCADE
Может быть как-то это следует обсудить и поменять поведение, например для
ключей с CASCADE обновление делать до всех остальных триггеров?