假设我创建了以下表:
create table SAMPLE (
ID INTEGER,
COL_A INTEGER,
COL_B INTEGER
);
create table SAMPLE_CLONE (
ID INTEGER,
COL_A INTEGER,
COL_B INTEGER
);
我创建了以下触发器:
-- Increment COL_A on every update
CREATE TRIGGER INC_COL_A AFTER UPDATE ON SAMPLE
REFERENCING OLD AS oldrow NEW AS newrow
FOR EACH ROW MODE DB2SQL
WHEN (oldrow.COL_A = newrow.COL_A)
UPDATE SAMPLE SET COL_A = COL_A+1 WHERE ID = oldrow.ID;
-- Replicate inserts from SAMPLE to SAMPLE_CLONE
CREATE TRIGGER REPLICATE_INSERTED_DATA
AFTER INSERT ON SAMPLE
REFERENCING NEW AS newrow
FOR EACH ROW MODE DB2SQL
INSERT INTO SAMPLE_CLONE (ID, COL_A, COL_B) VALUES (newrow.ID, newrow.COL_A, newrow.COL_B);
-- Replicate updates from SAMPLE to SAMPLE_CLONE
CREATE TRIGGER REPLICATE_UPDATED_DATA
AFTER UPDATE ON SAMPLE
REFERENCING NEW AS newrow OLD AS oldrow
FOR EACH ROW MODE DB2SQL
UPDATE SAMPLE_CLONE SET COL_A = newrow.COL_A, COL_B = newrow.COL_B WHERE ID = newrow.ID;
我遇到的问题是,在SAMPLE表上运行任何更新后,由触发器INC_COL_A
递增的COL_A最新值在触发器REPLICATE_UPDATED_DATA处理期间没有反映到newrow
中。例如,如果我有以下数据:
INSERT INTO SAMPLE (ID, COL_A, COL_B) VALUES (1, 1, 100);
样品
| 识别码|列_A|列_B|
| - -|- -|- -|
| 一个|一个|100个|
样本克隆
| 识别码|列_A|列_B|
| - -|- -|- -|
| 一个|一个|100个|
然后,在运行以下命令后:
UPDATE SAMPLE SET COL_B = 200 WHERE ID = 1;
我在这些表上得到了以下提交结果:
样品
| 识别码|列_A|列_B|
| - -|- -|- -|
| 一个|2个|二百个|
样本克隆
| 识别码|列_A|列_B|
| - -|- -|- -|
| 一个|一个|二百个|
请注意,SAMPLE_CLONE.COL_A
上的记录没有被REPLICATE_UPDATED_DATA
触发器复制,因为它没有获得INC_COL_A
触发器所做的更新。
我在使用DB2 11.5时遇到了这个问题
2条答案
按热度按时间tag5nh1u1#
共享事件、时间和目标的触发器按其创建顺序执行。每个
BEFORE
触发器都可以修改NEW ROW
,后续的BEFORE
触发器将使用修改后的行。每个AFTER
触发器都将接收相同的最终行,它们都不能修改它。这里,
INC_COL_A
和REPLICATE_UPDATED_DATA
按此顺序执行。所以当
UPDATE SAMPLE SET COL_B = 200 WHERE ID = 1;
运行时COLB_B = 200
INC_COL_A
被触发,执行UPDATE SAMPLE SET COL_A = 2
1.此更新将再次触发
INC_COL_A
,但由于COL_A
在旧行和新行中相同,因此不会发生任何情况REPLICATE_UPDATED_DATA
使用COL_A = 2, COL_B = 200
处理行,并将其复制到SAMPLE_CLONE
INC_COL_A
内部的UPDATE语句现在已经完成,但是REPLICATE_UPDATED_DATA
仍然需要处理COL_A = 1, COL_B = 200
。最后,
COL_A = 1
和遵循一个逻辑。在**INC_COL_A
之前创建REPLICATE_UPDATED_DATA
**,您的触发器将按预期工作。检查实际行值是否与旧行值匹配可能是这里的一个解决方案,但可能不是您在真实的应用程序中所需要的。
5lhxktic2#
这不是让更新(或插入)触发器更改写入的值的正确方法...您需要使用
BEFORE
更新(插入)触发器