重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
你好:如何在oracle 11g 中导出空表
坚守“ 做人真诚 · 做事靠谱 · 口碑至上 · 高效敬业 ”的价值观,专业网站建设服务10余年为成都主动防护网小微创业公司专业提供成都定制网页设计营销网站建设商城网站建设手机网站建设小程序网站建设网站改版,从内容策划、视觉设计、底层架构、网页布局、功能开发迭代于一体的高端网站建设服务。
由于oracle 11g的 延迟段创建的新特性,导致在没有数据插入时,oracle是不会分配数据段的,进而导致exp 是不能导出11g数据库的空表的。
当然采用expdp就不存在这个问题了。
expdp hr/hr schemas=hr dumpfile=expdp.dmp directory=dbtest
conn hr/hr
select TABLE_NAME,NUM_ROWS from user_tables;
TABLE_NAME NUM_ROWS
------------------------------ ----------
LOCATIONS 23
EMP_1 0
PART_TIME_EMPLOYEES 0
TEST3 5
TEST1 5
TEST 5
PC_WELL_TEST 2
PC_ALARM_SORT_TEST 1
MVIEW_PC_WELL_TEST 2
MV_CAPABILITIES_TABLE 14
T 0
TEST2
SYS_EXPORT_SCHEMA_01
SYS_EXPORT_SCHEMA_02
HOURLY_EMPLOYEES 0
COUNTRIES 25
ADMIN_EXT_EMPLOYEES
ADMIN_WORK_AREA
EMPLOYEES 107
DEPARTMENTS 27
DIGITS 2
REGIONS 4
JOB_HISTORY 10
JOBS 19
24 rows selected.
为什么这里的num_rows为空呢?
那是因为表刚建立,数据字典中还没有这个表相关的统计信息呢。
SQL select 'alter table '||table_name||' allocate extent;' from user_tables where
num_rows=0
'ALTERTABLE'||TABLE_NAME||'ALLOCATEEXTENT;'
-----------------------------------------------------------
alter table PART_TIME_EMPLOYEES allocate extent;
alter table EMP_1 allocate extent;
alter table T allocate extent;
alter table HOURLY_EMPLOYEES allocate extent;
所以对于网上一些在oracle11g上先使用手工分配extent 再使用exp来导数据库,在实际上效果不怎么地,反而是多次一举直接使用expdp来导oracle 11g数据库中空表来的方便多了。
当然对那些要从11g导低版本,还是可以的采用这个办法,但是要注意,要么对所有相关的表进行分析系,然后使用上述那个批量脚本。或者不分析表,直接手工用ue编辑分配extent的命令。
SQL select TABLE_NAME,NUM_ROWS from user_tables where NUM_ROWS=0;
TABLE_NAME NUM_ROWS
------------------------------ ----------
PART_TIME_EMPLOYEES 0
EMP_1 0
T 0
HOURLY_EMPLOYEES 0
补充信息:
USER_TABLES describes the relational tables owned by the current user. Its columns (except
for OWNER) are the same as those in ALL_TABLES. To gather statistics for this view, use the
DBMS_STATS package.
收集表的统计信息:
analyze table xxx compute statistics;
or
exec dbma_stats.gather_table_stats('USER', 'TABLE');
MSSQL不知道
oracle在plsql里执行如下代码:
DECLARE
v_table tabs.table_name%TYPE;
v_sql VARCHAR2(888);
v_q NUMBER;
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);
END IF;
END LOOP;
CLOSE c2;
END LOOP;
EXCEPTION
WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error occurred');
END;
然后点output,显示的就是空表
之所以不能导出空表,是因为Oracle默认不会为空表分配segment,应对方法有三个
1、把deferred_segment_creation这个参数设置为false,这样新创建任何表都会自动分配segment,这样用逻辑导出就可以导出空表了,但是注意,在更改这个设置之前的空表还是不会分配segment的
2、可以在创建表的时候就手动分配segment
sqlcreate table TEST (XXX xxx,YYY yyy) segment creation immediate;
3、对于已经存在的空表,可以
sqlalter table TEST allocate extent;
希望能帮到题主!