Di MySQL, dapatkah saya menyalin satu baris untuk dimasukkan ke tabel yang sama?

162
insert into table select * from table where primarykey=1

Saya hanya ingin menyalin satu baris untuk disisipkan ke dalam tabel yang sama (yaitu, saya ingin menduplikasi baris yang ada di tabel) tetapi saya ingin melakukan ini tanpa harus mendaftar semua kolom setelah "pilih", karena tabel ini memiliki kolom terlalu banyak.

Tetapi ketika saya melakukan ini, saya mendapatkan kesalahan:

Entri duplikat 'xxx' untuk kunci 1

Saya bisa menangani ini dengan membuat tabel lain dengan kolom yang sama sebagai wadah sementara untuk catatan yang ingin saya salin:

create table oldtable_temp like oldtable;
insert into oldtable_temp select * from oldtable where key=1;
update oldtable_tem set key=2;
insert into oldtable select * from oldtable where key=2;

Apakah ada cara yang lebih sederhana untuk menyelesaikan ini?

lina
sumber
Saya hanya punya komentar tentang nilai-nilai hard-kode untuk kunci. Saya akan melakukan sesuatu seperti max(oldtable.id) + oldtable_temp.keyini saya memastikan kenaikan id dan unik.
guy mograbi
Kemungkinan duplikat dari Duplikat / Salin catatan dalam tabel MySQL yang sama
Advokat Organik
@OrganicAdvocate ini memiliki lebih banyak jawaban dan lebih banyak pandangan daripada pertanyaan itu
Drew

Jawaban:

189

Saya menggunakan teknik Leonard Challis dengan beberapa perubahan:

CREATE TEMPORARY TABLE tmptable_1 SELECT * FROM table WHERE primarykey = 1;
UPDATE tmptable_1 SET primarykey = NULL;
INSERT INTO table SELECT * FROM tmptable_1;
DROP TEMPORARY TABLE IF EXISTS tmptable_1;

Sebagai tabel temp, seharusnya tidak ada lebih dari satu catatan, jadi Anda tidak perlu khawatir tentang kunci utama. Menetapkannya ke nol memungkinkan MySQL untuk memilih nilai itu sendiri, sehingga tidak ada risiko membuat duplikat.

Jika Anda ingin menjadi sangat yakin bahwa Anda hanya mendapatkan satu baris untuk disisipkan, Anda dapat menambahkan LIMIT 1 di akhir baris INSERT INTO.

Perhatikan bahwa saya juga menambahkan nilai kunci utama (1 dalam kasus ini) ke nama tabel sementara saya.

Suram...
sumber
3
Solusi ini benar (berbeda dengan yang lain yang memperoleh suara) karena memungkinkan MySQL untuk memilih nilai kunci utama.
Jan Hettich
1
Meskipun tidak akan bekerja persis seperti yang disebabkan oleh nama tabel sementara yang tidak konsisten ( tmptable_1vs tmptable)
Kieran Tully
9
Bagaimana kunci primer menjadi nol?
Imran Shafqat
5
Jika nol, maka secara otomatis ditetapkan nomor AI berikutnya ketika dimasukkan.
Suram ...
3
IMRAN - Anda mungkin bertanya. Saya pikir mungkin bidang id dari tabel sementara tidak membuat PK secara otomatis (saya cukup yakin SQL Server tidak melakukannya dalam keadaan ini) tetapi itu. Saya perlu melakukan ALTER TABLE tmptable_1 MODIFY primarykeyINT NULL; setelah baris pertama untuk membuat solusi bekerja
DJDave
61

Pembaruan 07/07/2014 - Jawaban berdasarkan jawaban saya, oleh Grim ... , adalah solusi yang lebih baik karena meningkatkan solusi saya di bawah, jadi saya sarankan menggunakan itu.

Anda dapat melakukan ini tanpa mencantumkan semua kolom dengan sintaks berikut:

