В MySQL я могу скопировать одну строку, чтобы вставить в ту же таблицу?


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

Я просто хочу скопировать одну строку для вставки в ту же таблицу (т.е. я хочу дублировать существующую строку в таблице), но я хочу сделать это без необходимости перечислять все столбцы после «select», потому что эта таблица имеет слишком много столбцов.

Но когда я делаю это, я получаю ошибку:

Дублирующая запись 'xxx' для ключа 1

Я могу справиться с этим, создав другую таблицу с теми же столбцами, что и временный контейнер для записи, которую я хочу скопировать:

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;

Есть ли более простой способ решить эту проблему?


У меня просто есть комментарий о жестко закодированных значениях ключа. Я хотел бы сделать что-то вроде max(oldtable.id) + oldtable_temp.keyэтого, чтобы убедиться, что идентификатор увеличивается и является уникальным.
парень mograbi


У @OrganicAdvocate больше ответов и больше мнений, чем на этот вопрос
Дрю

Ответы:


189

Я использовал технику Леонарда Чаллиса с некоторыми изменениями:

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;

В качестве временной таблицы никогда не должно быть более одной записи, поэтому вам не нужно беспокоиться о первичном ключе. Установка его в null позволяет MySQL выбирать само значение, поэтому нет риска создания дубликата.

Если вы хотите быть уверены, что вставляете только одну строку, вы можете добавить LIMIT 1 в конец строки INSERT INTO.

Обратите внимание, что я также добавил значение первичного ключа (в данном случае 1) к имени моей временной таблицы.


3
Это решение является правильным (в отличие от некоторых других, набравших голоса), поскольку оно позволяет MySQL выбирать значение первичного ключа.
Ян Хеттих

1
Хотя не будет работать точно так, как это происходит из-за несовместимых имен временных таблиц ( tmptable_1против tmptable)
Киран Талли

9
Как первичный ключ может быть нулевым?
Имран Шафкат

5
Если он нулевой, ему автоматически присваивается следующий номер AI, когда он вставляется.
Мрачно ...

3
IMRAN - вы можете спросить. Я подумал, что, возможно, поле id временной таблицы не было автоматически преобразовано в PK (я почти уверен, что SQL Server этого не делает), но это так. Мне нужно было сделать ALTER TABLE tmptable_1 MODIFY primarykeyINT NULL; после первой строки, чтобы заставить решение работать
DJDave

61

Обновление 07/07/2014 - Ответ, основанный на моем ответе Grim ... , является лучшим решением, поскольку он улучшает мое решение ниже, поэтому я бы предложил использовать его.

Вы можете сделать это, не перечисляя все столбцы со следующим синтаксисом:

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;

Вы можете решить изменить первичный ключ другим способом.


16
Это в основном то же решение, которое OP уже предоставил для их собственной проблемы, хотя и с фактическими временными таблицами, и немного более чистым шаблоном создания. Я думаю, что ОП попросил лучшего подхода к тому, что они уже использовали, а не для очистки их существующего синтаксиса. Не очень понимаю все противники этого.
сентября

Спасибо. Это хорошо
сочетается

Нужно ли удалять tmptable после завершения этого процесса?
SSH это

«По умолчанию все временные таблицы удаляются MySQL, когда ваше соединение с базой данных прерывается. Тем не менее, вы хотите удалить их в промежутке, а затем сделать это с помощью команды DROP TABLE». Больше здесь
Леонард Чаллис

Учитывая, что вы создали tmptable, вам не нужно добавлять WHERE primarykey = 2оператор для последней строки. (Т.е. просто INSERT INTO table SELECT * FROM tmptable.)
Маркус

42

Я предполагаю, что вы хотите, чтобы новая запись имела новую primarykey? Если primarykeyэто так, AUTO_INCREMENTпросто сделайте это:

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

... где col1, col2, col3, ...все столбцы в таблице, кроме primarykey .

Если это не AUTO_INCREMENTстолбец, и вы хотите иметь возможность выбрать новое значение для primarykeyнего аналогично:

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

... где 567новое значение для primarykey.


41
Как получается, что за это проголосовали 7 раз, когда он игнорирует вопрос? ... но я не хочу перечислять все столбцы после "select", потому что в этой таблице слишком много столбцов ...
LeonardChallis

