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

时间:2010-09-23 16:15:27

标签: sql oracle

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

问题是我不想在执行时键入所有列名称;

insert into table_name
select pk_seq.nextval, 
       'foreign-key', 
       col3,
       col4...col51
  from table_name
 where pk_id = "original_primary_key"

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

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

6 个答案:

答案 0 :(得分: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;

答案 1 :(得分:15)

基于Tony's answer

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

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;

答案 2 :(得分:3)

您只需查询数据字典即可为您生成SQL。

SELECT 'tbl.' || column_name || ','
FROM   user_tab_columns
WHERE  table_name = 'MYTABLE'
ORDER BY column_id;

获取此查询的结果,粘贴到您的SQL语句中,根据需要进行调整,然后瞧。

答案 3 :(得分:2)

对不起 - 这是一个全有或全无的事情 SELECT *之间没有任何内容,并列出特定列,它是一个或另一个。

答案 4 :(得分:1)

您可以创建'temp'表,更新两列并从此'temp'表中执行insert-select。

Eaxmple:

create table temptemp as 
select *
  from table_name
 where pk_id = "original_primary_key"

update temptemp
set col1 = ...
,   col2 =....

insert into table2
select * from temptemp;

答案 5 :(得分:0)

您可以创建一个采用表名的简单存储过程,并使用数据字典为您写入select语句文本(select的文本)。然后复制,粘贴和修改。