CREATE TEMPORARY TABLE tmptable SELECT * FROM table WHERE primarykey = 1;
UPDATE tmptable SET primarykey = 2 WHERE primarykey = 1;
INSERT INTO table SELECT * FROM tmptable WHERE primarykey = 2;

Anda dapat memutuskan untuk mengubah kunci utama dengan cara lain.

LeonardChallis
sumber
16
Ini pada dasarnya adalah solusi yang sama dengan OP telah menyediakan untuk masalah mereka sendiri, meskipun dengan tabel temp aktual , dan pola pembuatan sedikit lebih bersih. Saya pikir OP meminta pendekatan yang lebih baik untuk apa yang sudah mereka gunakan, bukan pembersihan dari sintaks yang ada. Tidak benar-benar mengerti semua upvotes untuk ini.
Sepster
Terima kasih. Ini berjalan baik dengan fungsi dinamis
Sonal Khunt
Apakah perlu menghapus tmptable setelah proses ini selesai?
SSH
"Secara default, semua tabel sementara dihapus oleh MySQL ketika koneksi basis data Anda diputus. Masih Anda ingin menghapusnya di antaranya maka Anda melakukannya dengan mengeluarkan perintah DROP TABLE." Lebih lanjut di sini
LeonardChallis
Mengingat Anda membuat tmptable, Anda tidak perlu menambahkan WHERE primarykey = 2pernyataan untuk baris terakhir juga. (Yaitu INSERT INTO table SELECT * FROM tmptable.)
Marcus
42

Saya berasumsi Anda ingin catatan baru memiliki yang baru primarykey? Jika primarykeyini AUTO_INCREMENTkemudian hanya melakukan ini:

INSERT INTO table (col1, col2, col3, ...)
SELECT col1, col2, col3, ... FROM table
  WHERE primarykey = 1

... di mana col1, col2, col3, ...semua kolom dalam tabel kecuali untuk primarykey .

Jika bukan AUTO_INCREMENTkolom dan Anda ingin dapat memilih nilai baru untuk primarykeyitu serupa:

INSERT INTO table (primarykey, col2, col3, ...)
SELECT 567, col2, col3, ... FROM table
  WHERE primarykey = 1

... di mana 567nilai baru untuk primarykey.

Jordan Running
sumber
41
Kenapa ini terbalik 7 kali ketika mengabaikan pertanyaan? ... tetapi saya tidak ingin mencantumkan semua kolom setelah "pilih", karena tabel ini memiliki terlalu banyak kolom ...
LeonardChallis
7
-1 karena inilah yang ingin dihindari OP. Baca pertanyaannya, atau paling tidak tawarkan jawaban seperti "ini satu-satunya cara yang mungkin".
devios1
5
Karena terkadang pertanyaannya sendiri salah. :) Baris duplikat tanpa mengubah konten meningkatkan redundansi. Mengubah struktur database untuk meminimalkan redundansi harus direkomendasikan, jika memungkinkan.
Torben
5
Hanya karena itu tidak benar dalam praktik normal tidak membuatnya salah. Ada banyak waktu ketika praktik terbaik standar tidak berlaku. Contoh: database mewakili dokumen dan pengguna perlu menyimpan salinan dokumen sebelum membuat perubahan.
ima747
6
Karena Anda mungkin mendarat di halaman ini tidak ingin persis sama dengan OP
jx12345
13

Anda hampir memilikinya dengan kueri pertama Anda, Anda hanya perlu menentukan kolom, dengan cara itu Anda dapat mengecualikan kunci utama Anda di sisipan yang akan memberlakukan kenaikan otomatis yang mungkin Anda miliki di atas meja untuk secara otomatis membuat kunci primer baru untuk masuk.

Misalnya ubah ini:

insert into table select * from table where primarykey=1

Untuk ini:

