如何在oracle的特定位置插入一列而不删除并重新创建表?

时间:2011-03-22 12:34:41

标签: oracle oracle11g

我有一个特定的场景,我必须在Oracle的现有表中插入两个新列。我无法放弃并重新创建表格。那么它可以通过任何方式实现吗?

4 个答案:

答案 0 :(得分:19)

阿米特 -

我不相信你可以在任何地方添加一个列,但是在创建表之后会在表的末尾添加一个列。一种解决方案可能是试试这个:

CREATE TABLE MY_TEMP_TABLE AS
SELECT *
FROM TABLE_TO_CHANGE;

删除要添加列的表格:

DROP TABLE TABLE_TO_CHANGE;

您可以从头开始重建现有表,添加您希望的列。 我们假设您要在本练习中添加名为“COL2和COL3”的列。

现在将数据插回新表:

INSERT INTO TABLE_TO_CHANGE (COL1, COL2, COL3, COL4) 
SELECT COL1, 'Foo', 'Bar', COL4
FROM MY_TEMP_TABLE;

当数据插入“新旧”表时,您可以删除临时表。

DROP TABLE MY_TEMP_TABLE;

这通常是我想在特定位置添加列时的操作。显然,如果这是一个生产在线系统,那么它可能不实用,但只是一个潜在的想法。

-CJ

答案 1 :(得分:5)

您(仍然)无法使用ALTER TABLE选择列的位置:它只能添加到表的末尾。显然,您可以按任何顺序选择列,因此,除非您使用SELECT * FROM列顺序,否则不应该是一个大问题。

如果您确实必须按特定顺序拥有它们并且无法删除并重新创建表,那么您可以删除并重新创建列: -

首先复制表格

CREATE TABLE my_tab_temp AS SELECT * FROM my_tab;

然后删除要插入的列后想要的列

ALTER TABLE my_tab DROP COLUMN three;

现在添加新列(本例中为两列)和删除的列。

ALTER TABLE my_tab ADD (two NUMBER(2), three NUMBER(10));

最后添加重新创建的列的数据

UPDATE my_tab SET my_tab.three = (SELECT my_tab_temp.three FROM my_tab_temp WHERE my_tab.one = my_tab_temp.one);

显然,您的更新很可能会更复杂,您将不得不处理索引和约束,并且在某些情况下(LOB列等)将无法使用它。此外,这是一个非常可怕的方式 - 但表格将始终存在,您将按照您想要的顺序结束列。但是,列顺序真的很重要吗?

答案 2 :(得分:5)

虽然这有点旧,但我想添加一个稍微改进的版本,它真正改变了列顺序。以下是步骤(假设我们有一个表格TAB1,列COL1,COL2,COL3):

  1. 向表格TAB1添加新列:
  2. alter table TAB1 add (NEW_COL number);
    1. 在更改列顺序时将“复制”表更改为临时名称并重命名新列:
    2. create table tempTAB1 as select NEW_COL as COL0, COL1, COL2, COL3 from TAB1;
      1. 删除现有表格:
      2. drop table TAB1;
        1. 将临时表名重命名为刚删除的表名:
        2. rename tempTAB1 to TAB1;

答案 3 :(得分:0)

在12c中,您可以利用以下事实:从不可见设置为可见的列显示为表的最后一列: Tips and Tricks: Invisible Columns in Oracle Database 12c

也许这是@ jeffrey-kemp在他的评论中所说的“把戏”,但是那里的链接不再起作用。

示例:

ALTER TABLE my_tab ADD (col_3 NUMBER(10));
ALTER TABLE my_tab MODIFY (
  col_1 invisible,
  col_2 invisible
);
ALTER TABLE my_tab MODIFY (
  col_1 visible,
  col_2 visible
);

现在col_3将首先在SELECT * FROM my_tab语句中显示。

注意:这不会更改磁盘上列的物理顺序,但是在大多数情况下,这并不是您要执行的操作。如果您确实要更改实际订单,则可以使用DBMS_REDEFINITION包。