MySQL'de, aynı tabloya eklemek için bir satırı kopyalayabilir miyim?


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

Ben sadece aynı tabloya eklemek için bir satır kopyalamak istiyorum (yani, tablodaki varolan bir satırı çoğaltmak istiyorum) ama bu tabloyu "seçin" sonra tüm sütunları listelemek zorunda kalmadan yapmak istiyorum çok fazla sütun var.

Ama bunu yaptığımda hatayı alıyorum:

Anahtar 1 için yinelenen giriş 'xxx'

Kopyalamak istediğim kayıt için geçici bir kapsayıcıyla aynı sütunlara sahip başka bir tablo oluşturarak bunu halledebilirim:

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;

Bunu çözmenin daha basit bir yolu var mı?


Anahtarın sabit kodlanmış değerleri hakkında bir yorumum var. Ben böyle bir şey yapmak istiyorum max(oldtable.id) + oldtable_temp.keyids artış ve benzersiz olduğundan emin olun.
guy mograbi


@OrganicAdvocate, bu sorudan daha fazla cevap ve daha fazla görünüme sahip
Drew

Yanıtlar:


189

Leonard Challis'in tekniğini birkaç değişiklikle kullandım:

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;

Geçici tablo olarak, asla birden fazla kayıt olmamalıdır, bu nedenle birincil anahtar hakkında endişelenmenize gerek yoktur. Null değerine ayarlamak, MySQL'in değerin kendisini seçmesine izin verir, bu nedenle kopya oluşturma riski yoktur.

Eklemek için yalnızca bir satır alacağınızdan emin olmak istiyorsanız, INSERT INTO satırının sonuna LIMIT 1 ekleyebilirsiniz.

Geçici anahtar adıma da birincil anahtar değerini (bu örnekte 1) eklediğimi unutmayın.


3
Bu çözüm, MySQL'in birincil anahtar değerini seçmesine izin vermesi bakımından (oy kullanan diğer bazı çözümlerin aksine) doğrudur.
Jan Hettich

1
Rağmen tam olarak tutarsız geçici tablo isimleri ( tmptable_1vs. tmptable) gibi çalışmaz
Kieran Tully

9
Birincil anahtar nasıl boş olabilir?
Imran Shafqat

5
Boşsa, yerleştirildiğinde otomatik olarak bir sonraki AI numarasını atar.
Grim ...

3
IMRAN - isteyebilirsiniz. Belki de geçici tablonun id alanı otomatik olarak bir PK yapılmadı düşündüm (SQL Server bu durumlarda bunu yapmaz eminim) ama öyle. ALTER TABLE yapmam gerekiyordu tmptable_1 primarykeyINT NULL DEĞİŞTİR ; çözüm yapmak için ilk satırdan sonra
DJDave

61

Güncelleme 07/07/2014 - Grim ... tarafından verilen cevabımın cevabı aşağıdaki çözümümde daha iyi olduğu için daha iyi bir çözüm, bu yüzden bunu kullanmanızı öneririm.

Bunu, aşağıdaki sözdizimiyle tüm sütunları listelemeden yapabilirsiniz:

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;

Birincil anahtarı başka bir şekilde değiştirmeye karar verebilirsiniz.


16
Bu temelde OP'nin gerçek sıcaklık tabloları ile de olsa kendi problemleri için zaten sağladıklarıyla aynı çözümdür ve biraz daha temiz desen oluşturur. Bence OP halihazırda kullandıklarına daha iyi bir yaklaşım istedi , varolan sözdiziminin temizlenmesi değil. Bunun için tüm oyları gerçekten anlama.
Sepster

Teşekkür ederim. Dinamik işlevi ile iyi gidiyor
Sonal Khunt

Bu işlem bittikten sonra tmptable'ı silmek gerekli mi?
SSH Bu

"Varsayılan olarak, tüm geçici tablolar veritabanı bağlantınız sonlandırıldığında MySQL tarafından silinir. Hala aralarında silmek istediğinizde DROP TABLE komutu vererek bunu yaparsınız." Daha fazlası için
LeonardChallis

Oluşturduğunuz göz önüne alındığında , son satır için de ifade tmptableeklemenize gerek yoktur WHERE primarykey = 2. (Yani, sadece INSERT INTO table SELECT * FROM tmptable.)
Marcus

42

Ben Yeni albümünü yeni olmasını istediğiniz varsayarak yaşıyorum primarykey? Eğer primarykeybir AUTO_INCREMENTsonra sadece bunu:

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

... col1, col2, col3, ...tablo dışındaki tüm sütunlar nerede primarykey?

Bu bir AUTO_INCREMENTsütun değilse ve primarykeybenzer olduğu için yeni değeri seçebilmek istiyorsanız :

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

... 567yeni değeri nerede primarykey.


41
Bu, soruyu görmezden geldiğinde 7 kez nasıl değerlendirilir? ... ama ben "select" sonra tüm sütunları listelemek istemiyorum, çünkü bu tablo çok fazla sütun var ...
LeonardChallis

7
-1 tam olarak OP'nin kaçınmak istediği şeydir. Soruyu okuyun veya en azından "mümkün olan tek yol bu" gibi bir cevap verin.
devios1

5
Çünkü bazen sorunun kendisi yanlıştır. :) İçeriği değiştirmeden satırları çoğaltmak artıklığı artırır. Mümkünse yedekliliği en aza indirmek için veritabanı yapısının değiştirilmesi önerilir.
Torben

5
Normal uygulamalarda doğru olmaması, yanlış yapmaz. Standart en iyi uygulamaların uygulanmadığı birçok zaman vardır. Örnek: veritabanı belgeleri temsil eder ve kullanıcının değişiklik yapmadan önce belgenin bir kopyasını koruması gerekir.
ima747

6
Çünkü bu sayfaya OP ile tam olarak aynı şekilde istemeyebilirsiniz
jx12345

13

Neredeyse ilk sorgunuzda, sütunları belirtmeniz yeterlidir; girişi.

Örneğin bunu değiştirin:

insert into table select * from table where primarykey=1

Buna:

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

Birincil anahtar sütununu INSERT veya sorgunun SELECT bölümleri için sütun listesine eklemeyin.


1
sütunların çoğunu select deyiminden almanın ancak insert komutunda bunlardan birini manuel olarak güncellemenin bir yolu var mı? gibi insert into table ("val1", col2, col3) select col2, col3 from table where primarykey = 1ya da benzer bir şey?
anon58192932

1
Buldum! Değerleri bir satırdan kopyalayın, ancak kendi değerlerinizden birini ekleme deyimine ekleyin: stackoverflow.com/questions/23971078/…
anon58192932

1
Üzgünüm sorularınız hakkında bilgilendirildi, bulduğunuza sevindim, gerçekten de bu.
Braeden Black

9

Ayrıca tabloyu dökmeyi, insert komutunu bulmayı ve düzenlemeyi deneyebilirsiniz:

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

--skip-extended-insertSize satıra bir insert komutu verir. Daha sonra satırı favori metin düzenleyicinizde bulabilir, komutu çıkarabilir ve birincil anahtarı "varsayılan" olarak değiştirebilirsiniz.


2
Bu, bazı durumlarda çalışma süresi dışında gerçekten yararlı olabilecek iyi bir "kutunun dışında" yaklaşımı olduğundan benden +1. Ama öncelikle OP'nin sorusunu ele alan ve OP tarafından halihazırda sağlanan çözümü sözdizimsel olarak değiştirmeyen ilk cevaptır.
Sepster

6

Bu prosedür aşağıdakileri varsaymaktadır:

  • _duplicate_temp_table yok
  • birincil anahtarınız int
  • tablo oluşturma erişiminiz var

Tabii ki bu mükemmel değil, ancak bazı (muhtemelen çoğu) durumda işe yarayacak.

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;

1
+1 Bunu doğrulamamış worksama yaklaşım sağlam ve değerlidir çünkü burada benzersizdir ve aslında OP'nin sorusunu ele alır.
Sepster

5

Bu, bazı yaratıcılıklarla başarılabilir:

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;

Bu, yeni satırın seçilen satırdaki kimlik yerine otomatik olarak artan bir kimlik almasına neden olur.


Bu kabul edilen cevap olmalı!
Felipe Desiderati

5

Tablonuzun birincil anahtar alanı bir otomatik artış alanı ise, sütun içeren sorguyu kullanabilirsiniz. Örneğin, adlı tablonuzun test_tbl3 alanı vardır id, name, age. idbirincil anahtar alanı ve otomatik artıştır, bu nedenle satırı çoğaltmak için aşağıdaki sorguyu kullanabilirsiniz:

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

Bu sorgu her satırı çoğaltmakla sonuçlanır.


Tablonuzun birincil anahtar alanı bir otomatik artış alanı değilse, aşağıdaki yöntemi kullanabilirsiniz:

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

Bu sorgunun sonucu, yinelenen olarak id=19eklenen bir satırdır id=20.


Durum böyle oldukça basittir, en iyi yanıt olduğunu edilir: INSERT INTO tableName( fieldName1, fieldName2, fieldName3) SEÇ fieldName1, fieldName2, fieldName3İTİBAREN tableName1 (bir defada hepsini kopyalamak için) NEREDE
jakubplus

İkincisi - bu cevap özlüdür ve aslında bir satırı "Kopyalamak" ruhudur.
user37309

4

güncelleme alanları ve otomatik artış değeri olan klon satırı

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

@Torben Herkesin sizin için çalıştığını bilmesi için lütfen sorunun solundaki onay işaretini kontrol edin (kabul edildi olarak işaretleyin).
HosseyNJF

3

Aşağıdakilerden bazıları bu siteden çıkarılmıştır. Bu, herhangi bir sayıda alan içeren bir tablodaki bir kaydı çoğaltmak için yaptığım şey:

Bu, tablonun başında bir AI alanınız olduğunu varsayar.

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
}

3

Grim'in tekniğini küçük bir değişiklikle kullandım: Birisi bu sorguyu arayan, birincil anahtar sorunu nedeniyle basit bir sorgu yapamayacağı için:

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

MySql kurulum 5.6.26 ile anahtar boş bırakılamaz ve bir hata oluşturur:

#1048 - Column 'primakey' cannot be null 

Bu yüzden geçici tablo oluşturduktan sonra birincil anahtarı boş değer olarak değiştiririm.

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;

alternatif olarak yeni mariadb / mysql sürümlerinde birincilKey 0 değerine ayarlanabilir, bu da otomatik artışın yerleştirildiğinde çalışmasını sağlar.
shelbypereira

2

Buna geç kalabilirim, ama benim için çalışan benzer bir çözümüm var.

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

Bu şekilde geçici bir tablo ve benzeri oluşturmak gerek yok. Satır aynı tabloya kopyalandığı için Max(PK)+1işlev kolayca kullanılabilir.

Bu sorunun çözümünü aradım (sözdizimini unutmuştum) ve kendi sorgumu yaptım. Bazı şeylerin nasıl işlediğini komik.

Saygılarımızla


2

Birincil Anahtar Otomatik Artış ise, birincil anahtar hariç her alanı belirtin.

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


2

@ LeonardChallis'in çözümünü güncelledim, çünkü diğerleri için hiç işe yaramadı. Kaldırılacak WHEREmaddeleri ve SET primaryKey = 0MySQL otomatik artışlarla kendisi primaryKey böylece geçici tabloda

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

Bu elbette tablodaki tüm satırları çoğaltmak içindir .


2

Aşağıda kullanırdım,

insert into ORDER_ITEM select * from ORDER_ITEM where ITEM_NUMBER =123;

1
ITEM_NUMBER birincil anahtarınız ise, bu durumda olması muhtemel değildir.
Billy Pilgrim

2

Koha veritabanımda barkod sütununda 'C' öneki ile yinelenen öğeler eklemek için kullandım :

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