INSERT INTO table (col1, col2, col3) 
SELECT col1, col2, col3 
FROM table 
WHERE primarykey = 1

Hanya saja, jangan memasukkan kolom kunci utama dalam daftar kolom untuk INSERT atau untuk bagian SELECT dari permintaan.

Braeden Black
sumber
1
adakah cara untuk menarik sebagian besar kolom melalui pernyataan pilih tetapi perbarui salah satunya secara manual dalam perintah insert? seperti insert into table ("val1", col2, col3) select col2, col3 from table where primarykey = 1atau yang serupa?
anon58192932
1
Menemukannya! Salin nilai dari satu baris tetapi tambahkan salah satu dari nilai Anda sendiri ke dalam pernyataan penyisipan: stackoverflow.com/questions/23971078/…
anon58192932
1
Maaf baru saja diberitahu tentang pertanyaan Anda, senang Anda menemukannya, memang itulah caranya.
Braeden Black
9

Anda juga dapat mencoba membuang tabel, menemukan perintah memasukkan dan mengeditnya:

mysqldump -umyuser -p mydatabase --skip-extended-insert mytable > outfile.sql

The --skip-extended-insertmemberikan satu perintah insert per baris. Anda kemudian dapat menemukan baris di editor teks favorit Anda, ekstrak perintah dan ubah kunci utama menjadi "default".

donasi berhasil
sumber
2
Memberi saya +1 karena ini adalah pendekatan "luar kotak" yang bagus yang sebenarnya dapat membantu di luar run-time, dalam beberapa keadaan. Tapi terutama itu adalah jawaban pertama yang benar-benar menjawab pertanyaan OP dan tidak hanya men-tweak solusi yang sudah disediakan oleh OP.
Sepster
6

Prosedur ini mengasumsikan bahwa:

  • Anda tidak memiliki _duplicate_temp_table
  • kunci utama Anda adalah int
  • Anda memiliki akses untuk membuat tabel

Tentu saja ini tidak sempurna, tetapi dalam kasus-kasus tertentu (mungkin sebagian besar) itu akan berhasil.

DELIMITER $$
CREATE PROCEDURE DUPLICATE_ROW(copytable VARCHAR(255), primarykey VARCHAR(255), copyid INT, out newid INT)
BEGIN
        DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @error=1;
        SET @temptable = '_duplicate_temp_table';
        SET @sql_text = CONCAT('CREATE TABLE ', @temptable, ' LIKE ', copytable);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('INSERT INTO ', @temptable, ' SELECT * FROM ', copytable, ' where ', primarykey,'=', copyid);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('SELECT max(', primarykey, ')+1 FROM ', copytable, ' INTO @newid');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('UPDATE ', @temptable, ' SET ', primarykey, '=@newid');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('INSERT INTO ', copytable, ' SELECT * FROM ', @temptable, '');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('DROP TABLE ', @temptable);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SELECT @newid INTO newid;
END $$
DELIMITER ;

CALL DUPLICATE_ROW('table', 'primarykey', 1, @duplicate_id);
SELECT @duplicate_id;
Piotr Kaczmarek
sumber
1
+1 Belum mengonfirmasi hal ini workstetapi pendekatannya masuk akal, dan bernilai karena unik di sini dan benar-benar menjawab pertanyaan OP.
Sepster
5

Ini dapat dicapai dengan beberapa kreativitas:

SET @sql = CONCAT('INSERT INTO <table> SELECT null, 
    ', (SELECT GROUP_CONCAT(COLUMN_NAME) 
    FROM information_schema.columns 
    WHERE table_schema = '<database>' 
    AND table_name = '<table>' 
    AND column_name NOT IN ('id')), ' 
from <table> WHERE id = <id>');  

PREPARE stmt1 FROM @sql;
EXECUTE stmt1;

Ini akan menghasilkan baris baru mendapatkan id yang bertambah secara otomatis alih-alih id dari baris yang dipilih.