7
-1 так как именно этого ОП хочет избежать. Прочтите вопрос или, по крайней мере, предложите ответ типа «это единственный возможный путь».
devios1

5
Потому что иногда сам вопрос неверен. :) Дублирование строк без изменения содержимого увеличивает избыточность. Рекомендуется изменить структуру базы данных для минимизации избыточности, если это возможно.
Торбен

5
То, что это не правильно в обычной практике, не делает это неправильно. Существует множество случаев, когда стандартные лучшие практики не применяются. Пример: база данных представляет документы, и пользователь должен сохранить копию документа перед внесением изменений.
ima747

6
Потому что вы можете
попасть

13

Вы почти получили его с первым запросом, вам просто нужно указать столбцы. Таким образом, вы можете исключить свой первичный ключ из вставки, который применит автоматическое приращение, которое вы, вероятно, имеете в таблице, чтобы автоматически создать новый первичный ключ для запись.

Например, измените это:

insert into table select * from table where primarykey=1

К этому:

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

Просто не включайте столбец primarykey ни в список столбцов для INSERT, ни для SELECT-частей запроса.


1
Есть ли способ получить большинство столбцов через оператор выбора, но обновить один из них вручную в команде вставки? например insert into table ("val1", col2, col3) select col2, col3 from table where primarykey = 1или что-то подобное?
anon58192932

1
Нашел это! Скопируйте значения из одной строки, но добавьте одно из ваших собственных значений в оператор вставки: stackoverflow.com/questions/23971078/…
anon58192932

1
Извините, только что получил уведомление о ваших вопросах, рад, что вы нашли его, это действительно так.
Брейден Блэк

9

Вы также можете попробовать сбросить таблицу, найти команду вставки и отредактировать ее:

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

Это --skip-extended-insertдает вам одну команду вставки на строку. Затем вы можете найти строку в вашем любимом текстовом редакторе, извлечь команду и изменить первичный ключ на «default».


2
+1 от меня, так как это хороший подход «нестандартно», который может быть полезен вне времени выполнения, в некоторых обстоятельствах. Но в первую очередь это первый ответ, который фактически затрагивает вопрос ОП, а не просто синтаксически подправляет решение, уже предоставленное ОП.
Sepster

6

Эта процедура предполагает, что:

  • у вас нет _duplicate_temp_table
  • Ваш первичный ключ - int
  • у вас есть доступ к созданию таблицы

Конечно, это не идеально, но в определенных (возможно, в большинстве) случаях это будет работать.

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 Не подтвердил это, worksно подход обоснован и имеет ценность, потому что здесь он уникален и действительно отвечает на вопрос ОП.
Sepster

5

Это может быть достигнуто с некоторой креативностью:

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;

Это приведет к тому, что новая строка получит автоматически увеличенный идентификатор вместо идентификатора из выбранной строки.


Это должен быть принятый ответ!
Фелипе Дезидерати

5

Если поле первичного ключа вашей таблицы является полем с автоинкрементом, то вы можете использовать запрос со столбцами. Например, ваша именованная таблица test_tblимеет 3 поля как id, name, age. idявляется полем первичного ключа и автоматическим приращением, поэтому вы можете использовать следующий запрос для дублирования строки:

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

Этот запрос приводит к дублированию каждой строки.


Если поле первичного ключа вашей таблицы не является полем с автоматическим приращением, вы можете использовать следующий метод:

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

Результатом этого запроса является дубликат строки, id=19вставленный как id=20.


Это самый лучший ответ есть, случай довольно прост: INSERT INTO tableName( fieldName1, fieldName2, fieldName3) ВЫБРАТЬ fieldName1, fieldName2, fieldName3FROM tableNameWHERE 1 (скопировать все из них сразу)
jakubplus

Seconded - этот ответ лаконичен и в духе «копирования» строки.
user37309

4

строка клона с полями обновления и значением автоинкремента

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 Пожалуйста, отметьте галочку слева от вопроса (отметьте его как принятый), чтобы все знали, что это работает для вас.
HosseyNJF

3

Некоторые из следующего были почерпнуты из этого сайта. Вот что я сделал, чтобы дублировать запись в таблице с любым количеством полей:

