首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 11g 匯出空表失敗:deferred_segment_creation 參數導致無 Segment 的根因與解法

     編輯:Oracle 資料庫基礎

現象

使用 exp 匯出資料時,空表(無資料列)未出現在匯出檔中。

根因

Oracle 11g 引入 deferred_segment_creation = TRUE(預設),建立空表時不立即配置 Segment(Extent),導致 exp 忽略此類表。

解法一:手動為空表配置 Extent(針對既有表)

-- 1. 先更新統計資訊確認 NUM_ROWS=0
ANALYZE TABLE table_name COMPUTE STATISTICS;

-- 2. 產生 ALTER TABLE ... ALLOCATE EXTENT 指令
SELECT 'ALTER TABLE ' || table_name || ' ALLOCATE EXTENT;'
FROM user_tables WHERE num_rows = 0;

-- 3. 複製輸出的指令至 SQL 工具執行,再重新 exp 即可匯出空表

解法二:暴力法——全 Schema 空表一次配置

SELECT 'ALTER TABLE ' || table_name || ' ALLOCATE EXTENT;'
FROM user_tables WHERE num_rows = 0;

解法三:PL/SQL 程序自動偵測 COUNT=0 並配置

DECLARE
  v_table  tabs.table_name%TYPE;
  v_sql    VARCHAR2(888);
  v_q      NUMBER;
  v_alter  VARCHAR2(1000);
  CURSOR c1 IS SELECT table_name tn FROM tabs;
  TYPE c IS REF CURSOR;
  c2 c;
BEGIN
  DBMS_OUTPUT.PUT_LINE('以下為空資料表的表名:');
  FOR r1 IN c1 LOOP
    v_table := r1.tn;
    v_sql := 'SELECT COUNT(*) q FROM ' || v_table;
    OPEN c2 FOR v_sql;
    LOOP
      FETCH c2 INTO v_q;
      EXIT WHEN c2%NOTFOUND;
      IF v_q = 0 THEN
        DBMS_OUTPUT.PUT_LINE(v_table);
        v_alter := 'ALTER TABLE ' || v_table || ' ALLOCATE EXTENT';
        DBMS_OUTPUT.PUT_LINE(v_alter);
        -- 取消下行註解即實際執行
        -- EXECUTE IMMEDIATE v_alter;
      END IF;
    END LOOP;
    CLOSE c2;
  END LOOP;
EXCEPTION WHEN OTHERS THEN
  DBMS_OUTPUT.PUT_LINE('Error occurred');
END;

根治方案:關閉延遲段建立

ALTER SYSTEM SET deferred_segment_creation = FALSE SCOPE = BOTH;

修改後需重啟資料庫實例,後續新建表即會立即配置 Segment,exp 可正常匯出空表。

驗證參數

SHOW PARAMETER deferred_segment_creation;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved