2009-10-27 14 views
5

Mam tabelę i chcę zduplikować określone wiersze w tabeli. Wiem, że to nie jest najlepszy sposób na robienie rzeczy, ale szukamy szybkiego rozwiązania.Duplikat rekordu w MySQL

Oto coś trudniejszego niż początkowo sądziłem, wystarczy skopiować cały rekord do nowego rekordu w tabeli automatycznego przyrostu w MySql bez konieczności podawania każdego pola. Dzieje się tak dlatego, że tabela może się zmienić w przyszłości i może przerwać duplikowanie. Będę duplikował rekordy MySQL z PHP.

Jest to problem, ponieważ w zapytaniu "SELECT *" MySql spróbuje skopiować identyfikator kopiowanego rekordu, który generuje zduplikowany błąd ID.

To blokuje: INSERT INTO customer SELECT * FROM customer WHERE customerid=9181. Blokuje on również INSERT INTO customer (Field1, Field2, ...) SELECT Field1, Field2, ..... FROM customer WHERE customerid=9181. Czy jest sposób na to zrobić z PHP lub MySQL?

Odpowiedz

12

W końcu znalazłem ten kod. Jestem pewien, że pomoże to ludziom w przyszłości. Więc oto jest.

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; 
} 

Oto link do artykułu http://www.epigroove.com/posts/79/how_to_duplicate_a_record_in_mysql_using_php

+1

Próbowałem go użyć i wystąpił błąd z funkcją foreach. –

0

Co powiesz na skopiowanie wierszy do tabeli tymczasowej, a następnie z powrotem do tabeli klientów? Myślę, że zmusiłoby to mysql do nadania mu nowego identyfikatora autoinkrementacji, szczególnie w przypadku drugiej wersji wysłanego zapytania.

1

Co

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

wydaje się działać dla mnie. Zastąp swój stół, pola, stan oczywiście.

Wartość pusta pozwala DB wygenerować dla ciebie identyfikator automatycznej inkrementacji.

+0

Wadą jest to, że muszę ciężko kodować val1, val2, itd. Czy istnieje sposób, aby nie mieć tego twardego kodowania? – Pasta

+0

Tak, to jest wada. Prawdopodobnie zdecyduję się programowo określić nazwy kolumn i skonstruować odpowiednią instrukcję wstawiania w locie, aby uniknąć twardego kodowania kolumn. "POKAŻ KOLUMNY Z tabeli" dostarczy Ci tych informacji, a w wynikach tego połączenia znajduje się kolumna "Pole" i "Klucz". Chociaż nie jestem programistą PHP, podejrzewam, że mógłbyś wykonać wywołanie w celu pobrania nazw kolumn, wyodrębnić pola kluczy innych niż podstawowe i skonstruować instrukcję wstawiania z tego. Nie próbowałem, ale podejrzewam, że to zadziała. – itsmatt

0

Dwa posty do tej pory, a oto trzecia opcja: W PHP dynamicznie określ pola w tabeli. Możesz też utworzyć tablicę z listami, które "zakodowujesz", utrzymywać ręcznie, aby odzwierciedlić tabelę. Twoje zapytanie wynikowe nie będzie używało *.

1

Opcje:

  1. unikać używania * wieloznaczny i określić wszystkie kolumny siebie. Ale twierdzisz, że oczekuje się, że tabela zmieni się w przyszłości i nie jest to praktyczne rozwiązanie dla twojej sprawy.

  2. Introspekcja kolumn z bieżącej definicji tabeli (za pomocą DESCRIBE lub przez zapytanie INFORMATION_SCHEMA.COLUMNS). Użyj tej informacji o metadanych do zbudowania zapytania, pomijając kolumnę klucza klucza z automatyczną inkrementacją.

  3. Wykonaj kwerendę SELECT *, pobierz wiersz z powrotem do aplikacji, a następnie usuń z niego kolumnę automatycznego przyrostu. Następnie użyj tej krotki, aby utworzyć instrukcję INSERT.

Podsumowując, istnieje złożony wymóg dostosowania się do zmieniających się metadanych. Prawdopodobnie nie da się tego zrobić w jednym zapytaniu.

0

Jeśli znasz nazwę kolumny klucza podstawowego w tabeli (i zgaduję, że to zrobisz, bo to w klauzuli WHERE w każdym razie), Myślę, że mógłbyś to zrobić:

Edytuj - Zapomniałem, że MySQL nie obsługuje opcji select ... do. To powinno działać zamiast tego:

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