我有一个特定的场景,我必须在Oracle的现有表中插入两个新列。我无法放弃并重新创建表格。那么它可以通过任何方式实现吗?
答案 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):
alter table TAB1 add (NEW_COL number);
create table tempTAB1 as select NEW_COL as COL0, COL1, COL2, COL3 from TAB1;
drop table TAB1;
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包。