curmil
sumber
Ini harus menjadi jawaban yang diterima!
Felipe Desiderati
5

Jika bidang kunci utama tabel Anda adalah bidang kenaikan otomatis, maka Anda bisa menggunakan kueri dengan kolom. Misalnya, nama tabel Anda test_tblmemiliki 3 bidang sebagai id, name, age. idadalah bidang kunci utama dan kenaikan otomatis, sehingga Anda dapat menggunakan kueri berikut untuk menduplikasi baris:

INSERT INTO `test_tbl` (`name`,`age`) SELECT `name`,`age` FROM `test_tbl`;

Kueri ini menghasilkan duplikasi setiap baris.


Jika bidang kunci utama tabel Anda bukan bidang kenaikan otomatis, maka Anda dapat menggunakan metode berikut:

INSERT INTO `test_tbl` (`id`,`name`,`age`)
  SELECT 20,`name`,`age` FROM `test_tbl` WHERE id = 19;

Hasil dari kueri ini adalah baris duplikat yang id=19disisipkan sebagai id=20.

pengguna2595171
sumber
Itu adalah jawaban terbaik yang ada, kasus ini cukup sederhana: INSERT INTO tableName( fieldName1, fieldName2, fieldName3) SELECT fieldName1, fieldName2, fieldName3DARI tableNameMANA 1 (untuk menyalin semua dari mereka sekaligus)
jakubplus
Diperbanyak - jawaban ini ringkas dan dengan semangat "Menyalin" berturut-turut.
user37309
4

baris klon dengan bidang pembaruan dan nilai kenaikan otomatis

CREATE TEMPORARY TABLE `temp` SELECT * FROM `testing` WHERE id = 14;

UPDATE `temp` SET id = (SELECT id FROM testing ORDER by id DESC LIMIT 1
 )+1, user_id = 252 ,policy_no = "mysdddd12" where id = 14;

INSERT INTO `testing` SELECT * FROM `temp`;

DROP TEMPORARY TABLE IF EXISTS `temp`;
Shrinivas Mahindrakar
sumber
@Torben Periksa centang di sebelah kiri pertanyaan (tandai sebagai diterima) sehingga semua orang tahu itu bekerja untuk Anda.
HosseyNJF
3

Beberapa hal berikut diperoleh dari situs ini. Inilah yang saya lakukan untuk menduplikasi catatan dalam tabel dengan sejumlah bidang:

Ini juga mengasumsikan Anda memiliki bidang AI di awal tabel

function duplicateRow( $id = 1 ){
dbLink();//my db connection
$qColumnNames = mysql_query("SHOW COLUMNS FROM table") or die("mysql error");
$numColumns = mysql_num_rows($qColumnNames);

for ($x = 0;$x < $numColumns;$x++){
$colname[] = mysql_fetch_row($qColumnNames);
}

$sql = "SELECT * FROM table WHERE tableId = '$id'";
$row = mysql_fetch_row(mysql_query($sql));
$sql = "INSERT INTO table SET ";
for($i=1;$i<count($colname)-4;$i++){//i set to 1 to preclude the id field
//we set count($colname)-4 to avoid the last 4 fields (good for our implementation)
$sql .= "`".$colname[$i][0]."`  =  '".$row[$i]. "', ";
}
$sql .= " CreateTime = NOW()";// we need the new record to have a new timestamp
mysql_query($sql);
$sql = "SELECT MAX(tableId) FROM table";
$res = mysql_query($sql);
$row = mysql_fetch_row($res);
return $row[0];//gives the new ID from auto incrementing
}
richardwhitney
sumber
2

Saya mungkin terlambat dalam hal ini, tetapi saya memiliki solusi serupa yang berhasil bagi saya.

 INSERT INTO `orders` SELECT MAX(`order_id`)+1,`container_id`, `order_date`, `receive_date`, `timestamp` FROM `orders` WHERE `order_id` = 1

