之前用 exp 导出,报了 EXP-00011 的错误,对应的表不存在,问了研发这些都是什么表,不导出对业务有没有影响,得知没影响之后就没去处理了。(现在想一想不去处理好像确实不太好,虽然说表没数据,但是要是突然有一天需要用到这张表,查不到就惨了)今天偶然看到一篇文章有讲到这个问题,随记录下来。
关键知识点:deferred_segment_creation 参数
Oracle 11g 新增一个参数 deferred_segment_creation,它的含义是段延迟创建。默认情况下,这个值是 true,也就是说,当你新建一张表后没有往里插入数据,这个表不会立即分配 extent。
解决方法
方法一 修改deferred_segment_creation参数
修改 deferred_segment_creation 参数,配置之后,只对新创建的表会分配 segment。对之前已经建立的空表是不起作用的。通常情况下,还需要重启数据库,让参数真正生效。
#修改参数
alter system set deferred_segment_creation=FALSE;
#查看参数是否生效
SELECT name, TYPE, VALUE, isses_modifiable, issys_modifiable FROM v$parameter WHERE name LIKE 'defer%';
方法二 在创建表时指定段创建方式
如果你不想修改系统参数,也可以在创建表的时候直接指定是否创建段。
create table test(id number(10)) SEGMENT CREATION IMMEDIATE;
方法三 手动为表分配表
如果你已经创建了空表,并且希望为它们分配段,也可以使用以下方法。
BEGIN
DBMS_SPACE_ADMIN.materialize_deferred_segments (
schema_name => 'SCOTT',
table_name => 'TEST'
);
END;
或者
ALTER TABLE TableName ALLOCATE EXTENT;
#分区表
ALTER TABLE TableName modify partition partition_name ALLOCATE EXTENT;
方法四 手动插入数据
人工插入数据之后删除,嘻嘻,有点费人就是了。
方法五 构建对空表分配空间的 sql 命令
如果你想批量为当前用户下的所有空表分配空间,可以按照以下步骤操作:
首先,查询当前用户下的所有空表:
SELECT table_name
FROM user_tables
WHERE NUM_ROWS = 0;
然后,构建针对空表分配空间的命令语句:
set echo off feed off pages 0
spool temp.sql
SELECT'alter table ' || table_name || ' allocate extent;'
FROM user_tables
WHERE num_rows = 0AND partitioned = 'NO';
SELECT'alter table '
|| table_name
|| ' modify partition '
|| partition_name
|| ' allocate extent;'
FROM USER_TAB_PARTITIONS
WHERE num_rows = 0;
spool off
set echo on feed on
@ temp.sql
评论