Строка клонирования Mysql с первичным ключом

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

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

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

если бы пробовали

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

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

ОБНОВЛЕНИЕ:

Я думаю, я должен добавить, что мне действительно не нужны две копии данных в таблице. Я просто хочу изменить первичный ключ. Поэтому, если бы я использовал INSERT SELECT, мне пришлось бы компенсировать использование ON DUPLICATE KEY UPDATE pkey='next_available_primary_key', я просто не уверен, как это сделать...


person John Space    schedule 18.01.2010    source источник
comment
Из любопытства: какова ваша цель? Потому что вы можете неправильно использовать первичный ключ для какой-то цели (например, данных заказа), для которой он не предназначен.   -  person Decent Dabbler    schedule 18.01.2010


Ответы (5)


Вам нужен INSERT, а не 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'
person O. Jones    schedule 18.01.2010
comment
Итак, я подумал об этом, и я могу использовать это решение, но я надеялся на более чистое решение, в котором мне не нужно перечислять все поля, кроме первичного ключа. - person John Space; 18.01.2010
comment
Я делаю много подобных вещей и использую метаданные (information_schema.COLUMNS) для построения своего запроса. COLUMNS.COLUMN_KEY = 'PRI', если этот столбец является частью первичного ключа таблицы, пустая строка, если это не так. - person O. Jones; 22.01.2010
comment
В любом случае вам придется использовать какой-то скрипт для построения запроса. И я думаю, вам придется использовать временную таблицу также в зависимости от вашего механизма базы данных. - person Pierre de LESPINAY; 26.05.2011

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;
person jspcal    schedule 18.01.2010

Как насчет решения, найденного на 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 - это "T"+raw_time_stamp, например T20120124132754
  • %2 устарел
  • %3 новый идентификатор
person Paul Crown    schedule 24.01.2012

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

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`;
person Anam Shah    schedule 26.12.2016

Обратите внимание, что другие приведенные решения, по-видимому, работают с исходной таблицей, которая допускает нуль для столбца первичного ключа. Поскольку для меня это не так, я столкнулся с ошибкой, которую можно легко решить, изменив временную таблицу (я ожидал, что 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();
person s10z    schedule 01.03.2017