表重定义 ```sql DECLARE -- 参数定义 l_orig_table VARCHAR2(30) := 'T_FOC_CREW_MQ_NEW'; l_int_table VARCHAR2(30) := 'T_FOC_CREW_MQ_NEW_TEMP'; l_orig_owner VARCHAR2(30) := 'KNDBFOC'; l_tablespace VARCHAR2(30) := 'KNDBFOC'; -- 变量 l_num_errors PLS_INTEGER := 0; l_start_time TIMESTAMP; l_end_time TIMESTAMP; BEGIN DBMS_OUTPUT.PUT_LINE('[INFO] 开始在线重定义流程: ' || TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS')); l_start_time := SYSTIMESTAMP; -- Step 1: 检查是否支持重定义 DBMS_OUTPUT.PUT_LINE('[INFO] 步骤 1: 检查表是否支持在线重定义...'); BEGIN DBMS_REDEFINITION.CAN_REDEF_TABLE( uname => l_orig_owner, tname => l_orig_table, options_flag => DBMS_REDEFINITION.CONS_USE_PK ); DBMS_OUTPUT.PUT_LINE('[SUCCESS] 表支持在线重定义。'); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('[ERROR] 检查失败: ' || SQLERRM); RAISE; END; -- Step 2: 创建中间分区表 DBMS_OUTPUT.PUT_LINE('[INFO] 步骤 2: 创建中间分区表...'); BEGIN EXECUTE IMMEDIATE ' CREATE TABLE ' || l_orig_owner || '.' || l_int_table || ' ( ID NUMBER(38) NOT NULL, MESSAGE_ID VARCHAR2(255), TOPIC VARCHAR2(255), CHANNEL VARCHAR2(255), INSERT_TIME DATE, TEXT1 VARCHAR2(2000), TEXT2 VARCHAR2(2000 CHAR), TEXT3 VARCHAR2(2000 CHAR), TEXT4 VARCHAR2(2000 CHAR) ) PARTITION BY RANGE (INSERT_TIME) INTERVAL(NUMTOYMINTERVAL(1, ''MONTH'')) ( PARTITION P_INIT VALUES LESS THAN (DATE ''2020-01-01'') ) TABLESPACE ' || l_tablespace; DBMS_OUTPUT.PUT_LINE('[SUCCESS] 中间表创建成功。'); EXCEPTION WHEN OTHERS THEN IF SQLCODE = -955 THEN DBMS_OUTPUT.PUT_LINE('[WARNING] 表已存在,跳过创建。'); ELSE DBMS_OUTPUT.PUT_LINE('[ERROR] 创建失败: ' || SQLERRM); RAISE; END IF; END; -- Step 3: 开始重定义 DBMS_OUTPUT.PUT_LINE('[INFO] 步骤 3: 开始在线重定义...'); BEGIN DBMS_REDEFINITION.START_REDEF_TABLE( uname => l_orig_owner, orig_table => l_orig_table, int_table => l_int_table, options_flag => DBMS_REDEFINITION.CONS_USE_PK ); DBMS_OUTPUT.PUT_LINE('[SUCCESS] 重定义已启动。'); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('[ERROR] 启动失败: ' || SQLERRM); RAISE; END; -- Step 4: 复制依赖对象(✅ 极简调用,仅传必要参数) DBMS_OUTPUT.PUT_LINE('[INFO] 步骤 4: 复制依赖对象...'); l_num_errors := 0; -- 重置错误计数 BEGIN DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS( uname => l_orig_owner, orig_table => l_orig_table, int_table => l_int_table, num_errors => l_num_errors ); IF l_num_errors = 0 THEN DBMS_OUTPUT.PUT_LINE('[SUCCESS] 依赖对象复制完成。'); ELSE DBMS_OUTPUT.PUT_LINE('[WARNING] 复制完成,但有 ' || l_num_errors || ' 个错误。'); DBMS_OUTPUT.PUT_LINE('[INFO] 请查询 DBA_REDEFINITION_ERRORS 查看详情。'); END IF; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('[ERROR] 复制依赖对象时出错: ' || SQLERRM); -- 不中断,继续完成 END; -- Step 5: 同步增量数据 DBMS_OUTPUT.PUT_LINE('[INFO] 步骤 5: 同步增量数据...'); BEGIN DBMS_REDEFINITION.SYNC_INTERIM_TABLE( uname => l_orig_owner, orig_table => l_orig_table, int_table => l_int_table ); DBMS_OUTPUT.PUT_LINE('[SUCCESS] 增量同步完成。'); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('[WARNING] 增量同步失败: ' || SQLERRM); END; -- Step 6: 完成重定义 DBMS_OUTPUT.PUT_LINE('[INFO] 步骤 6: 完成重定义...'); BEGIN DBMS_REDEFINITION.FINISH_REDEF_TABLE( uname => l_orig_owner, orig_table => l_orig_table, int_table => l_int_table ); DBMS_OUTPUT.PUT_LINE('[SUCCESS] 重定义完成!表已成功转为分区表。'); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('[ERROR] 完成失败: ' || SQLERRM); RAISE; END; l_end_time := SYSTIMESTAMP; DBMS_OUTPUT.PUT_LINE('[INFO] 总耗时: ' || TO_CHAR(l_end_time - l_start_time)); DBMS_OUTPUT.PUT_LINE('[INFO] ✅ 操作成功!'); DBMS_OUTPUT.PUT_LINE('[INFO] ⚠️ 注意:请手动重新授权该表的访问权限。'); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('[FATAL] 未预期错误: ' || SQLERRM); DBMS_OUTPUT.PUT_LINE('[INFO] 如需中止,请运行:'); DBMS_OUTPUT.PUT_LINE('BEGIN DBMS_REDEFINITION.ABORT_REDEF_TABLE(''KNDBFOC'', ''T_FOC_CREW_MQ_NEW'', ''T_FOC_CREW_MQ_NEW_TEMP''); END;'); RAISE; END; / ``` ```sql ALTER SYSTEM FLUSH SHARED_POOL; ```