2010-01-18 4 views
4

У меня есть таблица Mysql с одним первичным ключом (называется pkey), который автоматически увеличивается, и я хотел бы клонировать одну строку, сохраняя все данные одинаковыми, за исключением первичного ключа, который должен станет следующим доступным значением, определяемым с помощью автоматического приращения.Mysql Clone Row With Primary Key

Мой первый вопрос: возможен ли следующий запрос?

UPDATE `table` SET pkey='next_available_primary_key' WHERE pkey='old_primary_key' 

если бы пытались

UPDATE `table` SET pkey=null WHERE pkey='old_primary_key' 

Но это только устанавливает значение первичного ключа к нулю. Заранее благодарим за любую помощь/предложения.

UPDATE:

Я думаю, я должен добавить, что я на самом деле не нужны две копии данных в таблице. Я просто хочу изменить первичный ключ. Так что, если я должен был использовать INSERT ВЫБРАТЬ я бы компенсировать с помощью ON KEY UPDATE DUPLICATE PKEY = «next_available_primary_key» я просто не знаю, как это сделать ...

+0

Из любопытства: что это ваша цель ? Потому что вы можете злоупотреблять первичным ключом для некоторой цели (например, данные упорядочения), для которой она не предназначена. –

ответ

3
insert into t select 0,a,b,c,d,e from t where id = some_id 

использование 0 в качестве значения для auto_increment столбец, MySQL будет использовать следующий доступный один ...

отредактированный для нового комментария, если вы хотите изменить идентификатор к следующему доступному один,

update tbl set id = (select auto_increment from 
    information_schema.tables where table_name = 'tbl') where id = 4; 
7

вы хотите ВСТАВИТЬ, не UPDATE, если вы пытаетесь создать новую строку в таблице.

Как насчет этого? Убедитесь, что ваш PKEY установлен на автоинкремент.

INSERT INTO `table` (col,col,col) /*name all the columns EXCEPT the primary key*/ 
SELECT col,col,col /*name all the columns EXCEPT the primary key*/ 
    FROM 'table` 
WHERE pkey='old_primary_key' 
+0

Итак, я подумал об этом, и я могу использовать это решение, но я надеялся на более чистое решение, где мне не нужно перечислять все поля, кроме первичного ключа. –

+2

Я делаю много такого рода вещей, и я использую метаданные (information_schema.COLUMNS) для построения моего запроса. КОЛОННЫ.COLUMN_KEY = 'PRI', если этот столбец является частью первичного ключа для таблицы, пустая строка, если это не так. –

+0

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

2

Как насчет найденного решения на clone-sql-record?

CREATE TEMPORARY TABLE %1 ENGINE=MEMORY SELECT * FROM mytable WHERE myid=%2; 

UPDATE %1 SET myid=%3; 

INSERT INTO mytable SELECT * FROM %1; 

DROP TABLE %1; 

где

  • % 1 "Т" + raw_time_stamp, экс T20120124132754
  • % 2 oldid
  • % 3 NEWID
0

клонов записи таблицы, с автоинкрементным первичным ключом

CREATE TEMPORARY TABLE `tmp` SELECT * FROM `your_table_name`; 

UPDATE `tmp` SET id = NULL ; 

INSERT INTO `your_table_name` SELECT * FROM `tmp`; 

DROP TEMPORARY TABLE IF EXISTS `tmp`; 
0

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

CREATE TEMPORARY TABLE tmp_clone ENGINE=MEMORY 
    SELECT * FROM my_source_table WHERE id=some_id; 

ALTER TABLE tmp_clone MODIFY id bigint(20) default null; 
UPDATE tmp_clone SET id=null; 

INSERT INTO my_source_table SELECT * FROM tmp_clone; 

DROP TABLE tmp_clone; 

SELECT * from my_source_table where id = last_insert_id();