Informix数据库中递增更新serial_num字段的技术问题
问题描述
我在Informix数据库中有一张名为store的表,初始数据如下:
| serial_num | store_seq |
|---|---|
| 381-15 | 82600 |
| 381-15 | 82610 |
| 381-15 | 82640 |
| 381-15 | 82650 |
| 381-15 | 82680 |
| 381-114-1 | 82690 |
需要将serial_num字段按规则递增更新,目标结果如下:
| serial_num | store_seq |
|---|---|
| 381-15-1 | 82600 |
| 381-15-2 | 82610 |
| 381-15-3 | 82640 |
| 381-15-4 | 82650 |
| 381-15-5 | 82680 |
| 381-114-1 | 82690 |
我尝试创建了如下存储过程:
CREATE PROCEDURE update_store() DEFINE counter INTEGER; DEFINE temp_serial_num CHAR(20); FOREACH cur1 FOR SELECT serial_num INTO temp_serial_num FROM store WHERE serial_num = '381-15' LET counter = 0; WHILE counter < (SELECT COUNT(*) FROM store WHERE serial_num = '381-15') LET counter = counter + 1; UPDATE store SET serial_num = temp_serial_num || '-' || counter::CHAR WHERE CURRENT OF cur1; END WHILE; END FOREACH; END PROCEDURE;
但执行后所有原serial_num为'381-15'的记录都被更新为'381-15-5'。
注:serial_num字段为CHAR(16)类型,store_seq为INTEGER类型。
问题原因
你的存储逻辑存在核心错误:
- 外层
FOREACH会遍历每一条serial_num = '381-15'的记录 - 针对每条记录,你又执行了一个循环次数等于该类记录总数(5次)的
WHILE循环 - 这导致每条记录都会被连续更新5次,从
381-15-1一直覆盖到381-15-5,最终所有记录都停留在最后一次更新的结果
解决方案
只需要在外层循环外初始化计数器,遍历每条目标记录时递增计数器并执行一次更新即可:
CREATE PROCEDURE update_store() DEFINE counter INTEGER; DEFINE temp_serial_num CHAR(20); -- 初始化计数器为0,避免每次遍历重置 LET counter = 0; -- 按store_seq排序遍历,确保序号和目标顺序匹配 FOREACH cur1 FOR SELECT serial_num INTO temp_serial_num FROM store WHERE serial_num = '381-15' ORDER BY store_seq LET counter = counter + 1; -- 仅更新当前遍历到的这条记录 UPDATE store SET serial_num = temp_serial_num || '-' || counter::CHAR WHERE CURRENT OF cur1; END FOREACH; END PROCEDURE;
关键调整点
- 将计数器初始化移到
FOREACH循环外,保证计数全局递增 - 添加
ORDER BY store_seq,确保更新后的序号和预期的顺序一致(按store_seq从小到大排列) - 移除冗余的
WHILE循环,每条记录仅更新一次,避免重复覆盖
验证说明
执行该存储过程后,每条serial_num = '381-15'的记录会按store_seq的顺序依次被更新为381-15-1到381-15-5,其他记录不受影响,完全匹配预期结果。
内容的提问来源于stack exchange,提问作者Cikson
相关产品推荐
相关产品推荐

