2009-10-27 93 views
5

我有一个表,我想复制表中的特定行。我知道这不是做事的最佳方式,但我们正在寻找一个快速解决方案。在MySQL中复制记录

这里比我最初想象的要难,我需要做的是将整个记录复制到MySql中自动增量表中的新记录,而无需指定每个字段。这是因为表格可能会在将来发生变化,并可能会导致重复。我将从PHP复制MySQL记录。

这是一个问题,因为在'SELECT *'查询中,MySql将尝试复制正在复制的记录的ID,从而导致重复的ID错误。

这封锁了: INSERT INTO customer SELECT * FROM customer WHERE customerid=9181。它也封锁INSERT INTO customer (Field1, Field2, ...) SELECT Field1, Field2, ..... FROM customer WHERE customerid=9181.

有没有办法从PHP或MySQL做到这一点?

回答

12

我终于找到了这段代码。我相信它将在未来帮助人们。所以在这里。

function DuplicateMySQLRecord ($table, $id_field, $id) { 
    // load the original record into an array 
    $result = mysql_query("SELECT * FROM {$table} WHERE {$id_field}={$id}"); 
    $original_record = mysql_fetch_assoc($result); 

    // insert the new record and get the new auto_increment id 
    mysql_query("INSERT INTO {$table} (`{$id_field}`) VALUES (NULL)"); 
    $newid = mysql_insert_id(); 

    // generate the query to update the new record with the previous values 
    $query = "UPDATE {$table} SET "; 
    foreach ($original_record as $key => $value) { 
    if ($key != $id_field) { 
     $query .= '`'.$key.'` = "'.str_replace('"','\"',$value).'", '; 
    } 
    } 
    $query = substr($query,0,strlen($query)-2); # lop off the extra trailing comma 
    $query .= " WHERE {$id_field}={$newid}"; 
    mysql_query($query); 

    // return the new id 
    return $newid; 
} 

这里是链接到文章http://www.epigroove.com/posts/79/how_to_duplicate_a_record_in_mysql_using_php

+1

我试图使用它,并且foreach函数出现错误。 – 2013-06-16 15:01:27

0

如何将行复制到临时表中,然后返回到客户表中?我认为这会迫使mysql给它一个新的自动增量ID,特别是对于你发布的第二个查询版本。

1

什么

insert into test.abc select null, val1, val2 from test.abc where val2 = some_condition; 

似乎为我工作那样。替换你的桌子,领域,条件当然。

null让数据库为您生成自动递增ID。

+0

缺点是,我必须硬编码val1,val2等。有没有办法没有这个硬编码? – Pasta 2009-10-27 18:28:36

+0

是的,这是缺点。我可能会选择以编程方式确定列名并动态构建适当的插入语句以避免对列进行硬编码。 “SHOW COLUMNS FROM table”将为您提供该信息,并在该调用的结果中包含“字段”和“密钥”列。虽然我不是PHP开发人员,但我怀疑可以通过调用来检索列名,剔除非主键字段并从中构建插入语句。还没有尝试过,但怀疑这会起作用。 – itsmatt 2009-10-27 20:18:30

0

到目前为止有两篇文章,这里是第三个选项:在PHP中,动态确定表中的字段。或者,您可以创建一个“硬编码”字段的数组列表,以便手动维护以反映表格。您的结果查询不会使用*。

1

选项:使用

  1. 避免*通配符,和你自己指定的所有列。但是你说表格预计在未来会发生变化,这对你的情况来说不是一个可行的解决方案。

  2. 反思当前表定义的列(使用DESCRIBE或查询INFORMATION_SCHEMA.COLUMNS)。使用这些关于元数据的信息构建查询,省略自动增加主键列。

  3. 执行SELECT *查询,将行取回到您的应用程序中,然后从中删除自动增量列。然后使用该元组来构造一个INSERT语句。

总之,您有一个复杂的要求来适应不断变化的元数据。这可能无法在单个查询中完成。

0

如果你知道你的表的主键列的名称(和我猜测,你这样做,因为它是在where子句中无论如何),我认为你可以这样做:

编辑 - 我忘了MySQL不支持select ... into。这应该工作而不是

create new_table 
select * 
from customer 
where customerid = 9181 

alter table new_table 
drop column customerid 

insert into customer 
select null, * 
from new_table 

drop table new_table