我有一个程序,在某些时候会将tableA
+某些字段的行副本复制到tableB
,如下所示:
INSERT INTO tableB
SELECT a.*, 'field1', 'field2'
FROM tableA a
WHERE a.id = myId
当我不得不向tableA
添加新列时出现问题。如果我将该列添加到tableA
,则将其添加为最后一列,使此过程无效会导致列数不匹配。为了使这个脚本有意义,我应该将tableA
的新列添加到tableB
。我可以手工编写所有列,但是有很多列,我正在寻找更易于维护的内容
有没有办法在特定位置将新列添加到tableB
?如果它不可行,有没有办法从tableA
中选择除新的列之外的所有列(所以我可以选择它作为tableB
的最后一列)?如果没有,我如何自动化列顺序选择/插入?
由于
答案 0 :(得分:4)
除了即席查询(有时是子查询和支点)之外,select *
通常被认为是一个坏主意的原因之一。如果表结构发生变化,你就会陷入困境。
You cannot select all but some columns。您也无法将新列添加到特定位置的表中。您可以recreate the table但是这会使引用它的任何内容无效,并且可能太慢或使用太多存储空间。如果您的餐桌适合,您可以使用the DBMS_REDEFINITION
package来减轻痛苦和可见度。但是,每当结构发生变化时,您可能不希望这样做。
我不推荐的另一个选项是使插入成为动态SQL语句,其中包含在运行时从user_tab_columns
生成的列名。但是这有它自己的问题,尤其是你不能在运行时之前验证insert语句,你仍然需要弄清楚两个表中的列是如何对齐的。
明智的做法是在代码中一次性爆炸*
。您不必手动键入所有列名称; you can generate them from a query against user_tab_columns
并剪切并粘贴到您的程序中。然后,维护包括记住在查询中添加未来的新列(如果需要)。您可以部分编写脚本 - 例如您可以生成一个填充历史表的触发器,但可能不适合在过程中使用。
Justin Cave指出,Oracle 12c introduced invisible columns可以帮助你,但请注意Tom Kytes的文章将其描述为“应用程序代码(等待修复!)”的解决方法,所以你仍然应该无论如何都要正确地修复*
引用 - 这只是给你空间来解决它。