1

Sadece bunu yapmak zorunda kaldım ve bu benim manuel çözümümdü:

  1. In phpmyadmin , sen kopya isteyen satırı kontrol
  2. Sorgu sonucu işlemlerinin altındaki 'Dışa Aktar'ı tıklayın
  3. Sonraki sayfada 'Dosya olarak kaydet'i işaretleyin ve ' Git'i tıklayın
  4. Dışa aktarılan dosyayı bir metin düzenleyicisiyle açın, birincil alanın değerini bulun ve benzersiz bir şeye değiştirin.
  5. Geri içinde phpmyadmin tıklama 'İthal' sekmesi altında .sql dosyasını almak için dosyayı bulmak browse tıklayın 'Git' ve yinelenen satır yerleştirilmelidir.

Ne bilmiyorsanız İLKÖĞRETİM alanına, bakmak geri phpmyadmin , sayfayı tıklayın 'Yapı' sekmesinin altında sayfanın alt kısmında Endeksleri ' hangi gösterecektir 'Alan' a sahiptir 'Keyname' değeri 'PRIMARY' .

Biraz uzun bir yol var, ama işaretleme ile uğraşmak istemiyorsanız ve sadece tek bir satırı çoğaltmanız gerekiyorsa gidin.


Güzel, op'u kutudan çıkmış bir şekilde cevaplar. Açıkçası, lekeler ve jeo-uzamsal veriler gibi tüm durumlar için çalışmaz, ancak çekilmesi oldukça kolaydır ve bu garip top değişiklikleri için çalışır.
Strixy

1

Bu çözüm yukarıda seçilen satırlar için de mükemmel çalıştığını gösterdi. Örneğin nice2work projem için gösteri satırları oluşturuyorum ve bu mükemmel çalışıyor.

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

0

Necropost için özür dilerim ama bu google ile ortaya çıktı ve bu yararlı ama sorunlu bulduğumdan beri, bu kazı yapan herkes için önemli bir modifikasyona katkıda bulunmak istedim.

Öncelikle, MySQL değil SQL Server kullanıyorum, ancak benzer şekilde çalışması gerektiğini düşünüyorum. Leonard Challis'in çözümünü kullandım çünkü en basitti ve ihtiyacı karşıladı, ancak bununla ilgili bir sorun var - sadece PK'yi alıp 1'e çıkarırsanız, söz konusu satır eklendiğinden beri başka kayıtlar eklediyseniz ne olur? . Sistemin PK'nin otomatik büyümesini gerçekleştirmesine izin vermenin en iyisi olduğuna karar verdim, bu yüzden aşağıdakileri yaptım:

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

Bunun MySQL'de benzer şekilde çalışacağına inanıyorum, ancak bunu test edemiyorum, üzgünüm


1
tamamen bakwaas cevap
AsadYarKhan

0

Eski bir soru olduğunu biliyorum, ama işte başka bir çözüm:

Bu, birincil anahtarın otomatik olarak artırıldığı varsayılarak ana tablodaki bir satırı çoğaltır ve yeni ana tablo kimliğiyle bağlantılı tablo verilerinin kopyalarını oluşturur.

Sütun adlarını almak için diğer seçenekler:
-SONUN KOLONLARINI GÖSTER tablename; (Sütun adı: Alan)
-DESCRIBE tablename (Sütun adı: Alan)
-SONECT sütun_adı FROM information_schema.columns NEREDE table_name = 'tablename' (Sütun adı: sütun_adı)

//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__);
}

0

max233 kesinlikle en azından otoyol durumu için doğru yoldaydı. Ancak, ALTER TABLOSU yapmayın. Geçici tablodaki otomatik artış alanını NULL olarak ayarlamanız yeterlidir. Bu bir hata görüntüler, ancak geçici tablodaki tüm alanların aşağıdaki INSERT ifadesi gerçekleşir ve NULL otomatik alanı benzersiz bir değer elde eder.


0

Tablo oluşturma

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

Satır ekle

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

