【问题标题】:Oracle SQL merge tables without specifying columnsOracle SQL 合并表而不指定列
【发布时间】:2015-11-04 17:09:06
【问题描述】:

我有一个表 people 的记录少于 100,000 条,我已使用以下方法对该表进行了备份:

create table people_backup as select * from people 

随着时间的推移,我将一些新记录添加到我的people 表中,但最终我想将备份表中的记录合并到people。不幸的是,我不能简单地DROP 我的桌子,因为我的新记录会丢失!

所以我想根据主键id 使用来自people_backup 的记录来更新我的people 表中的记录,我找到了两种方法来做到这一点:

  1. MERGE桌子在一起
  2. 使用某种fancy correlated update

太棒了!但是,这两种方法都使用SET 并让我指定要更新的列。不幸的是我很懒,people 的结构可能会随着时间而改变,而我的CTAS 语句不需要更新,我的更新/合并脚本需要更改,这对我来说感觉像是不必要的工作。

有没有一种方法可以合并整行而不必指定列?我看到hereINSERT 期间不指定列将指示SQL 按顺序插入值,这里可以应用相同的方法吗,这样安全吗?

注意:表的结构在备份之间不会改变

【问题讨论】:

  • 您始终需要指定要更新的列。这就是它的工作原理。但是,您可以编写脚本来编写脚本 - 例如。 select 'set tgt.'||column_name||' = src.'||colunn_name||',' from user_tab_columns where table_name = 'TABLE_NAME'; 至少可以为您生成列列表,因此您可以复制并粘贴到您的语句中
  • 鉴于您的表很小,您可以简单地 delete 备份中存在的表中的任何内容,然后对备份中的所有内容执行 insert 吗?这很慢而且不是特别优雅,但它满足您的要求。
  • 你想用旧数据替换新数据吗?
  • @JustinCave 如果你可以作为答案发帖,我会接受

标签: sql oracle sql-merge


【解决方案1】:

鉴于您的桌子很小,您可以简单地

DELETE FROM table t
 WHERE EXISTS( SELECT 1
                 FROM backup b
                WHERE t.key = b.key );

INSERT INTO table
  SELECT *
    FROM backup;

这很慢而且不是特别优雅(特别是如果备份中的大部分数据没有更改),但假设两个表中的列匹配,它确实允许您不列出列。就个人而言,我更喜欢写出列名(大概这些名称不会经常更改),以便进行更新。

【讨论】:

    猜你喜欢
    • 2013-02-28
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    相关资源
    最近更新 更多