2013-06-12 50 views
0

在MySQL中,我想复制几条记录,但由于存在大量的列,我不想列出插入表中的每个列名。我尝试使用ON DUPLICATE KEY子句进行INERT INTO,但没有奏效。我首先将记录复制到临时表中。该设置是这样的:插入表中强制新主键

CREATE TABLE copy_of_test LIKE test; 
INSERT INTO copy_of_test SELECT * FROM test WHERE some_column IN (@X, @Y, @Z); 
UPDATE copy_of_test SET some_other_column = @NewValue; 
INSERT INTO test SELECT * FROM copy_of_test 
ON DUPLICATE KEY UPDATE test.idTest = last_insert_id(test.idTest); 

最后一个INSERT会显示:

查询OK,0行受到影响(0.00秒) 记录:3次重复:0警告:0

但没有记录插入到测试中。我试过这个查询的各种其他版本,但只有关于列名的语法或含糊不清的错误消息。我错过了什么?

我真正想要的是这样的:

INSERT INTO test SELECT * FROM copy_of_test 
ON DUPLICATE KEY AUTO_INCREMENT test PRIMARY KEY; 

回答

1

下面是应该工作(非常)快速和肮脏的方式:

CREATE TABLE copy_of_test LIKE test; 
INSERT INTO copy_of_test SELECT * FROM test WHERE some_column IN (@X, @Y, @Z); 
UPDATE copy_of_test SET some_other_column = @NewValue; 
UPDATE copy_of_test SET idTest = idTest + (SELECT MAX(idTest) FROM test); -- here's where the magic happens 
INSERT INTO test SELECT * FROM copy_of_test 

编辑 - 这是另一个类似quick'n'dirty不会使用子查询方式:(如果有其他独特的限制这是行不通的。)

CREATE TABLE copy_of_test LIKE test; 
ALTER TABLE copy_of_test DROP PRIMARY KEY, MODIFY idTest INT; 
ALTER TABLE copy_of_test ALTER idTest DROP DEFAULT; 
INSERT INTO copy_of_test SELECT * FROM test WHERE some_column IN (@X, @Y, @Z); 
UPDATE copy_of_test SET some_other_column = @NewValue, idTest = null; 
INSERT INTO test SELECT * FROM copy_of_test 

尽管如此,我认为你不应该使用这种技巧来避免写下所有列名。为一个查询创建一个临时表也可以用一个语句来完成,这绝对不是一个好的解决方案。您可能希望找到一种以编程方式创建语句的方法。 SHOW COLUMNS IN test可以成为你的朋友。

+0

由于四个其他列没有被更改的唯一键,所以这已变得没有意义,因此它们违反了唯一性。 – dokhebi

+0

好的,是的。你是对的 - 第二个版本不会工作。 –