在Oracle中重新排序表的列

时间:2011-02-08 23:32:32

标签: sql oracle rename

我有一个包含50多列的表,我需要交换前两列的顺序。使用Oracle实现此目的的最佳方法是什么?假设表名是ORDERDETAILS,实际上,前两列是ITEM_ID和ORDER_ID。重命名完成后,表名仍应为ORDERDETAILS,但前两列将为ORDER_ID和ITEM_ID。 FWIW,列类型和其余列及其顺序是irelevent。

如果我错了,请纠正我,但我认为一般步骤是:

  1. 重命名现有表格。
  2. 删除主键约束。
  3. 使用正确的列顺序重新创建表。
  4. 列表项
  5. 运行INSERT INTO .. SELECT以在步骤#3中将数据从temp移动到表。
  6. 删除临时表。
  7. 我对Oracle的经验很少,所以也许我错过了一两步。

    主键是否意味着Oracle中的索引?删除主键是否也会丢弃索引?

    非常感谢SQL示例。

    编辑:非诚挚地感谢那些质疑为什么需要而不是提供帮助的人。要回答你为什么需要这样做的问题:我遵循其他人的命令,他说我需要这样做,而且列的顺序很重要。我对此的想法/意见是无关紧要的。

5 个答案:

答案 0 :(得分:49)

自Oracle 12c发布以来,现在可以更轻松地重新排列列。

Oracle 12c增加了对列不可见的支持,并且该功能可用于逻辑重新排列列。

来自documentation on invisible columns

的引用
  

当您看到一个不可见的列时,该列将作为最后一列包含在表的列顺序中。

实施例

创建一个表格:

var json = [{
    "date":"04\/30\/15",
    "email":"user@user.com",
    "sent":"<\/i>",
    "notsent":""
},{
    "date":"04\/30\/15",
    "email":"user@leader.com",
    "sent":"<\/i>",
    "notsent":""
},{
    "date":"04\/30\/15",
    "email":"user@admin.com",
    "sent":"<\/i>",
    "notsent":""
}];

$('#table-javascript').bootstrapTable({
    data: json,
    height: 300,
    striped: true,
    pagination: true,
    search: false,
    pageSize: 20,
    pageList: [20, 40, 60, 100, 200],
    minimumCountColumns: 2,
    clickToSelect: true,
});

添加一列:

CREATE TABLE t (
    a INT,
    b INT,
    d INT,
    e INT
);

将列移到中间位置:

ALTER TABLE t ADD (c INT);

ALTER TABLE t MODIFY (d INVISIBLE, e INVISIBLE); ALTER TABLE t MODIFY (d VISIBLE, e VISIBLE);

DESCRIBE t;

积分

我从an article by Tom Kyte on new features in Oracle 12c了解到这一点。

答案 1 :(得分:17)

查看包DBMS_Redefinition。它将使用新的排序重建表。它可以在线完成。

正如菲尔布朗所说,在做这件事之前要仔细考虑。但是,在列中扫描行并在更新时移动数据会产生开销。我使用的列排序规则(没有特定的顺序):

  • 将相关列组合在一起。
  • 在无空列之前的非空列。
  • 首先经常搜索未编入索引的列。
  • 很少填充无效列。
  • 首先是静态列。
  • 稍后可更新的varchar列。
  • 其他可搜索列之后的索引列。

这些规则存在冲突,并未在最新版本中对性能进行全面测试。大多数已经在实践中进行了测试,但我没有记录结果。展示位置选项针对三个相互冲突的目标之一:易于理解的列位置;快速数据检索;更新时的数据移动最少。

答案 2 :(得分:7)

令人遗憾的是甲骨文不允许这样做,我被要求开发人员一直这样做。

这是一种稍微危险,有点快速和肮脏的方法:

  1. 确保您有足够的空间来复制表格
  2. 注意任何约束,助学金,索引,同义词,触发器,嗯..也许还有其他一些东西 - 属于表 - 我还没想过?
  3. CREATE TABLE table_right_columns AS SELECT column1 column3, column2 FROM table_wrong_columns; -- Notice how we correct the position of the columns :)
  4. DROP TABLE table_wrong_columns;
  5. 'ALTER TABLE table_right_columns RENAME TO table_wrong_columns;`
  6. 现在令人讨厌的部分:重新创建上面步骤2中记下的所有项目
  7. 检查现在无效的代码,并重新编译以检查错误
  8. 下次创建表格时,请考虑未来的要求! ;)

答案 3 :(得分:2)

我遵循了乔纳斯(Jonas)的上述解决方案,并且效果很好,直到需要添加第二列为止。我发现,当使列再次可见时,Oracle不一定会按语句中列出的顺序将它们设置为可见。

为证明这一点,请遵循以上乔纳斯的示例。正如他所展示的,一旦步骤完成,表格就会按照您期望的顺序排列。然后,当您添加另一列时,事情就崩溃了,如下所示:

示例(续于乔纳斯(Jonas'))

在C列之前添加另一列。

ALTER TABLE t ADD (b2 INT);

使用上面演示的技术将新添加的B2列移到C列之前。

ALTER TABLE t MODIFY (c INVISIBLE, d INVISIBLE, e INVISIBLE);
ALTER TABLE t MODIFY (c VISIBLE, d VISIBLE, e VISIBLE);

DESCRIBE t;

Name
----
A
B
B2
D
E
C

如上所示,列C已移至末尾。似乎上面的ALTER TABLE语句按D,E,C的顺序而不是按照语句中指定的顺序(也许按物理表顺序)处理列。为了确保将列放置在所需的位置,有必要使列按所需的顺序一目了然。

ALTER TABLE t MODIFY (c INVISIBLE, d INVISIBLE, e INVISIBLE);
ALTER TABLE t MODIFY c VISIBLE;
ALTER TABLE t MODIFY d VISIBLE;
ALTER TABLE t MODIFY e VISIBLE;

DESCRIBE t;

Name
----
A
B
B2
C
D
E

答案 4 :(得分:0)

使用View来改变列的位置: 创建视图CORRECTED_POSITION 如 SELECT co1_1,col_3,col_2 来自UNORDERDED_POSITION 应该有所帮助。

发出此请求以便在使用SELECT * FROM [table_name]的情况下生成一些报告。或者,某些企业采用层次结构方式放置信息,以便从后端获得更好的可读性。

由于 迪利普