2009-10-27 43 views
5

Tôi có một bảng và tôi muốn sao chép các hàng cụ thể trong bảng. Tôi biết đây không phải là cách tốt nhất để làm việc nhưng chúng tôi đang tìm kiếm một giải pháp nhanh chóng. Đây là một cái gì đó khó hơn tôi nghĩ ban đầu, tất cả những gì tôi cần làm là sao chép toàn bộ bản ghi vào một bản ghi mới trong bảng tự động tăng trong MySql mà không cần chỉ định từng trường. Điều này là do bảng có thể thay đổi trong tương lai và có thể phá vỡ trùng lặp. Tôi sẽ nhân bản các bản ghi MySQL từ PHP.Sao chép một bản ghi trong MySQL

Đó là một vấn đề bởi vì trong một truy vấn 'SELECT *' MySql sẽ cố gắng sao chép ID của bản ghi được sao chép mà tạo ra một lỗi ID trùng lặp.

Điều này chặn: INSERT INTO customer SELECT * FROM customer WHERE customerid=9181. Nó cũng chặn ra INSERT INTO customer (Field1, Field2, ...) SELECT Field1, Field2, ..... FROM customer WHERE customerid=9181.

Có cách nào để thực hiện điều này từ PHP hay MySQL không?

Trả lời

12

Cuối cùng tôi đã tìm thấy mã này. Tôi chắc chắn nó sẽ giúp mọi người trong tương lai. Vì vậy, ở đây nó được.

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

Dưới đây là liên kết đến bài viết http://www.epigroove.com/posts/79/how_to_duplicate_a_record_in_mysql_using_php

+1

Tôi đã cố gắng sử dụng nó và có một lỗi với chức năng foreach. –

0

Làm thế nào để sao chép các hàng vào bảng tạm thời và sau đó quay trở lại bảng khách hàng? Tôi nghĩ rằng sẽ buộc mysql cung cấp cho nó một ID tự động mới, đặc biệt là với phiên bản thứ hai của truy vấn bạn đã đăng.

1

gì về

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

Dường như làm việc đối với tôi như thế. Thay thế bảng của bạn, các lĩnh vực, điều kiện của khóa học.

Giá trị rỗng cho phép DB tạo ID tự động tăng cho bạn.

+0

Nhược điểm là tôi phải mã hóa cứng val1, val2, v.v ... Có cách nào không có mã hóa cứng này không? – Pasta

+0

Vâng, đó là nhược điểm. Tôi có thể chọn để lập trình xác định tên cột và xây dựng câu lệnh chèn phù hợp khi đang di chuyển để tránh mã hóa cứng các cột. "HIỂN THỊ COLUMNS TỪ bảng" sẽ cung cấp cho bạn thông tin đó và có cột 'Trường' và 'Khóa' trong kết quả từ cuộc gọi đó. Trong khi tôi không phải là một nhà phát triển PHP, tôi nghi ngờ bạn có thể thực hiện cuộc gọi để lấy các tên cột, loại bỏ các trường không phải là khóa chính và xây dựng câu lệnh chèn từ đó. Đã không thử nó, nhưng nghi ngờ rằng điều này sẽ làm việc. – itsmatt

0

Hai bài đăng cho đến nay và đây là tùy chọn thứ 3: Trong PHP, tự động xác định các trường trong bảng của bạn. Hoặc, bạn có thể tạo một danh sách mảng các trường mà bạn "mã cứng", duy trì bằng tay để phản ánh bảng. Truy vấn kết quả của bạn sẽ không sử dụng *.

1

Options:

  1. Tránh sử dụng các ký tự đại diện *, và chỉ định tất cả các cột chính mình. Nhưng bạn nói rằng bảng được dự kiến ​​sẽ thay đổi trong tương lai và đây không phải là giải pháp khả thi cho trường hợp của bạn.

  2. Nhìn vào các cột từ định nghĩa bảng hiện tại (sử dụng DESCRIBE hoặc bằng cách truy vấn INFORMATION_SCHEMA.COLUMNS). Sử dụng thông tin này về siêu dữ liệu để tạo truy vấn, bỏ qua cột khóa chính tăng tự động.

  3. Thực hiện truy vấn SELECT *, tìm nạp lại hàng vào ứng dụng của bạn, sau đó xóa cột tăng tự động khỏi ứng dụng. Sau đó, sử dụng bộ dữ liệu đó để tạo một tuyên bố INSERT.

Tóm lại, bạn có yêu cầu phức tạp để thích ứng với thay đổi siêu dữ liệu. Điều đó có thể không được thực hiện trong một truy vấn đơn lẻ.

0

Nếu bạn biết tên của cột khóa chính trong bảng của bạn (và tôi đoán rằng bạn làm vì nó là trong mệnh đề where anyway), Tôi nghĩ bạn có thể làm điều này:

Chỉnh sửa - Tôi quên rằng MySQL không hỗ trợ chọn ... vào. Điều này sẽ hoạt động thay vì

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 
Các vấn đề liên quan