代码之家  ›  专栏  ›  技术社区  ›  nearly_lunchtime

如何复制记录,仅更改id?

  •  6
  • nearly_lunchtime  · 技术社区  · 17 年前

    我的表有很多列。我有一个复制某些数据的命令——可以将其视为克隆产品——但由于列将来可能会更改,我只想从表中选择所有内容,只更改一列的值,而不必参考其余列。

    例如,代替:

    INSERT INTO MYTABLE (
    SELECT NEW_ID, COLUMN_1, COLUMN_2, COLUMN_3, etc
    FROM MYTABLE)
    

    我想要类似的东西

    INSERT INTO MYTABLE (
    SELECT * {update this, set ID = NEW_ID}
    FROM MYTABLE)
    

    有没有一个简单的方法可以做到这一点?

    这是一个iSeries上的DB2数据库,但欢迎回答任何平台的问题。

    5 回复  |  直到 17 年前
        1
  •  10
  •   Tony Andrews    17 年前

    您可以这样做:

    create table mytable_copy as select * from mytable;
    update mytable_copy set id=new_id;
    insert into mytable select * from mytable_copy;
    drop table mytable_copy;
    
        2
  •  3
  •   Kristoffon    17 年前

    我认为,如果不去麻烦地创建一个临时表,那么在SQL中完全可以做到这一点。在内存中执行应该快得多。如果使用临时表路由,则必须为每个函数调用选择一个唯一的表名,以避免代码同时运行两次并将两行数据合并到一个临时表中的争用情况。

    我不知道您使用的是哪种语言,但应该可以在程序中获得字段列表。我会这样做:

    array_of_field_names = conn->get_field__list;
    array_of_row_values = conn->execute ("SELECT... ");
    array_of_row_values ["ID"] = new_id_value
    insert_query_string = "construct insert query string from list of field names and values";
    conn->execute (insert_query_string);
    

    然后您可以将其封装为一个函数,只需调用它指定表、旧id和新id,它就会发挥神奇的作用。

    在Perl代码中,可以使用以下代码段:

    $table_name = "MYTABLE";
    $field_name = "ID";
    $existing_field_value = "100";
    $new_field_value = "101";
    
    my $q = $dbh->prepare ("SELECT * FROM $table_name WHERE $field_name=?");
    $q->execute ($existing_field_value);
    my $rowdata = $q->fetchrow_hashref; # includes field names
    $rowdata->{$field_name} = $new_field_value;
    
    my $insq = $dbh->prepare ("INSERT INTO $table_name (" . join (", ", keys %$rowdata) . 
        ") VALUES (" . join (", ", map { "?" } keys %$rowdata) . ");";
    $insq->execute (values %$rowdata);
    

        3
  •  2
  •   Rob Farley    17 年前

    好的,试试这个:

    declare @othercols nvarchar(max);
    declare @qry nvarchar(max);
    
    select @othercols = (
    select ', ' + quotename(name)
    from sys.columns
    where object_id = object_id('tableA')
    and name <> 'Field3'
    and is_identity = 0
    for xml path(''));
    
    select @qry = 'insert mynewtable (changingcol' + @othercols + ') select newval' + @othercols;
    
    exec sp_executesql @qry;
    

    在运行“sp_executesql”行之前,请执行“select@qry”以查看要运行的命令。

    抢劫

        4
  •  1
  •   berlindev    17 年前

    你的例子应该很有用。

    
    INSERT INTO MYTABLE
    (id, col1, col2)
    SELECT new_id,col1, col2
    FROM TABLE2
    WHERE ...;
    
        5
  •  -1
  •   nWorx    17 年前

    我从未使用过db2,但在mssql中,您可以通过以下过程来解决它。此解决方案仅在您不关心项目获得的新id时有效。

    1.)创建具有相同方案但id列自动递增的新表。(mssql“标识规格=1,标识增量=1)

    insert into newTable(col1, col2, col3)
    select (col1, col2, col3) from oldatable
    

    应该足够了,请确保不要在上述声明中包含您的id列