基于字典映射的PL/SQL数据迁移与分类转换方案问询
PL/SQL 分类数据迁移与转换实现方案
核心需求梳理
- 需求1:Books分类下的Sci-Fi和Fantasy子分类合并转换为
Sci-Fi Fantasy - 需求2:其他分类下的Fantasy子分类保留原名称
- 需求3:Klasyka子分类根据所属分类,匹配字典表中的对应目标值
- 需求4:目标表
Subcategory_ID按公式1000*Category_ID + 源Subcategory_ID生成
前提表结构假设
基于需求,假设现有源表与字典表结构如下(若实际结构不同,可调整字段名适配):
源分类表 (SOURCE_CATEGORY)
| 字段名 | 类型 | 说明 |
|---|---|---|
| CATEGORY_ID | NUMBER | 分类ID(主键) |
| CATEGORY_NAME | VARCHAR2(50) | 分类名称 |
源子分类表 (SOURCE_SUBCATEGORY)
| 字段名 | 类型 | 说明 |
|---|---|---|
| SUBCATEGORY_ID | NUMBER | 子分类ID(主键) |
| CATEGORY_ID | NUMBER | 关联分类ID |
| SUBCATEGORY_NAME | VARCHAR2(50) | 子分类名称 |
字典映射表 (CATEGORY_DICT)
| 字段名 | 类型 | 说明 |
|---|---|---|
| SOURCE_CAT_NAME | VARCHAR2(50) | 源分类名称 |
| SOURCE_SUBCAT_NAME | VARCHAR2(50) | 源子分类名称 |
| TARGET_SUBCAT_NAME | VARCHAR2(50) | 目标子分类名称 |
目标子分类表 (TARGET_SUBCATEGORY)
| 字段名 | 类型 | 说明 |
|---|---|---|
| SUBCATEGORY_ID | NUMBER | 目标子分类ID(主键) |
| CATEGORY_ID | NUMBER | 关联分类ID |
| SUBCATEGORY_NAME | VARCHAR2(50) | 目标子分类名称 |
PL/SQL 迁移脚本
DECLARE CURSOR c_subcat IS SELECT sc.SUBCATEGORY_ID, sc.CATEGORY_ID, sc.SUBCATEGORY_NAME, cat.CATEGORY_NAME FROM SOURCE_SUBCATEGORY sc JOIN SOURCE_CATEGORY cat ON sc.CATEGORY_ID = cat.CATEGORY_ID; v_target_subcat_name VARCHAR2(100); v_target_subcat_id NUMBER; BEGIN -- 清空目标表(可选,根据迁移策略调整) TRUNCATE TABLE TARGET_SUBCATEGORY; FOR rec IN c_subcat LOOP -- 处理需求1:Books分类下的Sci-Fi和Fantasy合并为Sci-Fi Fantasy IF rec.CATEGORY_NAME = 'Books' AND rec.SUBCATEGORY_NAME IN ('Sci-Fi', 'Fantasy') THEN v_target_subcat_name := 'Sci-Fi Fantasy'; -- 处理需求3:Klasyka子分类匹配字典表 ELSIF rec.SUBCATEGORY_NAME = 'Klasyka' THEN SELECT cd.TARGET_SUBCAT_NAME INTO v_target_subcat_name FROM CATEGORY_DICT cd WHERE cd.SOURCE_CAT_NAME = rec.CATEGORY_NAME AND cd.SOURCE_SUBCAT_NAME = rec.SUBCATEGORY_NAME; -- 处理需求2:其他分类下的Fantasy保留原名称,其余子分类默认保留原名称 ELSE v_target_subcat_name := rec.SUBCATEGORY_NAME; END IF; -- 处理需求4:生成目标Subcategory_ID v_target_subcat_id := 1000 * rec.CATEGORY_ID + rec.SUBCATEGORY_ID; -- 插入目标表 INSERT INTO TARGET_SUBCATEGORY (SUBCATEGORY_ID, CATEGORY_ID, SUBCATEGORY_NAME) VALUES (v_target_subcat_id, rec.CATEGORY_ID, v_target_subcat_name); END LOOP; COMMIT; DBMS_OUTPUT.PUT_LINE('数据迁移完成,共处理 ' || SQL%ROWCOUNT || ' 条子分类数据'); EXCEPTION WHEN NO_DATA_FOUND THEN ROLLBACK; DBMS_OUTPUT.PUT_LINE('错误:Klasyka子分类在字典表中无匹配记录,分类名称:' || rec.CATEGORY_NAME); WHEN OTHERS THEN ROLLBACK; DBMS_OUTPUT.PUT_LINE('迁移失败,错误码:' || SQLCODE || ',错误信息:' || SQLERRM); END; /
关键逻辑说明
- 需求1实现:通过判断分类名称为
Books且子分类是Sci-Fi或Fantasy,直接赋值合并后的名称 - 需求2实现:仅在Books分类下处理Fantasy,其余分类的Fantasy进入ELSE分支,保留原名称
- 需求3实现:当子分类是
Klasyka时,通过分类名称和子分类名称关联字典表,取出目标名称 - 需求4实现:严格按照公式计算目标子分类ID,确保唯一标识
注意事项
- 若迁移时不需要清空目标表,可删除
TRUNCATE TABLE语句,改为增量迁移逻辑(比如通过判断ID是否已存在) - 需确保字典表中
Klasyka子分类的映射记录完整,避免抛出NO_DATA_FOUND异常 - 可根据实际表结构调整字段名、数据类型及长度
内容的提问来源于stack exchange,提问作者Karol Witkowski
相关产品推荐
相关产品推荐

