Saya telah mencari beberapa waktu sekarang tetapi saya tidak dapat menemukan solusi yang mudah untuk masalah saya. Saya ingin menduplikasi catatan dalam tabel, tetapi tentu saja, kunci utama yang unik perlu diperbarui.
Saya punya pertanyaan ini:
INSERT INTO invoices
SELECT * FROM invoices AS iv WHERE iv.ID=XXXXX
ON DUPLICATE KEY UPDATE ID = (SELECT MAX(ID)+1 FROM invoices)
Masalahnya adalah ini hanya mengubah ID
baris, bukan menyalin baris. Apakah ada yang tahu cara memperbaikinya?
// edit: Saya ingin melakukan ini tanpa mengetik semua nama field karena nama field dapat berubah seiring waktu.
CREATE TEMPORARY TABLE tmp SELECT bla FROM invoices WHERE bla; UPDATE tmp SET id=NULL; INSERT INTO invoices SELECT * FROM tmp;
NOT NULL
menyetelnyaid
. Saya hanya ingin tahu apakah Anda punya saran untuk kasus ini. Apakah itu dianggap praktik yang buruk?Jawaban Alex membutuhkan perhatian (misalnya penguncian atau transaksi) di lingkungan multi-klien.
Dengan asumsi
AUTO ID
bidang tersebut adalah yang pertama dalam tabel (kasus biasa), kita dapat menggunakan transaksi implisit.Dari dokumen MySQL:
sumber
NULL
atau0
keduanya dapat diterima. Dapatkah Anda memposting tangkapan layar masalah dengan mereproduksi dan membagikannya di sini.invoices
berisiID
bidang AUTO_INCREMENT . Tabel sumbertmp
tidak. Untuk mendapatkan korelasi 1: 1 yang diperlukan selama penyisipan, Anda menentukan a0
sebagai bidang pertama dari pilih yang merupakan bidang AUTO_INCREMENT tabel tujuan. Thetmp.*
menyeleksi semua bidang dari tabel sumbertmp
. Sempurna! Anda sekarang memiliki korelasi 1: 1. Jawaban luar biasa @Tim.NULL
dan0
tidak sama. Konteks saat ini ada diAUTO_INCREMENT
fitur. Anda tidak dapat menyisipkan0
atauNULL
nilai ke dalam bidang seperti itu. Tapi ketika Anda menggunakannya sebagai masukan ke lapangan seperti itu, nilai urutan berikutnya akan ditugaskan dengan bidang auto matically. Dan karena itulah komentar saya. Bukti tentang SQL Fiddle: sqlfiddle.com/#!9/d619f/1Anda TAHU pasti, bahwa DUPLICATE KEY akan terpicu, sehingga Anda dapat memilih MAX (ID) +1 terlebih dahulu:
INSERT INTO invoices SELECT MAX(ID)+1, ... other fields ... FROM invoices AS iv WHERE iv.ID=XXXXX
sumber
Pendekatan Anda bagus tetapi masalahnya adalah Anda menggunakan "*" alih-alih meminta nama bidang. Jika Anda meletakkan semua nama kolom kecuali kunci utama, skrip Anda akan berfungsi seperti pesona pada satu atau banyak rekaman.
INSERT INTO invoices (iv.field_name, iv.field_name,iv.field_name ) SELECT iv.field_name, iv.field_name,iv.field_name FROM invoices AS iv WHERE iv.ID=XXXXX
sumber
Jawaban terlambat yang saya tahu, tetapi ini masih merupakan pertanyaan umum, saya ingin menambahkan jawaban lain yang berhasil untuk saya, dengan hanya menggunakan satu baris
insert into
pernyataan, dan menurut saya ini sangat mudah, tanpa membuat tabel baru (karena dapat menjadi masalah denganCREATE TEMPORARY TABLE
izin):INSERT INTO invoices (col_1, col_2, col_3, ... etc) SELECT t.col_1, t.col_2, t.col_3, ... t.updated_date, FROM invoices t;
Solusinya bekerja untuk
AUTO_INCREMENT
kolom id, jika tidak, Anda dapat menambahkanID
kolom juga ke pernyataan:INSERT INTO invoices (ID, col_1, col_2, col_3, ... etc) SELECT MAX(ID)+1, t.col_1, t.col_2, t.col_3, ... etc , FROM invoices t;
Ini sangat mudah dan lugas, Anda dapat memperbarui apa pun dalam satu baris tanpa pernyataan pembaruan kedua untuk nanti, (mis: memperbarui kolom judul dengan teks tambahan atau mengganti string dengan yang lain), juga Anda dapat lebih spesifik dengan apa sebenarnya Anda ingin menduplikasi, jika semuanya, jika beberapa, Anda dapat melakukannya.
sumber
INSERT into wp_options SELECT NULL, 'theme_mods_twopress', option_value, autoload FROM wp_options where option_name = 'theme_mods_onepress';
menyalin sambil meningkatkan entri (AUTO_INCREMENT
NULL
trik dari atas) danoption_name
bidang juga.Saya hanya ingin menyampaikan jawaban hebat Alex agar sesuai jika Anda kebetulan ingin menduplikasi seluruh rangkaian catatan:
SET @x=7; CREATE TEMPORARY TABLE tmp SELECT * FROM invoices; UPDATE tmp SET id=id+@x; INSERT INTO invoices SELECT * FROM tmp;
Saya hanya harus melakukan ini dan menemukan jawaban Alex sebagai titik awal yang sempurna !. Tentu saja, Anda harus menyetel @x ke nomor baris tertinggi dalam tabel (saya yakin Anda bisa mengambilnya dengan kueri). Ini hanya berguna dalam situasi yang sangat spesifik ini, jadi berhati-hatilah menggunakannya saat Anda tidak ingin menduplikasi semua baris. Sesuaikan matematika seperlunya.
sumber
Saya memiliki masalah serupa, dan inilah yang saya lakukan:
insert into Preguntas (`EncuestaID`, `Tipo` , `Seccion` , `RespuestaID` , `Texto` ) select '23', `Tipo`, `Seccion`, `RespuestaID`, `Texto` from Preguntas where `EncuestaID`= 18
Been Preguntas:
CREATE TABLE IF NOT EXISTS `Preguntas` ( `ID` int(11) unsigned NOT NULL AUTO_INCREMENT, `EncuestaID` int(11) DEFAULT NULL, `Tipo` char(5) COLLATE utf8_unicode_ci DEFAULT NULL, `Seccion` int(11) DEFAULT NULL, `RespuestaID` bigint(11) DEFAULT NULL, `Texto` text COLLATE utf8_unicode_ci , PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=522 ;
Jadi,
ID
secara otomatis bertambah dan saya juga menggunakan nilai tetap ('23') untukEncuestaID
.sumber
Saya membutuhkan ini juga; solusi saya adalah menggunakan SQLYOG (versi gratis) untuk mengekspor catatan yang diinginkan sebagai SQL (membuat sisipan).
Saya kemudian mengedit tangan ini untuk menghapus id karena ini perlu dibuat secara otomatis dan kemudian menyalin sisipan ke SQLYog untuk menjalankannya. Ini tidak menyakitkan. Saya kira banyak GUI MySQL lain yang dapat melakukan ini juga.
Ini memberi saya catatan yang dapat saya gunakan untuk tujuan pengujian pada sistem langsung.
Sekarang saya memiliki sisipan ini untuk digunakan kembali juga, karena tabel ditulis ulang setiap hari.
sumber
Sedikit variasi, perbedaan utamanya adalah menyetel bidang kunci utama ("varname") ke null, yang menghasilkan peringatan tetapi berfungsi. Dengan menyetel kunci utama ke null, penambahan otomatis berfungsi saat memasukkan record di pernyataan terakhir.
Kode ini juga membersihkan upaya sebelumnya, dan dapat dijalankan lebih dari sekali tanpa masalah:
DELETE FROM `tbl` WHERE varname="primary key value for new record"; DROP TABLE tmp; CREATE TEMPORARY TABLE tmp SELECT * FROM `tbl` WHERE varname="primary key value for old record"; UPDATE tmp SET varname=NULL; INSERT INTO `tbl` SELECT * FROM tmp;
sumber
Anda dapat mengubah tabel sementara untuk mengubah bidang ID menjadi bigint atau lebih tanpa persyaratan NOT NULL, kemudian mengatur ID ke 0 dalam tabel temp itu. Setelah itu tambahkan kembali ke tabel asli dan NULL akan memicu kenaikan otomatis.
CREATE TEMPORARY TABLE tmptable SELECT * FROM x WHERE (id='123'); ALTER TABLE tmptable CHANGE id id bigint; UPDATE tmptable SET id = NULL; INSERT INTO x SELECT * FROM tmptable;
sumber