银行数据库链式交易表的联动更新(基于计算列)需求
银行交易链式结构的联动更新解决方案
我们在银行数据库中,需要在Operation表存储账户交易记录及每笔交易后的账户余额,表结构定义如下:
CREATE TABLE Operation ( Id int PRIMARY KEY, Change int, PreviousId int null FOREIGN KEY REFERENCES Operation(id), PreviousAmount int null, NewAmount AS (COALESCE(PreviousAmount,0) + Change) PERSISTED );
注:为简化展示,已移除AccountId、Date等部分字段
其中PreviousId存储账户上一笔交易的ID,以此形成交易链式结构。
插入测试数据:
INSERT INTO Operation (Id, Change, PreviousId, PreviousAmount) VALUES (1, 1, null, null), (2, 2, 1, 1), (3, 3, 2, 3), (4, 4, 3, 5);
此时表中数据状态如下:
| id | change | previousId | previousAmount | newAmount |
|---|---|---|---|---|
| 1 | 1 | NULL | NULL | 1 |
| 2 | 2 | 1 | 1 | 3 |
| 3 | 3 | 2 | 3 | 6 |
| 4 | 4 | 3 | 6 | 10 |
当执行如下更新语句修改首行的Change字段时:
Update Operation set Change=10 where id=1
我们需要一个数据库级的解决方案(如触发器),自动更新链式结构中所有后续行的PreviousAmount,确保每一行的PreviousAmount等于其前一行更新后的NewAmount。
补充说明
我选择使用计算列而非触发器中用窗口函数计算NewAmount的方案,原因是计算列能可靠验证NewAmount非负:
- 若用窗口函数,需先执行更新,再通过额外查询更新
NewAmount并检查是否为负,若为负则回滚事务; - 而计算列搭配数据库约束,无需额外查询与事务回滚,数据库引擎会自动完成非负验证。
内容的提问来源于stack exchange,提问作者HamedH
相关产品推荐
相关产品推荐

