在同一个表中复制一行而不必键入50+列名称(同时更改2列)

Tol*_*a E 28 sql oracle

在我的工作期间,我通常必须在更改主键并为其提供新戳并可能更改外键时复制行.

问题是我不想在做的时输入所有列名;

insert into table_name
select pk_seq.nextval, 
       'foreign-key', 
       col3,
       col4...col51
  from table_name
 where pk_id = "original_primary_key"
Run Code Online (Sandbox Code Playgroud)

如果我在select语句中执行*,我将无法更新前2列...

有什么方法可以做我想做的吗?

Ton*_*ews 42

好吧,它可能不会那么冗长,但这个PL/SQL是一个选项:

begin
  for r in (select *
              from table_name
             where pk_id = 'original_primary_key')
  loop
    r.pk := pk_seq.nextval;
    r.fk := 'foreign-key';
    insert into table_name values r;
  end loop;
end;
Run Code Online (Sandbox Code Playgroud)

  • +1很好.注意那些不在Oracle 11g上的人,`r.pk:= pk_seq.nextval;`应该用`select pk_seq.nextval替换为r.pk来自dual;` (7认同)
  • @Adam Musch:游标最多应处理一行,因为`where`子句对主键进行了相等测试.只有一排,批量收集/批量插入不会买任何东西. (2认同)

Sha*_*nce 15

根据Tony的回答:

我们知道,因为我们在主键上搜索,所以最多会返回一行.假设指定了有效的键值,则至少返回一行.所以我们不需要循环:

declare
    r table_name%ROWTYPE;
begin
    select *
    into r
    from table_name
    where pk_id = "original_primary_key";
-- 
    select pk_seq.nextval into r.pk_id from dual;
     -- For 11g can use instead: r.pk_id := pk_seq.nextval;
    r.fk_id := "new_foreign_key";
    insert into table_name values r;
end;
Run Code Online (Sandbox Code Playgroud)