需要先将空表找出来,执行如下语句,再exp就ok;
不过需要重新分析统计信息再执行下面语句就ok,因为(列NUM_ROWS),这个列行数并不是准确的行数;
执行:select 'analyze table '||table_name||' compute statistics;' from user_tables;
然后复制到sql窗口,执行语句;
再选择num_rows=0的表,如下:
select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0;然后复制这些语句到新的sql窗口,执行,再将表的内容选中复制到txt库里,或直接复制到sql编辑器里,执行sql语句。
再exp导出来,就可以导出空表了;
还有另外一个野蛮方法:将全用户表都分配一遍空间,以免漏掉表;再导出;
或者写存储过程将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;
oracle 11g 新增了一个参数:deferred_segment_creation,含义是段延迟创建,默认是true。
如果这个参数设置为true,你新建了一个表T1,并且没有向其中插入数据,那么这个表不会立即分配extent,也就是不占数据空间,只有当你insert数据后才分配空间。这样可以节省少量的空间。
可用此修改:alter system set deferred_segment_creation=false;
在命令窗口中,用此查看:SQL>show parameter deferred_segment_creation
重启服务后,再新建的表就不存在此问题了。