Dengan cara ini saya tidak perlu membuat tabel sementara dan lain-lain. Seperti baris disalin dalam tabel yang sama Max(PK)+1 fungsinya dapat digunakan dengan mudah.

Saya datang mencari solusi dari pertanyaan ini (lupa sintaksisnya) dan akhirnya saya membuat pertanyaan sendiri. Lucu bagaimana hal itu terjadi beberapa kali.

Salam

echo_salik
sumber
2

Jika Kunci Utama adalah Peningkatan Otomatis, cukup tentukan setiap bidang kecuali kunci utama.

INSERT INTO table(field1,field2,field3) SELECT (field1,field2,field3) FROM table WHERE primarykey=1

Racun Fedy
sumber
2

Saya memperbarui solusi @ LeonardChallis karena tidak berfungsi untuk saya karena tidak ada yang lain. Saya menghapus WHEREklausa dan SET primaryKey = 0di tabel temp sehingga MySQL secara otomatis menambah sendiri primaryKey

CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable;
UPDATE tmptable SET primaryKey = 0;
INSERT INTO myTable SELECT * FROM tmptable;

Ini tentu saja untuk menduplikasi semua baris dalam tabel.

D4V1D
sumber
2

Saya menggunakan teknik Grim dengan sedikit perubahan: Jika seseorang mencari permintaan ini adalah karena tidak dapat melakukan permintaan sederhana karena masalah kunci utama:

INSERT INTO table SELECT * FROM table WHERE primakey=1;

Dengan MySql saya menginstal 5.6.26, kunci tidak dapat dibatalkan dan menghasilkan kesalahan:

#1048 - Column 'primakey' cannot be null 

Jadi setelah membuat tabel sementara saya mengubah kunci utama menjadi nullable.

CREATE TEMPORARY TABLE tmptable_1 SELECT * FROM table WHERE primarykey = 1;
ALTER TABLE tmptable_1 MODIFY primarykey int(12) null;
UPDATE tmptable_1 SET primarykey = NULL;
INSERT INTO table SELECT * FROM tmptable_1;
DROP TEMPORARY TABLE IF EXISTS tmptable_1;
Luca Camillo
sumber
sebagai alternatif, dalam versi baru mariadb / mysql, primaryKey dapat diatur ke 0 yang memungkinkan kenaikan otomatis berfungsi ketika dimasukkan.
shelbypereira
2

Saya akan gunakan di bawah ini,

insert into ORDER_ITEM select * from ORDER_ITEM where ITEM_NUMBER =123;
Ishan Liyanage
sumber
1
Ini tidak berfungsi jika ITEM_NUMBER adalah kunci utama Anda, yang kemungkinan besar dalam situasi ini.
Billy Pilgrim
2

Saya menggunakan dalam database Koha saya untuk memasukkan item duplikat dengan awalan 'C' di kolom barcode :

INSERT INTO items (`biblionumber`, `biblioitemnumber`, `barcode`, `dateaccessioned` ) SELECT `biblionumber`, `biblioitemnumber`,  CONCAT('C',`barcode`), `dateaccessioned` FROM `items` WHERE barcode='14832';
Rajiv Mahmud
sumber
1

Saya hanya perlu melakukan ini dan ini adalah solusi manual saya:

  1. Di phpmyadmin , periksa baris yang ingin Anda salin
  2. Di bagian bawah di bawah operasi hasil permintaan klik 'Ekspor'
  3. Pada halaman berikutnya periksa 'Simpan sebagai file' lalu klik 'Pergi'
  4. Buka file yang diekspor dengan editor teks, temukan nilai bidang utama dan ubah menjadi sesuatu yang unik.
  5. Kembali di klik phpmyadmin pada tab 'Impor' , cari file untuk mengimpor file .sql di bawah browse , klik 'Go' dan baris duplikat harus dimasukkan.

