【问题标题】:Oracle column order (dynamically?)Oracle 列顺序(动态?)
【发布时间】:2016-02-01 23:23:57
【问题描述】:

我有一个程序,在某些时候会复制从tableA + 一些字段到tableB 的行,如下所示:

INSERT INTO tableB
SELECT a.*, 'field1', 'field2'
FROM tableA a
WHERE a.id = myId

当我不得不向tableA 添加一个新列时,问题就来了。如果我将该列添加到tableA,它将作为最后一列添加,使此过程无效导致列数不匹配。为了使这个脚本有意义,我应该将新列从tableA 添加到tableB。我可以手动编写所有的列,但是有很多列,我正在寻找更易于维护的东西

有没有办法将新列添加到tableB 的特定位置?如果不可能,有没有办法从tableA 中选择除新列之外的每一列(所以我可以选择它作为tableB 的最后一列)?如果没有,我该如何自动化列顺序选择/插入?

谢谢

【问题讨论】:

  • 请添加带有此问题的表格脚本。
  • 据我所知,SQL 中没有任何方法可以让您选择除指定列之外的每一列。考虑使用事件触发器在tableB 中自动创建一个列。如果您希望手动完成维护工作,请生成一次tableA 列列表并将它们放入您的过程处理中,当对tableA 的结构进行一些更改时,将新列添加到tableB
  • @Md.ShamimAlMamun 对不起,这是工作代码,我无法添加表定义。表格脚本的某些特定部分有用吗?
  • 键入列是可维护的。你只需要做一次,对吧?

标签: sql oracle


【解决方案1】:

这是select * 在除临时查询(有时是子查询和数据透视表)之外的任何事情中通常被认为是一个坏主意的原因之一。如果表结构发生变化,你会有点卡住。

You cannot select all but some columns。您也不能将新列添加到特定位置的表中。您可以recreate the table 但这会使引用它的任何内容无效,并且可能太慢或使用太多存储空间。如果您的桌子合适,您可以使用the DBMS_REDEFINITION package 来减少痛苦和明显。但您可能不想在每次结构更改时都这样做。

我不推荐的另一个选项是使用在运行时从user_tab_columns 生成的列名插入动态 SQL 语句。但这有其自身的问题,尤其是在运行时之前您也无法验证插入语句,并且您仍然必须弄清楚两个表中的列如何对齐。

明智的做法是一次性在代码中爆炸*。您不必手动输入所有列名; you can generate them from a query against user_tab_columns 并剪切并粘贴到您的程序中。然后,维护包括记住将未来的新列添加到查询中(如果需要)。您可能会部分编写脚本 - 例如您可以生成一个填充历史表的触发器,但可能不适合在过程中间。


正如 Justin Cave 指出的那样,Oracle 12c introduced invisible columns 可以帮助您,但请注意,Tom Kytes 的文章将此描述为“应用程序代码(等待修复!)”的解决方法,因此您仍然应该修复* 无论如何都要正确引用 - 这只是给你空间来解决它。

【讨论】:

  • 嗯,这就是我害怕的。但是user_tab_columns 将使任务更容易一些。非常感谢
  • 既然您已经给出了一个很好的选项纲要,您可能希望包含 12.1 使列不可见然后再次可见的技巧以重新排列表中的列oracle.com/technetwork/issue-archive/2014/14-may/…
  • @JustinCave - 谢谢;我不确定我能否做到这一点(可耻的是,我还没有使用 12c,而且我还没有看到之前提到的那种变化)。但我想如果该链接还不够,我会赞成一个解释它的答案。 (我喜欢提到“编码不良的应用程序”!)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 2021-10-27
  • 2013-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多