Это также предполагает, что у вас есть поле ИИ в начале таблицы

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

Я использовал технику Гримса с небольшим изменением: если кто-то ищет этот запрос, потому что не может выполнить простой запрос из-за проблемы первичного ключа:

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

С моей установкой MySql 5.6.26 ключ не обнуляется и выдает ошибку:

#1048 - Column 'primakey' cannot be null 

Поэтому после создания временной таблицы я изменяю первичный ключ на обнуляемый.

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;

альтернативно, в новых версиях mariadb / mysql primaryKey может быть установлен в 0, что позволяет автоинкременту работать при вставке.
Шелбыперейра

2

Я мог бы опоздать в этом, но у меня есть подобное решение, которое сработало для меня.

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

Таким образом, мне не нужно создавать временную таблицу и т. Д. Поскольку строка копируется в ту же таблицу, Max(PK)+1 функцию можно легко использовать.

Я искал решение этого вопроса (забыл синтаксис) и закончил тем, что сделал свой собственный запрос. Забавно, как все получается несколько раз.

С уважением


2

Если первичным ключом является автоинкремент, просто укажите каждое поле, кроме первичного ключа.

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


2

Я обновил решение @ LeonardChallis, так как оно не сработало для меня, как никто другой. Я удалил WHEREпункты и SET primaryKey = 0во временной таблице, поэтому MySQL автоматически увеличивает значение primaryKey

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

Это, конечно, дублировать все строки в таблице.


2

Я бы использовал ниже,

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

1
Это не работает, если ITEM_NUMBER является вашим основным ключом, что вероятно в этой ситуации.
Билли Пилигрим

2

Я использовал в своей базе данных Koha для вставки повторяющихся элементов с префиксом 'C' в столбце штрих-кода :

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

1

Я просто должен был сделать это, и это было мое ручное решение:

  1. В phpmyadmin проверьте строку, которую вы хотите скопировать
  2. Внизу под запросом результатов операции нажмите «Экспорт».
  3. На следующей странице отметьте «Сохранить как файл», затем нажмите «Перейти».
  4. Откройте экспортированный файл в текстовом редакторе, найдите значение основного поля и измените его на нечто уникальное.
  5. Вернуться в phpmyadmin нажмите на «Импорт» вкладку , найдите файл для импорта .sql файла в разделе « Обзор» , нажмите «Перейти», и необходимо вставить дублирующую строку.

Если вы не знаете, что такое поле PRIMARY , посмотрите на свою страницу phpmyadmin , нажмите на вкладку «Структура» и в нижней части страницы под «Индексами» будет показано, какие поле имеет «Keyname». значение «ПЕРВИЧНОЕ» .

Это довольно долгий путь, но если вы не хотите иметь дело с разметкой и вам просто нужно дублировать один ряд, то вы идете.


Ницца, отвечает на вопрос в оригинальном виде. Понятно, что он работает не во всех случаях, таких как большие двоичные объекты и геопространственные данные, но довольно прост в использовании и работает для тех странных изменений шара.
Strixy

1

Это решение, показанное выше, прекрасно работает и для выбранных рядов. Например, я создаю демонстрационные ряды для своего проекта nice2work, и это прекрасно работает.

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

Извините за некропост, но это то, что я обнаружил в Google, и так как я нашел это полезным, но проблематичным, я хотел внести важную модификацию для всех, кто копает это.

Во-первых, я использую SQL Server, а не MySQL, но я думаю, что он должен работать аналогично. Я использовал решение Леонарда Чаллиса, потому что оно было самым простым и отвечало потребностям, однако есть проблема с этим - если вы просто возьмете PK и увеличите его на 1, то что произойдет, если вы добавили другие записи после добавления рассматриваемой строки , Я решил, что лучше всего позволить системе обрабатывать автоинкремент PK, поэтому я сделал следующее:

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

Я считаю, что это будет работать аналогично в MySQL, но я не могу проверить это, извините


1
полностью ответ Бакваас
AsadYarKhan

0

Я знаю, что это старый вопрос, но вот другое решение:

Это дублирует строку в основной таблице, предполагая, что первичным ключом является автоинкремент, и создает копии данных связанных таблиц с новым идентификатором основной таблицы.