Jika Anda tidak tahu apa bidang PRIMER itu, lihat kembali halaman phpmyadmin Anda , klik pada tab 'Struktur' dan di bagian bawah halaman di bawah 'Indeks' itu akan menunjukkan kepada Anda 'Bidang' mana yang memiliki 'Keyname' nilai 'PRIMER' .

Agak jauh, tetapi jika Anda tidak ingin berurusan dengan markup dan hanya perlu menduplikasi satu baris di sana Anda pergi.

pengguna27068
sumber
Bagus, jawab op dengan cara yang tidak biasa. Jelas tidak bekerja untuk semua kasus, seperti gumpalan dan data geospasial, tetapi cukup mudah untuk dilakukan dan bekerja untuk perubahan bola yang aneh itu.
Strixy
1

Solusi ini menunjukkan karya di atas sempurna juga untuk baris yang dipilih. Misalnya saya membuat baris demonstrasi untuk proyek nice2work saya, dan ini berfungsi dengan sempurna.

CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable WHERE id=500;
UPDATE tmptable SET id = 0;
UPDATE some fields I need to change
INSERT INTO myTable SELECT * FROM tmptable;
DROP TABLE tmptable;

//  You can use this same also directly into your code like (PHP Style)
$sql = "CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable WHERE id=500;
UPDATE tmptable SET id = 0;
UPDATE some fields I need to change
INSERT INTO myTable SELECT * FROM tmptable;DROP TABLE tmptable;";
Ronald Stevens
sumber
0

Maaf untuk necropost tapi inilah yang saya temukan dengan google dan karena saya menemukan ini membantu tapi bermasalah saya ingin berkontribusi modifikasi penting bagi siapa pun yang menggali ini.

Pertama, saya menggunakan SQL Server, bukan MySQL, tapi saya pikir itu harus bekerja sama. Saya menggunakan solusi Leonard Challis karena itu paling sederhana dan memenuhi kebutuhan, namun ada masalah dengan ini - jika Anda hanya mengambil PK dan menambahnya 1 maka apa yang terjadi jika Anda telah menambahkan catatan lain sejak baris yang dipertanyakan ditambahkan . Saya memutuskan bahwa yang terbaik adalah membiarkan sistem menangani perbaikan otomatis PK, jadi saya melakukan yang berikut:

SELECT * INTO #tmpTable FROM Table WHERE primarykey = 1
--Optionally you can modify one or more fields here like this: 
--UPDATE #tmpTable SET somefield = newData
ALTER TABLE #tmpTable DROP COLUMN TicketUpdateID
INSERT INTO Tickets SELECT * FROM #tmpTable
DROP TABLE #tmpTable

Saya percaya ini akan bekerja dengan cara yang sama di MySQL, tapi saya tidak bisa menguji ini, maaf

maxx233
sumber
1
totally bakwaas answer
AsadYarKhan
0

Saya tahu ini pertanyaan lama, tapi di sini ada solusi lain:

Ini menggandakan baris di tabel utama, dengan asumsi kunci utama adalah kenaikan otomatis, dan membuat salinan data tabel terkait dengan id tabel utama baru.

Pilihan lain untuk mendapatkan nama kolom:
-MUNJUKKAN KOLOM DARI tablename; (Nama kolom: Field)
-DESCRIBE tablename (Nama kolom: Field)
-SELECT column_name FROM information_schema.columns WHERE table_name = 'tablename' (Nama kolom: column_name)

//First, copy main_table row
$ColumnHdr='';
$Query="SHOW COLUMNS FROM `main_table`;";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
while($Row=mysql_fetch_array($Result))
{
    if($Row['Field']=='MainTableID')     //skip main table id in column list
        continue;
    $ColumnHdr.=",`" . $Row['Field'] . "`";
}
$Query="INSERT INTO `main_table` (" . substr($ColumnHdr,1) . ")
        (SELECT " . substr($ColumnHdr,1) . " FROM `main_table`
            WHERE `MainTableID`=" . $OldMainTableID . ");";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
