使用主键克隆Mysql行

4

我有一个Mysql表,其中只有一个主键(称为pkey),它是自动递增的。我想克隆一行数据,保持所有数据相同,除了主键应该成为下一个可用值,由自动递增定义。

我的第一个问题是,以下查询是否可行?

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'进行补偿,我只是不确定如何做到这一点...


出于好奇,你的目标是什么?因为你可能会误用主键来实现一些不适合它的目标(比如对数据进行排序)。 - Decent Dabbler
5个回答

7

如果您想在表中创建新行,则应使用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'

所以我考虑了一下,可能会使用这个解决方案,但我希望有一个更清晰的解决方案,不需要列出除主键之外的所有字段。 - John Space
2
我经常做这种事情,我使用元数据(information_schema.COLUMNS)来构建我的查询。如果该列是表的主键的一部分,则COLUMNS.COLUMN_KEY ='PRI',否则为空字符串。 - O. Jones
无论如何,您都需要使用一些脚本来构建查询。我认为根据您的数据库引擎,您还需要使用临时表。 - Pierre de LESPINAY

3
这个在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;

解释:本段内容是关于it技术的,下面是需要翻译的具体内容:

  • %1代表“T”加上原始时间戳,例如T20120124132754
  • %2代表旧ID
  • %3代表新ID

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

如果将auto_increment列的值设为0,MySQL将使用下一个可用的值...

根据您的最新评论进行编辑,如果想要将id更改为下一个可用的值,则...

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接