Yukarıdaki klon satırı eki

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;

Ölçek

SELECT * FROM `sample_table`;

Not: Hata alıyorsanız (# 1048) NULL yerine '' kullanın
Abdullah Aydın

Sadece ben mi yoksa OP'nin tam olarak istemediği şey bu mu? (Sorguya her sütunu manuel olarak ekliyoruz.)
Byson

Haklısın, sadece OP'nin "Ben sadece aynı tabloya eklemek için bir satır kopyalamak istiyorum" cümlesini okudum, belki, yine de bu yine de "Yinelenen giriş 'xxx' için anahtar ???" hata ^^
Abdullah Aydın

0

İşte bu sitede çevrimiçi bulduğum bir cevap Yukarıda nasıl yapılacağını açıklar 1 Cevabı sayfanın altında bulabilirsiniz. Temel olarak, yaptığınız şey kopyalanacak satırı bellekte tutulan geçici bir tabloya kopyalamaktır. Daha sonra, güncellemeyi kullanarak Birincil Anahtar numarasını değiştirin. Daha sonra hedef tabloya yeniden ekleyin. Sonra masayı bırakın.

Bunun kodu:

GEÇİCİ TABLO OLUŞTURMA rescueteamMOTORU = BELLEK SEÇİMİ * fitnessreport4RID = 1'DEN; 1 numaralı satır etkilenir. GÜNCELLEME rescueteamSET kurtulmak = null = 1 kurtulmak NEREDE; # 1 satır affected.INSERT INTO fitnessreport4SELECT * rescueteam; # 1 satır etkiledi. DROP TABLE rescueteam# MySQL boş bir sonuç kümesi döndürdü (örn. Sıfır
satır).

Geçici tablo kurtarma ekibini oluşturdum. Satırı orijinal tablo fitnessreport'umdan kopyaladım4. Daha sonra geçici tablodaki satırın birincil anahtarını null olarak ayarladım, böylece Yinelenen Anahtar hatası almadan orijinal tabloya geri kopyalayabilirim. Dün akşam bu kodu denedim ve işe yaradı.


0

Bu, "Grim ..." tarafından verilen cevaba ek bir çözümdür. Bu konuda bazı yorumlar çalışmıyor. Ve çözümler hakkında bazı yorumlar. Çözümlerin hiçbiri bizim için işe yaramadı. InnoDB tablosunda MariaDB var.

Birincil anahtarı null değerine izin verecek şekilde ayarlayamadık. NULL yerine 0 kullanılması, birincil anahtar için yinelenen değer hatasına yol açtı. SET SQL_SAFE_UPDATES = 0;Ya da işe yaramadı.

"Grim ..." nin çözümü, PRİMARY ANAHTARIMIZI EŞSİZ olarak değiştirdiğimizde işe yaradı


-1

Ben sadece PHP kod parçamı göndermek istedim, çünkü ben sütunları toplama yolu önceki örneklere göre kod biraz daha temiz olduğunu düşünüyorum. Ayrıca bu, bir alanı nasıl kolayca değiştirebileceğinizi gösterir, bu durumda bir dize ekler. Ancak, bazı alt kayıtları da kopyalamak istiyorsanız, yabancı anahtar alanını yeni eklenen kayıtla da değiştirebilirsiniz.

  // 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();

-2

Çok basit bir çözüm için, satırı CSV dosyası olarak dışa aktarmak için PHPMyAdmin'i kullanabilir ve sonra değiştirilmiş CSV dosyasını içe aktarabilirsiniz. Kimlik / birincil anahtar sütununu içe aktarmadan önce değer göstermeyecek şekilde düzenleme.

SELECT * FROM table where primarykey=1

Ardından sayfanın altında:

resim açıklamasını buraya girin

"Dışa Aktar" ifadesi yalnızca dışa aktarılır, daha sonra birincil anahtar değerini kaldırmak için csv dosyasını düzenler, böylece boş olur ve daha sonra veritabanına içe aktarılır, içe aktarma sırasında yeni bir birincil anahtar atanır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.