Oracle游标实现:将Table1列值转为TableNew多行插入数据
基于Oracle游标实现表结构转换与数据迁移
需求说明
需将旧数据库Table1的列数据转换为新数据库TableNew的多行数据,借助映射表建立列与DisableID的对应关系:
旧表Table1结构与示例数据
| Table1ID | WheelCount | BlindCount | OtherCount |
|---|---|---|---|
| 1 | 1 | 2 | 5 |
| 2 | 8 | 10 | 15 |
映射表结构与数据
| DisableID | Type |
|---|---|
| 1 | wheelCount |
| 2 | blindcount |
| 3 | otherCount |
新表TableNew预期结果
| ID | Table1ID | DISABLEID | QUANTITY |
|---|---|---|---|
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 2 |
| 3 | 1 | 3 | 5 |
| 4 | 2 | 1 | 8 |
| 5 | 2 | 2 | 10 |
| 6 | 2 | 3 | 15 |
游标实现代码
方式一:硬编码映射关系(适用于映射固定场景)
-- 先创建TableNewID的自增序列(若已存在可跳过) CREATE SEQUENCE TABLENEW_ID_SEQ START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE; DECLARE -- 定义游标遍历Table1所有数据 CURSOR c_table1 IS SELECT Table1ID, WheelCount, BlindCount, OtherCount FROM Table1; -- 定义变量存储游标读取的值 v_table1id Table1.Table1ID%TYPE; v_wheelcount Table1.WheelCount%TYPE; v_blindcount Table1.BlindCount%TYPE; v_othercount Table1.OtherCount%TYPE; BEGIN OPEN c_table1; LOOP -- 读取游标数据到变量 FETCH c_table1 INTO v_table1id, v_wheelcount, v_blindcount, v_othercount; -- 游标无数据时退出循环 EXIT WHEN c_table1%NOTFOUND; -- 插入wheelCount对应记录 INSERT INTO TableNew (TableNewID, Table1ID, DisableID, Quantity) VALUES (TABLENEW_ID_SEQ.NEXTVAL, v_table1id, 1, v_wheelcount); -- 插入blindcount对应记录 INSERT INTO TableNew (TableNewID, Table1ID, DisableID, Quantity) VALUES (TABLENEW_ID_SEQ.NEXTVAL, v_table1id, 2, v_blindcount); -- 插入otherCount对应记录 INSERT INTO TableNew (TableNewID, Table1ID, DisableID, Quantity) VALUES (TABLENEW_ID_SEQ.NEXTVAL, v_table1id, 3, v_othercount); END LOOP; CLOSE c_table1; -- 提交事务 COMMIT; EXCEPTION WHEN OTHERS THEN -- 异常时回滚事务并抛出错误 ROLLBACK; RAISE; END; /
方式二:动态关联映射表(适用于映射可能变动场景)
如果映射表的DisableID或Type可能调整,可通过查询映射表动态获取对应关系,避免硬编码:
CREATE SEQUENCE TABLENEW_ID_SEQ START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE; DECLARE CURSOR c_table1 IS SELECT Table1ID, WheelCount, BlindCount, OtherCount FROM Table1; v_table1id Table1.Table1ID%TYPE; v_wheelcount Table1.WheelCount%TYPE; v_blindcount Table1.BlindCount%TYPE; v_othercount Table1.OtherCount%TYPE; v_disableid NUMBER; -- 存储从映射表获取的DisableID BEGIN OPEN c_table1; LOOP FETCH c_table1 INTO v_table1id, v_wheelcount, v_blindcount, v_othercount; EXIT WHEN c_table1%NOTFOUND; -- 动态获取wheelCount对应的DisableID SELECT DisableID INTO v_disableid FROM 映射表 WHERE Type = 'wheelCount'; INSERT INTO TableNew (TableNewID, Table1ID, DisableID, Quantity) VALUES (TABLENEW_ID_SEQ.NEXTVAL, v_table1id, v_disableid, v_wheelcount); -- 动态获取blindcount对应的DisableID SELECT DisableID INTO v_disableid FROM 映射表 WHERE Type = 'blindcount'; INSERT INTO TableNew (TableNewID, Table1ID, DisableID, Quantity) VALUES (TABLENEW_ID_SEQ.NEXTVAL, v_table1id, v_disableid, v_blindcount); -- 动态获取otherCount对应的DisableID SELECT DisableID INTO v_disableid FROM 映射表 WHERE Type = 'otherCount'; INSERT INTO TableNew (TableNewID, Table1ID, DisableID, Quantity) VALUES (TABLENEW_ID_SEQ.NEXTVAL, v_table1id, v_disableid, v_othercount); END LOOP; CLOSE c_table1; COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; END; /
代码说明
- 序列
TABLENEW_ID_SEQ用于生成TableNew的自增主键TableNewID,确保每条记录ID唯一。 - 游标
c_table1遍历Table1的所有数据,逐行处理转换。 - 两种方式分别对应固定映射和动态映射场景,可根据实际需求选择。
- 异常处理部分确保出错时回滚事务,避免数据不一致。
内容的提问来源于stack exchange,提问作者jubi
相关产品推荐
相关产品推荐