$NewMainTableID=mysql_insert_id($link);

//Change the name (assumes a 30 char field)
$Query="UPDATE `main_table` SET `Title`=CONCAT(SUBSTRING(`Title`,1,25),' Copy') WHERE `MainTableID`=" . $NewMainTableID . ";";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);

//now copy in the linked tables
$TableArr=array("main_table_link1","main_table_link2","main_table_link3");
foreach($TableArr as $TableArrK=>$TableArrV)
{
    $ColumnHdr='';
    $Query="SHOW COLUMNS FROM `" . $TableArrV . "`;";
    $Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
    while($Row=mysql_fetch_array($Result))
    {
        if($Row['Field']=='MainTableID')     //skip main table id in column list, re-added in query
            continue;
        if($Row['Field']=='dbID')    //skip auto-increment,primary key in linked table
            continue;
        $ColumnHdr.=",`" . $Row['Field'] . "`";
    }

    $Query="INSERT INTO `" . $TableArrV . "` (`MainTableID`," . substr($ColumnHdr,1) . ")
            (SELECT " . $NewMainTableID . "," . substr($ColumnHdr,1) . " FROM `" . $TableArrV . "`
             WHERE `MainTableID`=" . $OldMainTableID . ");";
    $Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
}
Paul
sumber
0

max233 sudah pasti di jalur yang benar, setidaknya untuk kasus peningkatan otomatis. Namun, jangan lakukan ALTER TABLE. Cukup setel bidang kenaikan-otomatis di tabel sementara ke NULL. Ini akan menampilkan kesalahan, tetapi MASUKKAN semua bidang di tabel sementara berikut akan terjadi dan bidang otomatis NULL akan mendapatkan nilai unik.

pengguna3067083
sumber
0

Buat tabel

    CREATE TABLE `sample_table` (
       `sample_id` INT(10) unsigned NOT NULL AUTO_INCREMENT,
       `sample_name` VARCHAR(255) NOT NULL,
       `sample_col_1` TINYINT(1) NOT NULL,
       `sample_col_2` TINYINT(2) NOT NULL,

      PRIMARY KEY (`sample_id`),
      UNIQUE KEY `sample_id` (`sample_id`)

    ) ENGINE='InnoDB' DEFAULT CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

Sisipkan satu baris

INSERT INTO `sample_table`
   VALUES(NULL, 'sample name', 1, 2);

Masukkan baris klon di atas

INSERT INTO `sample_table`
   SELECT 
    NULL AS `sample_id`, -- new AUTO_INCREMENT PRIMARY KEY from MySQL
    'new dummy entry' AS `sample_name`,  -- new UNIQUE KEY from you
    `sample_col_1`, -- col from old row
    `sample_col_2` -- col from old row
   FROM `sample_table`
   WHERE `sample_id` = 1;

Uji

SELECT * FROM `sample_table`;
Abdullah Aydın
sumber
Catatan: Jika Anda mendapatkan kesalahan (# 1048) gunakan '' sebagai ganti NULL
Abdullah Aydın
Apakah hanya saya atau ini persis apa yang OP tidak ingin? (Yaitu secara manual menambahkan setiap kolom ke kueri.)
Byson
Anda benar, saya baru saja membaca kalimat OP "I HANYA ingin menyalin satu baris untuk dimasukkan ke dalam tabel yang sama", mungkin, lagi pula ini masih berguna untuk "Duplikat entri 'xxx' untuk kunci ???" error ^^
Abdullah Aydın
0

Inilah jawaban yang saya temukan online di situs ini Menjelaskan cara melakukan hal di atas 1 Anda dapat menemukan jawabannya di bagian bawah halaman. Pada dasarnya, apa yang Anda lakukan adalah menyalin baris yang akan disalin ke tabel sementara yang disimpan dalam memori. Anda kemudian mengubah nomor Kunci Utama menggunakan pembaruan. Anda kemudian memasukkan kembali ke tabel target. Anda kemudian menjatuhkan meja.

Ini adalah kode untuk itu:

BUAT rescueteamMESIN TABEL SEMENTARA = MEMORY SELECT * DARI fitnessreport4MANA rID = 1; # 1 baris terpengaruh. rescueteamSET UPDATE rID = Null WHERE rID = 1; baris # 1 terpengaruh. MASUK KE fitnessreport4PILIHAN * DARI rescueteam; Baris # 1 terpengaruh. DROP TABLE rescueteam# MySQL mengembalikan set hasil kosong (yaitu
baris nol ).

