在另一个字段中插入一个 table,其中一个字段不同

Insert a table inside another with one field different

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

让我们说 Tables Original 和 Temp,所以我通常会在下面使用这个 SQL:

Insert into Original Select * from Temp where site = 1

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

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

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

有什么想法吗?

您可以使用您想要的网站栏新值编写一个 create table as select (ctas) 查询,但指定一个临时栏名。然后在 table 创建后,删除 'bad' 网站栏,并将临时栏重命名为网站(每个 table 涉及 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;

请注意,如果您目前只截断了这些 'original' tables,请将它们放在 运行 CTAS 查询之前 tables。

您可以试试下面的查询

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

解释:

I) 值“2”将被插入到名为 "site"

的第一列中

II) Temp table 中的列值 field1、field2、field3 将被插入到原始 table 的 field1、field2、field3

我写了简单的PLSQL程序,代码如下。它生成要输出的插入字符串, 如果这些适合你,你可以 copy/paste 它们和手动 运行 或者你可以取消注释 line near end 和 inserts 将自动完成。测试样本数据,工作正常。

过程对 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;

使用另一个温度 table

插入临时文件 2 select * 来自 temp1 其中 站点=1; 更新 temp2 设置站点=2 其中网站=1;

插入主table select * 来自 temp2,其中 site=2;

从 temp2 中删除,其中 site=2;