2009-10-27 99 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