Saya membuat rescueteam tabel sementara. Saya menyalin baris dari tabel asli fitnessreport4 saya. Saya kemudian mengatur kunci utama untuk baris di tabel sementara ke nol sehingga saya bisa menyalinnya kembali ke tabel asli tanpa mendapatkan kesalahan kunci duplikat. Saya mencoba kode ini kemarin malam dan berhasil.

pengguna2363682
sumber
0

Ini adalah solusi tambahan untuk jawaban oleh "Grim ..." Ada beberapa komentar di atasnya yang memiliki kunci utama sebagai nol. Beberapa komentar tentang itu tidak berfungsi. Dan beberapa komentar tentang solusi. Tidak ada solusi yang berhasil bagi kami. Kami memiliki MariaDB dengan tabel InnoDB.

Kami tidak dapat mengatur kunci utama untuk mengizinkan nol. Menggunakan 0 bukannya NULL menyebabkan kesalahan nilai duplikat untuk kunci utama. SET SQL_SAFE_UPDATES = 0;Tidak berhasil juga.

Solusi dari "Grim ..." berhasil JIKA kita mengubah KUNCI UTAMA kita menjadi UNIK

Simon
sumber
-1

Hanya ingin memposting sepotong kode PHP saya, karena saya pikir cara saya mengumpulkan kolom sedikit lebih bersih dalam kode daripada contoh sebelumnya. Ini juga menunjukkan bagaimana Anda bisa dengan mudah mengubah bidang, dalam hal ini menambahkan string. Tetapi Anda juga bisa mengganti bidang kunci asing dengan catatan yang baru ditambahkan, jika Anda ingin menyalin beberapa catatan anak juga.

  // Read columns, unset the PK (always the first field in my case)
  $stmt = $conn->prepare('SHOW COLUMNS FROM template');
  $stmt->execute();

  $columns = $stmt->fetchAll();
  $columns = array_map(function ($element) { return $element['Field']; }, $columns);

  unset($columns[0]);

  // Insert record in the database. Add string COPY to the name field.
  $sql = "INSERT INTO `template` (".implode(",", $columns).")";
  if ($key = array_search('name', $columns))
      $columns[$key] = "CONCAT(name, ' COPY')";
  $sql .= " SELECT ".implode(",", $columns)." FROM `template` WHERE `id` = ".$id;

  $stmt = $conn->prepare($sql);
  $stmt->execute();
rolandow
sumber
-2

Untuk solusi yang sangat sederhana, Anda dapat menggunakan PHPMyAdmin untuk mengekspor baris sebagai file CSV kemudian cukup mengimpor file CSV yang diubah. Mengedit kolom ID / primarykey untuk tidak menunjukkan nilai sebelum Anda mengimpornya.

SELECT * FROM table where primarykey=1

Kemudian di bagian bawah halaman:

masukkan deskripsi gambar di sini

Di mana dikatakan "Ekspor" cukup ekspor, lalu edit file csv untuk menghapus nilai primarykey, jadi itu kosong, dan kemudian hanya impor ke dalam database, primarykey baru akan ditugaskan pada impor.

Hibah
sumber