背景:
數據庫所有序列都重置為1了,所以要將所有的序列都更新為對應的表主鍵(這里是id)的最大值+1。我這里序列的規則是SEQ_表名。
BEGINENHANCED_SYNC_SEQUENCES('WJ_CPP'); -- 替換為你的模式名
END;
/
CREATE OR REPLACE PROCEDURE ENHANCED_SYNC_SEQUENCES(p_schema_name IN VARCHAR2) ISv_table_name VARCHAR2(30);v_seq_name VARCHAR2(30);v_max_id NUMBER;v_new_seq_value NUMBER;v_current_seq_value NUMBER;v_increment_by NUMBER;v_table_exists NUMBER;v_step VARCHAR2(100); -- 記錄當前執行步驟,便于排查CURSOR c_sequences ISSELECT sequence_nameFROM all_sequencesWHERE sequence_owner = UPPER(p_schema_name)AND sequence_name LIKE 'SEQ\_%' ESCAPE '\';
BEGINDBMS_OUTPUT.PUT_LINE('=== 開始處理模式: ' || UPPER(p_schema_name) || ' ===');FOR seq_rec IN c_sequences LOOPv_seq_name := seq_rec.sequence_name;DBMS_OUTPUT.PUT_LINE(CHR(10) || '--- 處理序列: ' || v_seq_name || ' ---');-- 步驟1: 提取表名v_step := '提取表名';v_table_name := SUBSTR(v_seq_name, 5);DBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 對應表名 -> ' || v_table_name);-- 步驟2: 檢查表是否存在v_step := '檢查表是否存在';SELECT COUNT(*) INTO v_table_existsFROM all_tablesWHERE owner = UPPER(p_schema_name)AND table_name = UPPER(v_table_name);IF v_table_exists = 0 THENDBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 警告 - 表不存在,跳過');CONTINUE;END IF;DBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 表存在');-- 步驟3: 檢查ID列是否存在v_step := '檢查ID列是否存在';DECLAREv_id_exists NUMBER;BEGINSELECT COUNT(*) INTO v_id_existsFROM all_tab_columnsWHERE owner = UPPER(p_schema_name)AND table_name = UPPER(v_table_name)AND column_name = 'ID';IF v_id_exists = 0 THENDBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 警告 - 無ID列,跳過');CONTINUE;END IF;END;DBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: ID列存在');-- 步驟4: 查詢表最大IDv_step := '查詢表最大ID';BEGINEXECUTE IMMEDIATE 'SELECT NVL(MAX(ID), 0) FROM ' || p_schema_name || '.' || v_table_nameINTO v_max_id;v_new_seq_value := v_max_id + 1;DBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 表最大ID=' || v_max_id || ', 目標序列值=' || v_new_seq_value);EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 錯誤 - ' || SQLERRM);CONTINUE;END;-- 步驟5: 獲取序列當前值v_step := '獲取序列當前值';BEGINEXECUTE IMMEDIATE 'SELECT ' || p_schema_name || '.' || v_seq_name || '.NEXTVAL FROM DUAL'INTO v_current_seq_value;DBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 序列當前值=' || v_current_seq_value);EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 錯誤 - ' || SQLERRM);CONTINUE;END;-- 步驟6: 判斷是否需要調整v_step := '判斷是否需要調整';IF v_current_seq_value >= v_new_seq_value THENDBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 無需調整(當前值 >= 目標值)');CONTINUE;END IF;DBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 需要調整(當前值 < 目標值)');-- 步驟7: 調整序列v_step := '調整序列';BEGIN-- 計算增量v_increment_by := v_new_seq_value - v_current_seq_value;DBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 臨時增量=' || v_increment_by);-- 修改增量EXECUTE IMMEDIATE 'ALTER SEQUENCE ' || p_schema_name || '.' || v_seq_name || ' INCREMENT BY ' || v_increment_by;-- 觸發增量EXECUTE IMMEDIATE 'SELECT ' || p_schema_name || '.' || v_seq_name || '.NEXTVAL FROM DUAL' INTO v_current_seq_value;DBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 調整后的值=' || v_current_seq_value);-- 恢復增量EXECUTE IMMEDIATE 'ALTER SEQUENCE ' || p_schema_name || '.' || v_seq_name || ' INCREMENT BY 1';DBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 恢復增量為1,處理成功');EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 錯誤 - ' || SQLERRM);-- 嘗試恢復增量BEGINEXECUTE IMMEDIATE 'ALTER SEQUENCE ' || p_schema_name || '.' || v_seq_name || ' INCREMENT BY 1';EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('步驟[' || v_step || ']: 恢復增量失敗 - ' || SQLERRM);END;CONTINUE;END;END LOOP;DBMS_OUTPUT.PUT_LINE(CHR(10) || '=== 所有序列處理完畢 ===');
END ENHANCED_SYNC_SEQUENCES;
/