Чи можу я скопіювати один рядок у MySQL до однієї таблиці?


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

Я просто хочу скопіювати один рядок, який потрібно вставити в ту саму таблицю (тобто, я хочу дублювати існуючий рядок у таблиці), але я хочу це зробити, не перераховуючи всі стовпці після "вибору", оскільки ця таблиця має занадто багато стовпців.

Але коли я це роблю, я отримую помилку:

Дублікат запису "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таким чином, я переконуюсь, що приріст ідентифікаторів і унікальний.
guy 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;

Як тимчасова таблиця, ніколи не повинно бути більше одного запису, тому вам не доведеться турбуватися про первинний ключ. Встановлення його в нульове значення дозволяє MySQL сам вибирати значення, тому немає ризику створити дублікат.

Якщо ви хочете бути впевненими, вам потрібно вставити лише один рядок, ви можете додати LIMIT 1 до кінця рядка INSERT INTO.

Зауважте, що я також додав значення первинного ключа (1 у цьому випадку) до моєї імені тимчасової таблиці.


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

1
Хоча це не буде працювати точно так, як це пов’язано з непослідовними назвами тимчасових таблиць ( tmptable_1проти tmptable)
Kieran Tully

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

5
Якщо він недійсний, він автоматично присвоює наступний номер AI, коли він вставлений.
Похмурий ...

3
ІМРАН - ви можете запитати. Я подумав, що, можливо, поле id тимчасової таблиці не було автоматично створено ПК (я впевнений, що SQL Server не робить цього в цих умовах), але це так. Мені потрібно було ВИНИКНУТИ ТАБЛИЦЮ tmptable_1 МОДИФІКУВАТИ НУЛЬ primarykey; після першого рядка, щоб вирішити роботу
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
Це, в основному, те саме рішення, що ОР вже передбачало власну проблему, хоча і з фактичними таблицями темп, і трохи чіткіше створюють модель. Я думаю, що ОП попросила кращого підходу до того, що вони вже використовували, а не очищення існуючого синтаксису. Не дуже розумію всі відгуки на це.
Сепстер

Дякую. Це добре поєднується з динамічною функцією
Sonal Khunt

Чи потрібно видалити 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 разів, коли воно ігнорує питання? ... але я не хочу перераховувати всі стовпці після "вибору", тому що в цій таблиці є занадто багато стовпців ...
LeonardChallis

7
-1 Оскільки саме цього хоче уникнути ОП. Прочитайте питання або принаймні запропонуйте відповідь на кшталт "це єдиний можливий спосіб".
devios1

5
Тому що іноді саме питання неправильне. :) Дублювання рядків без зміни вмісту збільшує надмірність. Якщо це можливо, слід рекомендувати зміни структури бази даних для мінімізації надмірності.
Торбен

5
Тільки тому, що це неправильно в звичайній практиці, це не робить помилкою. Існує багато випадків, коли стандартні найкращі практики не застосовуються. Приклад: база даних представляє документи, і користувачеві необхідно зберегти копію документа перед внесенням змін.
ima747

6
Тому що ви можете приземлитися на цій сторінці, не бажаючи точно такого ж, як OP
jx12345

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

Просто не включайте стовпчик первинної клавіші ні в список стовпців для INSERT, ні для частин SELECT запиту.


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

1
Знайшов це! Скопіюйте значення з одного рядка , але додати один з ваших власних значень в заяву вставки: stackoverflow.com/questions/23971078 / ...
anon58192932

1
Вибачте, що щойно сповістили про ваші запитання, радий, що ви його знайшли, це дійсно так.
Брайден Блек

9

Ви також можете спробувати скинути таблицю, знайти команду insert та відредагувати її:

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

--skip-extended-insertДає одну команду вставки для кожного рядка. Потім ви можете знайти рядок у своєму улюбленому текстовому редакторі, витягнути команду та змінити основний ключ на "за замовчуванням".


2
+1 від мене, оскільки це хороший підхід "поза коробкою", який в деяких випадках може бути корисним поза часом виконання. Але насамперед це перша відповідь, яка насправді стосується питання ОП і не просто синтаксично налаштовує рішення, яке вже пропонує ОП.
Сепстер

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але підхід є здоровим і є цінним, оскільки він унікальний тут і насправді вирішує питання ОП.
Сепстер

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

Друга - ця відповідь є лаконічною і в дусі фактично "копіює" рядок.
користувач37309

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

Деякі з наступного описували на цьому веб-сайті. Це те, що я зробив, щоб дублювати запис у таблиці з будь-якою кількістю полів:

