在Oracle中,是否可以将列“插入”表中?

时间:2009-02-23 19:21:55

标签: database oracle

将列添加到现有表时,Oracle始终将列放在表的末尾。是否有可能告诉Oracle它应该出现在表中的哪个位置?如果是这样,怎么样?

9 个答案:

答案 0 :(得分:8)

表中列的位置应该不重要(除非要考虑“页面大小”,或Oracle用于实际存储数据的任何内容)。对消费者更重要的是如何调用结果,即Select语句。

答案 1 :(得分:6)

将YOUR_ORIGINAL_TABLE重命名为YOUR_NEW_TABLE;

创建表YOUR_ORIGINAL_TABLE nologging / *或不可恢复* / 如 选择Column1,Column2,NEW_COLUMN,Column3   来自YOUR_NEW_TABLE;

删除表YOUR_NEW_TABLE;

从YOUR_ORIGINAL_TABLE中选择*; <<<<<现在,您将在表格中间看到新列。

但你为什么要这样做呢?这似乎是不合逻辑的。如果列顺序很重要,您永远不应该假设列排序,只使用命名列列表。

答案 2 :(得分:3)

为什么列的顺序很重要?您可以随时在select语句中更改它吗?

在表的末尾添加新列是有利的。如果有代码天真地执行“SELECT *”然后按顺序解析字段,则不会通过在末尾添加新列来破坏旧代码。如果在表格中间添加新列,则可能会破坏旧代码。

在一份工作中,我有一位DBA,他是超级肛门的“从不做'SELECT *'”。他坚持要你总是写出具体的领域。

答案 3 :(得分:2)

我通常做的是:

  1. 重命名旧表。
  2. 按正确的顺序创建包含列的新表。
  3. 为该新表创建约束。
  4. 使用数据填充:从重命名的表中插入new_table select *。

答案 4 :(得分:2)

我不认为可以在不将数据保存到临时表,删除表并重新创建表的情况下完成此操作。另一方面,列的位置确实无关紧要。只要您在select语句中指定要检索的列,就可以根据需要对它们进行排序。

答案 5 :(得分:2)

请记住,在表格下,表格记录中的所有数据都粘在一起。将列添加到表的末尾[如果它是可空的或(在以后的版本中)不是默认的null]只是意味着更改表的元数据。 在中间添加列需要重写该表中的每个记录,以便为该列添加适当的值(或标记)。在某些情况下,这可能意味着记录在块上占用更多空间,并且需要迁移一些记录。 简而言之,对于任何实际大小的表来说,这是一个非常大的IO工作量。

您始终可以在表格中创建一个视图,该视图包含首选顺序的列,并在DML语句中使用该视图,就像使用表格一样

答案 6 :(得分:1)

我不相信 - SQL Server也不允许这样做。我经常使用的方法是:

  1. 创建看起来正确的新表(包括其他列
  2. 开始交易
  3. 从旧表中选择所有数据到新表
  4. 放弃旧桌子
  5. 重命名新表
  6. 提交交易。
  7. 不完全漂亮,但完成工作。

答案 7 :(得分:0)

不,通过“ALTER TABLE”语句无法实现。但是,您可以创建一个与当前定义具有相同定义的新表,尽管名称不同,但列的顺序与您希望的顺序相同。将数据复制到新表中。放下旧桌子。重命名新表以匹配旧表名。

Tom Kyte在AskTom上有一篇关于此的文章 link text

答案 8 :(得分:-1)

1)好的,所以你不能直接这样做。我们不需要在帖子后发帖说同样的事情,是吗?

2)好的,所以表中列的顺序在技术上并不重要。但这不是重点,原始问题只是问你是否可以完成。不要以为你知道其他人的要求。也许他们有一个包含100列的表,目前正在使用“SELECT * ...”查询一些怪异的黑客攻击查询,他们只是不想尝试解开,更不用说用100列名称替换“*”了。或者也许他们只是对事物的顺序肛门,并且喜欢在浏览模式时将相关字段彼此相邻,比如说SQL Developer。也许他们正在处理非技术人员,他们不知道在100列的列表的末尾看,从逻辑上讲,它应该在接近开头的某个地方。

没有什么比问一个诚实的问题并得到一个答案说:“你不应该这样做”更令人恼火。这是我的工作,而不是你的工作!请不要告诉我如何完成我的工作。如果可以,请提供帮助。谢谢!

好的...抱歉咆哮。现在......在www.orafaq.com上,它建议了这种解决方法。

首先假设您已经运行:

CREATE TABLE tab1(col1 NUMBER);

现在说你要添加一个名为“col2”的列,但是你想要它们在执行“SELECT * FROM tbl1;”

时命令“col2”,“col1”

建议运行:

ALTER TABLE tab1 ADD(col2 DATE); RENAME tab1 TO tab1_old; CREATE TABLE tab1 AS SELECT 0 AS col1,col1 AS col2 FROM tab1_old;

我发现这令人难以置信的误导。首先,你用零填充“col1”所以,如果你有任何数据,那么你就是这样做了。其次,它实际上将“col1”重命名为“col2”并且没有提到这一点。所以,这是我的例子,希望它更清楚一点:

假设您有一个使用以下语句创建的表:

CREATE TABLE用户(first_name varchar(25),last_name varchar(25));

现在假设您要在first_name和last_name之间插入middle_name。这是一种方式:

ALTER TABLE用户ADD middle_name varchar(25); RENAME用户TO users_tmp; CREATE TABLE用户AS SELECT first_name,middle_name,last_name FROM users_tmp; / *和好的措施...... * / DROP TABLE testusers_tmp;

请注意,middle_name将默认为NULL(由ALTER TABLE语句隐含)。您也可以在CREATE TABLE语句中设置不同的默认值,如下所示:

CREATE TABLE用户AS SELECT first_name,'some default value'AS middle_name,last_name FROM users_tmp;

如果您要添加一个默认值为sysdate的日期字段,但是您希望所有现有记录都具有其他一些(例如更早的)日期值,则此技巧可以派上用场。