oracle 11g不能匯出空表的多種解決方法

2021-08-17 07:01:17 字數 3878 閱讀 3658

查資料發現oracle 11g中有個新特性:新增了乙個引數「deferred_segment_creation」含義是段延遲建立,預設是true。

具體是什麼意思呢?

如果這個引數設定為true,你新建了乙個表table1,並且沒有向其中插入資料,那麼這個表不會立即分配extent,也就是不佔資料空間,即表也不分配 segment 以節省空間,所以這些表也沒能匯出來。在系統表user_tables中也可以看到segment_treated的字段裡是「no」或者「yes」說明了某張表是否分配了segment。說白了是為了可以節省少量的空間。

用下面的sql語句查詢,可以發現沒有匯出的表其 segment_created 字段值都是 'no'。

select segment_created,table_name from user_tables where segment_created = 'no';

解決方法:

1、最原始最笨的辦法(不推薦):insert一行,再rollback或者刪除就產生segment了。

該方法是在在空表中插入資料,再刪除,則產生segment。匯出時則可匯出空表。

2、設定deferred_segment_creation 引數:

設定deferred_segment_creation 引數為false來禁用"段推遲建立"(也就是直接建立segment),無論是空表還是非空表,都分配segment。

在sqlplus中,執行如下命令:

sql>alter system set deferred_segment_creation=false;

檢視:sql>show parameter deferred_segment_creation;

注意:該值設定後只對後面新增的表產生作用,對之前建立的空表(已經存在的)不起作用,仍不能匯出。

並且要重新啟動資料庫,讓引數生效。

3、使用allocate extent,可以匯出之前已經存在的空表。

使用allocate extent可以為資料庫物件的每一張表分配extent(注意針對每一張表,就是說一張表需要一條sql**):

其語法如下:

-----------

allocate extent

-----------

可以針對資料表、索引、物化檢視等手工分配extent。

allocate extent使用樣例:

allocate extent

allocate extent(size integer [k | m])

allocate extent(datafile 'filename')

allocate extent(instance integer)  www.2cto.com

allocate extent(size integer [k | m]   datafile 'filename')

allocate extent(size integer [k | m]   instance integer)

針對資料表操作的完整語法如下:

-----------

alter table [schema.] table_name allocate extent [()]

-----------

故,需要構建如下樣子簡單的sql命令:

-----------

alter table tablename allocate extent

-----------

但要是每一張表寫一條語句的話太過麻煩,為了方便我們使用sql命令拼寫出每一張表的alter語句。

構建對空表分配空間的sql命令。

查詢當前使用者下的所有空表(乙個使用者最好對應乙個預設表空間)。命令如下:

sql>select table_name from user_tables where num_rows=0; 

根據上述查詢,可以構建針對空表分配空間的命令語句,如下:

sql>select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0 or num_rows is null(注意:很多教程沒有這裡,這裡是有可能位空的)

上述**可產生批量的修改表extent的sql語句(有多少張空表就產生多少條),我們只需要將其生成的所有sql**全部執行,就可以給每一張已經存在的表來分配segment,就ok了。

最後:這時再用exp匯出就沒有問題了。

但是:資料庫本身的deferred_segment_creation屬性還是true,也是就是說如果再建立新錶的話,預設還是不分配segment的。所以還是需要更改deferred_segment_creation的引數,以便以後建立的新錶自動分配segment。

總結:如果你的資料庫還沒有建立任何資料表,那麼直接修改deferred_segment_creation屬性,以後建立的表無論是不是為空都會自動分配segment,就不會出現導不出空表的情況。然而如果你的資料庫中已經有很多空表,並且需要匯出來,那麼光修改deferred_segment_creation屬性則沒有用的,因為它只對之後建立的表有作用。你需要給已存在的空表分配segment以便可以匯出存在的空表,就用到上面講的allocate extent方法,但此方法只針對已經存在的表的segment屬性,所以最好就是:先給已存在的空表分配segment,方便其可以直接匯出,然後設定deferred_segment_creation引數以便以後每張表無論是否為空都自動分配segment。

附錄:有關第三種方法給已經存在的空表分配segment,下面介紹一種生成指令碼來執行sql的方法。

sql>select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0 or num_rows is null;

批量輸出上述生成的sql語句並寫入到乙個.sql的指令碼檔案中。

如: 1. 建立執行指令碼檔案:我建立乙個e:\sql_script.sql檔案。內容如下:

set heading off;

set echo off;

set feedback off;

set termout on;

spool e:\sql_allocate.sql;

select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0 or num_rows is null;

spool off;

這個指令碼的作用就是建立乙個e:\sql_allocate.sql指令碼檔案,將select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0 or num_rows is null的執行結果(就是給每張表生成segment的sql**)批量輸出,儲存到乙個e:\sql_allocate.sql的指令碼檔案中。

2. 執行e:\sql_script.sql檔案來生成「分配表空間的sql**」的指令碼檔案sql_allocate.sql。

命令如下:

sql>@ e:\sql_script.sql;  (也可寫乙個批處理檔案,命令如下:sqlplus 使用者名稱/密碼@資料庫 @e:\sql_script.sql)

執行完畢後,得到e:\sql_allocate.sql指令碼檔案(裡面是給所有空表分配segment的sql**)。 

開啟該檔案會看到,已經得到對所有空表分配空間的sql語句。

3. 執行e:\sql_allocate.sql檔案來對錶分配空間。

命令如下:sql>@ e:\sql_allocate.sql

執行完畢,表已更改。之前存在的空表已分配segment空間!

大功告成

,此時執行exp命令,即可把包括空表在內的所有表,正常匯出。

oracle11g匯出空表

該引數意思是當建立物件 如表 初始時沒有資料,是否立即建立segment。預設是true。這會導致在按使用者匯出時,沒有segment的物件不會匯出。首先執行下面的語句 select alter table table name allocate extent from user tables wh...

oracle 11g匯出空表

oracle 11g 用exp命令匯出庫檔案備份時,發現只能匯出來一部分表而且不提示錯誤,之前找不到解決方案只能把沒匯出來的表重新建建立。後來發現是所有的空表都沒有匯出來。於是想好好查查,因為在以前的10g版本中沒有這樣的問題。查資料發現oracle 11g中有個新特性 新增了乙個引數 deferr...

oracle11g 空表匯出

oracle11g的新特性,資料條數是0時不分配segment,所以就不能被匯出。解決方法 1插入一條資料 或者再刪除 浪費時間,有時幾百張表會累死的。2建立資料庫之前 使用 sql alter system set deferred segment creation false 調整再建表 這兩種...