【问题标题】:Copying a row in the same table without having to type the 50+ column names (while changing 2 columns)在同一个表中复制一行而无需键入 50 多个列名(同时更改 2 列)
【发布时间】:2010-09-23 16:15:27
【问题描述】:

在我的工作中,我通常必须在更改行的主键并给它们一个新标记并可能更改外键的同时复制行。

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

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

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

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

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    好吧,它可能不会那么冗长,但是这个 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 不错。未使用 Oracle 11g 的人请注意,r.pk := pk_seq.nextval; 行应替换为 select pk_seq.nextval into r.pk from dual;
    • BULK COLLECT / BULK INSERT 游标可能会更好。 10g+ 中的 PL/SQL 隐式地对隐式游标进行批量处理,但您仍然在每次插入时执行 PL/SQL -> SQL -> PL/SQL 上下文切换。
    • @Adam Musch:游标最多只能处理一行,因为where 子句对主键进行了相等性测试。只有一行,批量收集/批量插入不会购买任何东西。
    • 我完全没有注意到“and pk = 'primary key value'”;我脑子里有任意/一般情况。
    • @schnatterer 我回滚了您的编辑 - 我不明白为什么我的答案代码必须采用您喜欢的样式!?
    【解决方案2】:

    基于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;
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        您可以只查询数据字典来为您生成 SQL。

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

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

        【讨论】:

          【解决方案5】:

          您可以创建一个“临时”表,更新两列并从此“临时”表中进行插入选择。

          示例:

          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;
          

          【讨论】:

          • 这种方法对大数据集很有帮助。内存消耗并不显着。
          【解决方案6】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-10-31
            • 1970-01-01
            • 1970-01-01
            • 2015-02-18
            • 2021-12-16
            • 1970-01-01
            • 2015-09-20
            相关资源
            最近更新 更多