oracle - 从范围分区和压缩表中删除列

标签 oracle oracle11g

我有一个包含数据的表,需要删除一列,该列被标记为未使用。但由于压缩表而出现错误。

我已经使用了命令

ALTER TABLE <table name> MOVE NOCOMPRESS NOLOGGING PARALLEL 4;

但它给出了这个错误:

ORA-14511: cannot perform operation on a partitioned object

如何禁用分区?如何删除未使用的列?

最佳答案

不,您不能使用一个 alter table 语句来移动分区表,您需要按分区将该表重定位到新的段分区中:

创建测试表:

SQL>  create table t1(
  2      col1 number,
  3       col2 number
  4    )
  5    partition by range(col1) (
  6      partition p_1 values less than (10) compress,
  7      partition p_2 values less than (20) compress
  8    );

Table created.

使用一些示例数据填充测试表:

SQL> insert into t1(col1, col2)
  2      select level
  3           , level
  4        from dual
  5     connect by level <= 3;

3 rows created.

SQL> commit;

Commit complete.

SQL> select * from t1;

      COL1       COL2        
---------- ----------      
         1          1      
         2          2    
         3          3  

删除列语句失败:

SQL> alter table t1 drop column col2;
alter table t1 drop column col2
                           *
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tables 

表重定位失败:

SQL> alter table t1 move nocompress;
alter table t1 move nocompress
            *
ERROR at line 1:
ORA-14511: cannot perform operation on a partitioned object 

执行每个分区的重定位:

SQL> alter table t1 move partition p_1 nocompress;

Table altered.

SQL> alter table t1 move partition p_2 nocompress;

Table altered.

当分区过多时,您可以在查询user_tab_partitions数据字典 View 时轻松生成alter table语句。例如:

SQL> column res format a50
SQL> select 'alter table '   || t.table_name ||
  2         ' move partition ' || t.partition_name ||
  3         ' nocompress;' as res
  4    from user_tab_partitions t
  5  where t.table_name = 'T1';

RES                                              
--------------------------------------------------  
alter table T1 move partition P_1 nocompress;   
alter table T1 move partition P_2 nocompress;  

使用 nocompress 选项移动所有分区后,您可以删除列:

alter table t1 drop column col2

声明,或者

alter table t1 drop unused columns 

声明,如果您在重新定位之前已将列标记为未使用。

删除未使用的列:

使 col2 未使用

SQL> alter table t1 set unused(col2);

Table altered.

列出架构中包含未使用列的表

SQL> column table_name format a5
SQL> column table_name format a5
SQL> select *
  2    from user_unused_col_tabs;

TABLE      COUNT  
----- ----------        
T1             1    

重新定位分区

SQL> alter table T1 move partition P_1 nocompress;

Table altered.

SQL> alter table T1 move partition P_2 nocompress;

Table altered.

删除未使用的列:

SQL> alter table t1 drop unused columns;

Table altered.

确保我们放弃了所有我们想放弃的东西。 Col2 消失了:

SQL> desc t1;

Name     Null?    Type
-------- -------- -----------
COL1              NUMBER

没有包含未使用列的表:

SQL> select *
  2    from user_unused_col_tabs;

no rows selected

关于oracle - 从范围分区和压缩表中删除列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20681691/

相关文章:

oracle - 使用具有父类(super class)型属性的类型创建对象表

sql - oracle到db2数据类型:数字精度为星号

java - 如何在 Oracle 中全局(或按 session )限制结果集?

java - Hibernate、id、oracle、序列

oracle - 如何使用 Oracle.ManagedDataAccess.EntityFramework 提供程序从不同架构中选择表?

oracle - Oracle 更改表删除约束删除索引在语法上是否有效?

sql - 需要写子查询来计算每个月的收入

python - 如何在 Linux 服务器中将 Python、Oracle 11g 与 cx_Oracle 连接起来?

oracle - 甲骨文NUMBER hive

java - 数据库行上的锁的范围(简单)