update
This commit is contained in:
		
							
								
								
									
										161
									
								
								oracle/oracle-表重定义.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								oracle/oracle-表重定义.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
			
		||||
表重定义
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```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;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user