【问题标题】:Insert a table inside another with one field different将一个表插入另一个表,其中一个字段不同
【发布时间】:2015-03-09 01:24:16
【问题描述】:

我正在尝试在 oracle 中将一个表复制到另一个表,以更改其中一个字段的值。

假设 Tables Original 和 Temp,所以我通常会使用下面的 SQL:

Insert into Original Select * from Temp where site = 1

问题是现在我的原始表已经有站点 1,所以我需要将站点 1 的内容复制到原始表,将站点 1 更改为站点 2。我通常会这样做

Insert into Original (site, field1, field2, field3) Select '2', field1, field2, field3 from Temp where site = 1

但是,我有几百个表可以做到这一点,我正在寻找一种解决方案,我不需要在每个语句中输入字段的名称。

有什么想法吗?

【问题讨论】:

  • 我想你想要merge 声明。
  • @GordonLinoff - 这将如何消除指定字段名称的需要?

标签: sql oracle insert


【解决方案1】:

我写了简单的PLSQL程序,代码如下。它生成插入字符串以输出, 如果这些适合您,您可以复制/粘贴它们并手动运行,或者您可以取消注释 行接近结束和插入将自动完成。对样本数据进行了测试,效果很好。

过程对user_tab_columns 中的列进行操作。首先,您必须在声明部分定义您感兴趣的表列表。 您可能想根据需要更改一些代码。

生成的输出:

insert into original (site, F1, F2, F3) select 1, F1, F2, F3 
  from TEMP1 where site = 1
insert into original (site, F2, F1, F3) select 2, F2, F1, F3 
  from TEMP2 where site = 1
insert into original (site, F3, F2, F1) select 3, F3, F2, F1 
  from TEMP3 where site = 1

程序代码:

create or replace procedure justdoit is
  type t_var is table of varchar2(30);
  -- table names in uppercase
  tabs t_var := t_var('TEMP1', 'TEMP2', 'TEMP3'); 
  v_sql1 varchar2(4000);
  v_sql2 varchar2(4000);
begin

for i in 1..tabs.count
loop
  v_sql1 := 'insert into original (site, ';
  v_sql2 :=  'select '||i||', ';
  for o in (
    select * from user_tab_columns 
      where table_name = tabs(i)
      order by column_id)
  loop
    if o.column_name <> 'SITE' then
      v_sql1 := v_sql1 || o.column_name||', ';
      v_sql2 := v_sql2 || o.column_name||', ';
    end if;
  end loop;
  v_sql1 := rtrim(v_sql1, ', ')||') '||rtrim(v_sql2, ', ');
  v_sql1 := v_sql1||' from '||tabs(i)||' where site = 1';
  dbms_output.put_line(v_sql1);
  -- execute immediate v_sql1;  -- <- uncomment this line
end loop;

end justdoit;

【讨论】:

    【解决方案2】:

    你可以试试下面的查询

    INSERT INTO Original select '2' from Temp union all select * from Temp where site=1;
    

    解释:

    I) 值 '2' 将插入名为“site”的第一列

    II)临时表中的字段1、字段2、字段3将插入到原表的字段1、字段2、字段3中

    【讨论】:

    • 是的,我知道这项工作(我什至在描述中添加了),但我试图不使用字段名称,因为我必须对具有许多字段的许多不同表重复此操作。还是谢谢。
    • 您是否期望在子查询中也不应提及字段名称的查询? @IcaroNZ
    • 我希望上面编辑的答案能满足你的要求..看看@lcaroNZ
    • 正如我现在想象的那样,我每边的字段数不匹配原始表包含所有字段,选择状态包含所有字段加上“静态”字段。
    【解决方案3】:

    您可以编写一个create table as select (ctas) 查询,使用您想要的站点列的新值,但指定一个临时列名。然后在创建表后,删除“坏”站点列,并将临时站点重命名为站点(每个表涉及 3 个语句),如下所示:

    create table original as
    select '2' as new_site, t.* from temp t where site = 1;
    
    alter table original drop column site;
    
    alter table original rename column new_site to site;
    

    请注意,如果您目前只截断了这些“原始”表,请在从临时表中运行 CTAS 查询之前删除它们。

    【讨论】:

    • 是的,我也告诉过它,但正如我所描述的,我必须对很多很多表执行此操作,我希望能够更轻松、更快速地进行操作。无论如何感谢您的帮助。
    • 这不涉及指定列名,这就是您所描述的。使用表格列表,您可以在 excel 公式中生成这 3 条语句,然后将其轻松向下拖动。
    【解决方案4】:

    使用另一个临时表

    插入到 temp2 从 temp1 中选择 * 站点=1; 更新 temp2 设置站点 = 2 其中站点=1;

    插入主表 select * from temp2 where site=2;

    从站点=2的temp2中删除;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-21
      相关资源
      最近更新 更多