【问题标题】:Copy row and change a small subset of columns?复制行并更改一小部分列?
【发布时间】:2013-04-10 08:07:15
【问题描述】:

首先,让我先说我知道类似问题的 INSERT/SELECT 解决方案(请参阅here),但它不适用于我的场景。

我正在寻找一种不需要明确列出所有列的解决方案,因为这些列是提前未知的。此查询将在数十个独立数据库中的同一张表上运行。所有数据库都有一个公共列的子集,但每个都有自己独特的列,特定于该数据库。

那么,有没有一种方法可以复制整行,更改某些已知/恒定的列子集,然后在不明确列出所有列的情况下重新插入它?唯一的解决方案是使用从架构中收集的 DDL 信息动态构建查询吗?

【问题讨论】:

  • 是的,唯一的方法是使用动态 sql。但是,如果它在您的控制范围内,我强烈建议您查看您的数据模型。听起来您的父子关系应该是非枢轴的。
  • 我有点困惑。您何时知道需要更新哪些列?我同意@Dan 的观点,这将需要动态 SQL,我更同意数据模型听起来不是最理想的。
  • 数据模型不是最优的,不在我的控制之下。我确实知道需要更新哪些列(它是一组 5 个左右的列,对表的所有实例都是通用的)。

标签: sql oracle


【解决方案1】:

注意:此答案适用于 SQL Server。 标签被添加到这个答案之后的问题中

根据良好设计的原则,我将假设您的表有一个 IDENTITY 列,该列也是主键。我们还假设它没有有计算列(或时间戳或任何需要更多操作的类型)。最后让我们假设您至少知道这个 ID 列的名称,这是标准的,例如“id”。

你可以使用这个序列:

SELECT * INTO #tmp FROM tbl WHERE id = @copyfrom;
ALTER TABLE #tmp DROP COLUMN id;
UPDATE #tmp SET
   column1 = ...,
   column2 = ...,
   column3 = ...;  --- the subset of columns you want to change
INSERT tbl SELECT * FROM #tmp;

SQL Fiddle Demo

【讨论】:

  • 已经测试过这种方法,我认为Oracle不允许最后一条语句。我得到 ORA-00947:没有足够的值
  • 答案写满了 TSQL。对于 Oracle,我认为您需要保留所有列(因此没有 drop column 业务),但您还必须更新 PK 列,以免导致 PK 违规
  • 需要清空 id,而不是丢弃它。删除它然后插入尝试插入 tablevalues-1。 (假设 oracle 的工作方式与将显式 null 转换为新身份的其他平台相同)
【解决方案2】:

我认为你可以结合使用create table as(或select into)和更新来做你想做的事。

所以,创建一个表的副本:

create table newTable as
    select *
    from oldTable

或者,取决于您的数据库:

select *
into newTable
from oldTable

然后使用更新进行更改:

update newTable
    set col2 = col1,
        code = (case when code = 'bad' then good else code end)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-22
    • 2013-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多