Це також передбачає, що у вас є поле AI на початку таблиці

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, що дозволяє автоматичному збільшенню працювати при вставці.
shelbypereira

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 автоматично збільшує себе в первинному ключі

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-файлу під переглядом , натисніть "Перейти" і повторюваний рядок слід вставити.

Якщо ви не знаєте, що таке ПЕРШИЧНЕ поле, перегляньте свою сторінку phpmyadmin , натисніть на вкладку "Структура" , а внизу сторінки в розділі "Індекси" буде показано, яке поле має "ім'я ключа" значення "ПЕРВИЧНИЙ" .

Якийсь шлях довгий, але якщо ви не хочете мати справу з розміткою і просто потрібно дублювати один рядок, ви йдете.


Добре, відповіді на оп у нестандартному вигляді. Очевидно, що це не в усіх випадках, як, наприклад, краплі та геопросторові дані, але їх досить легко зняти та працює за ці дивні зміни кулі.
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, але я думаю, він повинен працювати аналогічно. Я використав рішення Леонарда Чалліса, тому що це було найпростіше і задовольнило потребу, проте в цьому є проблема - якщо ви просто візьмете ПК і збільшили його на 1, то що станеться, якщо ви додали інші записи з моменту додавання відповідного рядка . Я вирішив, що найкраще просто дозволити системі обробляти автоматичне підвищення ПК, тому я зробив наступне:

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
повністю відповів bakwaas
AsadYarKhan

0

Я знаю, що це старе питання, але ось інше рішення:

Це дублює рядок у головній таблиці, припускаючи, що основний ключ є автоматичним збільшенням, і створює копії даних зв'язаних таблиць з новим ідентифікатором основної таблиці.

Інші варіанти отримання назв стовпців:
-SHOW COLUMNS OF OF tablename; (Назва стовпця: Поле)
-DESCRIBE tablename (Назва стовпця: Поле)
-ВИБІРТЕ ім'я стовпця ІНФОРМАЦІЙНО_Схема.колонки WHERE table_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, безумовно, був на правильному шляху, принаймні, у випадку автоматичного збільшення. Однак не робіть ЗАЛИШЕННУ ТАБЛИЦЮ. Просто встановіть поле автоматичного збільшення у тимчасовій таблиці на NULL. Це призведе до помилки, але наступна ВСТАВКА всіх полів тимчасової таблиці відбудеться, і автоматичне поле 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
Абдулла Айдін

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

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

0

Ось відповідь, яку я знайшов в Інтернеті на цьому веб-сайті, описано, як зробити вищезазначене 1 ви можете знайти внизу сторінки. В основному, ви робите це копіювати рядок, який потрібно скопіювати, до тимчасової таблиці, що зберігається в пам'яті. Потім ви змінюєте номер первинного ключа, використовуючи оновлення. Потім ви знову вставите його в цільову таблицю. Потім ви опускаєте стіл.

Це код для нього:

CREATE TABLE ТИМЧАСОВОГО rescueteamДВИГАТЕЛЯ = ПАМ'ЯТЬ SELECT * FROM fitnessreport4WHERE РІД = 1; # 1 ряд постраждалих. UPDATE rescueteamSET rID = Недійсне, де RID = 1; порушений рядок №1.INSERT INTO fitnessreport4SELECT * FROM rescueteam; # 1 ряд порушений. DROP TABLE rescueteam# MySQL повернув порожній набір результатів (тобто нульові
рядки).

Я створив тимчасовий рятувальний стіл. Я скопіював рядок з мого оригінального таблиці fitnessreport4. Потім я встановлюю нульовий первинний ключ для рядка у тимчасовій таблиці, щоб я міг скопіювати його в початкову таблицю, не отримуючи помилки дублюючого ключа. Я спробував цей код вчора ввечері, і він спрацював.


0

Це додаткове рішення відповіді "Grim ..." Там були деякі коментарі, які мають первинний ключ як null. Деякі коментарі щодо цього не працюють. І кілька коментарів щодо рішень. Жодне з рішень не працювало на нас. У нас є MariaDB з таблицею InnoDB.

Не вдалося встановити первинний ключ, щоб дозволити нуль. Використання 0 замість NULL призвело до дублювання помилки значення для первинного ключа. SET SQL_SAFE_UPDATES = 0;Не працювали також.

Рішення від "Grim ..." спрацювало, якщо ми замінили наш ПЕРШИЙ КЛЮЧ на UNIQUE


-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 / основний ключ, щоб не імпортувати значення перед імпортом.

SELECT * FROM table where primarykey=1

Потім внизу сторінки:

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

Де сказано, "Експорт" просто експортуйте, а потім відредагуйте файл csv, щоб видалити значення основного ключа, щоб воно було порожнім, а потім просто імпортуйте його в базу даних, при імпорті буде призначено нову первинну клавішу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.