删除多列:PLSQL和user_tab_cols

时间:2011-08-03 13:14:40

标签: oracle

我有一个表TABLE_X,它有多个以M_字符开头的列需要删除。我决定使用以下PLSQL代码从M_个字符开始删除近100列。它是动态sql和游标的好用吗?可以更好吗?我不知道更简单的方法,因为ALTER TABLE ... DROP COLUMN不允许子查询指定多个列名。

declare
rcur sys_refcursor;
cn user_tab_cols.column_name%type;
begin
open rcur for select column_name from user_tab_cols where table_name='TABLE_X' and column_name LIKE 'M_%';
loop
fetch rcur into cn;
exit when rcur%NOTFOUND;
execute immediate 'alter table TABLE_X drop column '||cn;--works great
execute immediate 'alter table TABLE_X drop column :col'using cn;--error
end loop;
close rcur;
end;

另外。为什么不能使用'使用cn'?

2 个答案:

答案 0 :(得分:2)

在单个alter语句中删除多个列的语法是:

SQL> desc t42
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------
 COL1                                               NUMBER
 COL2                                               DATE
 COL3                                               VARCHAR2(30)
 COL4                                               NUMBER

SQL> alter table t42 drop (col2, col3)
  2  /

Table altered.

SQL> desc t42
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------
 COL1                                               NUMBER
 COL4                                               NUMBER

SQL>

因此,如果您确实需要优化操作,则需要逐步构建语句 - 或者使用字符串聚合技术。

但是,我会怀疑你是否应该经常运行这样的声明需要来优化它。

答案 1 :(得分:2)

这是动态SQL的合理使用。我会认真质疑一个基础数据模型,它在一个表中有数百列,以相同的前缀开头,所有这些都需要删除。这对我来说意味着数据模型本身可能存在很大问题。

即使使用动态SQL,也不能将绑定变量用于列名,表名,模式名等.Oracle需要在分析时知道SQL语句中涉及哪些对象和列。但是,由于绑定变量是在解析阶段之后提供的,因此您无法指定更改SQL语句正在影响的对象和/或列的绑定变量。