Другие варианты получения имен столбцов: -
ПОКАЗАТЬ КОЛОННЫ ИЗ tablename; (Имя столбца: поле)
-DESCRIBE tablename (Имя столбца: поле)
-SELECT имя- столбца FROM information_schema.columns WHERE table_name = 'tablename' (Имя столбца: 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__);
}

0

max233, безусловно, был на правильном пути, по крайней мере, для случая автоинкремента. Однако не делайте ALTER TABLE. Просто установите поле автоинкремента во временной таблице в NULL. Это приведет к ошибке, но произойдет следующая INSERT для всех полей во временной таблице, и автоматическое поле NULL получит уникальное значение.


0

Создать таблицу

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

Вставить строку

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

Вставить строку клона выше

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;

Тест

SELECT * FROM `sample_table`;

Примечание: если вы получаете ошибку (# 1048), используйте '' вместо NULL
Абдулла Айдын

Это только я или это именно то , чего ОП не хотел? (Т.е. вручную добавляя каждый столбец к запросу.)
Бисон

Вы правы, я только что прочитал предложение ОП "Я просто хочу скопировать одну строку для вставки в одну и ту же таблицу", возможно, в любом случае это все еще полезно для "Дублирующая запись 'xxx' для ключа ???" ошибка ^^
Абдулла Айдын

0

Вот ответ, который я нашел в Интернете на этом сайте Описывает, как сделать выше 1 Ответ вы можете найти в нижней части страницы. По сути, вы копируете строку, которая будет скопирована во временную таблицу, хранящуюся в памяти. Затем вы меняете номер первичного ключа, используя обновление. Затем вы снова вставляете его в целевую таблицу. Затем вы бросаете стол.

Вот код для этого:

СОЗДАТЬ ВРЕМЕННЫЙ СТОЛ rescueteamДВИГАТЕЛЬ = ВЫБОР ПАМЯТИ * ОТ fitnessreport4ГДЕ rID = 1; затронута строка # 1. ОБНОВЛЕНИЕ rescueteamУСТАНОВЛЕНО rID = Null ГДЕ rID = 1; затронута строка # 1. ВСТАВЬТЕ В fitnessreport4ВЫБОР * ИЗ rescueteam; DROP TABLE rescueteam# MySQL вернул пустой набор результатов (т. Е. Ноль
строк).

Я создал временную таблицу rescueteam. Я скопировал строку из моей исходной таблицы fitnessreport4. Затем я устанавливаю нулевой первичный ключ для строки во временной таблице, чтобы я мог скопировать его обратно в исходную таблицу без получения ошибки Duplicate Key. Я попробовал этот код вчера вечером, и он работал.


0

Это дополнительное решение к ответу "Grim ...". Было несколько комментариев по поводу того, что первичный ключ имеет значение null. Некоторые комментарии по этому поводу не работают. И некоторые комментарии по решениям. Ни одно из решений не сработало для нас. У нас есть MariaDB с таблицей InnoDB.

Мы не могли установить первичный ключ, чтобы позволить нуль. Использование 0 вместо NULL привело к ошибке дублированного значения для первичного ключа. SET SQL_SAFE_UPDATES = 0;Тоже не сработало.

Решение от "Grim ..." сработало, если вместо этого мы изменили наш ПЕРВИЧНЫЙ КЛЮЧ на УНИКАЛЬНЫЙ


-1

Просто хотел опубликовать свой кусок кода PHP, потому что я думаю, что способ сбора столбцов немного чище в коде, чем в предыдущих примерах. Также это показывает, как вы можете легко изменить поле, в этом случае добавив строку. Но вы также можете заменить поле внешнего ключа на вновь добавленную запись, если вы хотите скопировать некоторые дочерние записи.

  // 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

Для очень простого решения вы можете использовать PHPMyAdmin для экспорта строки в виде файла CSV, а затем просто импортировать исправленный файл CSV. Редактирование столбца ID / primarykey, чтобы не показывать значения перед его импортом.

SELECT * FROM table where primarykey=1

Тогда внизу страницы:

введите описание изображения здесь

Где написано «Экспорт», просто экспортируйте, затем отредактируйте файл csv, чтобы удалить значение первичного ключа, чтобы оно было пустым, а затем просто импортируйте его в базу данных, при импорте будет назначен новый первичный ключ.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.