复制表中的所有行并防止重复键

时间:2013-05-09 18:43:11

标签: mysql sql clone temp-tables

我想要这样做

  • 获取名为table的博客中的所有行。
  • 将它们复制到临时数据库中
  • 编辑此临时表记录的语言字段
  • 插入博客表

我正在尝试这样:

CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2;
UPDATE tmptable SET lan = 1;
INSERT INTO blogs SELECT * FROM tmptable; dump database tmptable;

但是我很难得到重复的关键错误...

我该如何预防?

- 编辑 -

我试过了:

CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2;
UPDATE tmptable SET lan = 1;
ALTER TABLE tmptable DROP id;
INSERT INTO blogs SELECT * FROM tmptable; dump database tmptable;

但是Column count doesn't match value count at row 1

- 编辑 -

我相信这会奏效(而且它确实存在,因为我知道有多少记录存在)

CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2;
UPDATE tmptable SET lan = 1;
UPDATE tmptable SET id = id + 1000;
INSERT INTO blogs SELECT * FROM tmptable;

但我该如何正确地做到这一点? (只需为主键(id)设置下一个可用的自动增量值(不含PHP /类似))

- 编辑 -

也许是这样的???

CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2;
UPDATE tmptable SET lan = 1;
UPDATE tmptable SET id = id + (SELECT id FROM blogs ORDER BY id DESC LIMIT 1);
INSERT INTO blogs SELECT * FROM tmptable;

5 个答案:

答案 0 :(得分:14)

不需要临时表。

INSERT INTO blogs (lan, col1, col2, col3, ...)
SELECT 1, col1, col2, col3, ...
FROM blogs
WHERE lan = 2

col1, col2, col3, ...替换为除lanid之外的所有列的列表。

答案 1 :(得分:4)

CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2;
UPDATE tmptable SET lan = 1;
alter table tmptable drop column id;
INSERT INTO blogs SELECT NULL,tmptable.* FROM tmptable;

假设,列“id”是第一个col。

答案 2 :(得分:1)

请尝试以下sql。类似的SQL FIDDLE

 CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2;
    UPDATE tmptable SET lan = 1;
    UPDATE tmptable SET id = (select @val:=@val+1 from(select @val:=(select max(id) from blogs)) t)
    INSERT INTO blogs SELECT * FROM tmptable;

希望这有帮助。

答案 3 :(得分:0)

UPDATE blogs SET lan = 1 WHERE lan = 2;

只需在原始表格上运行该查询。

  

我不想更改语言,我想保存另一份副本   所有记录和签名都复制了另一种语言

在这种情况下,请从临时表中删除主键。插回行时,请不要包含主键列:

INSERT INTO blogs (title, lan) SELECT * FROM tmptable;

答案 4 :(得分:0)

使用预准备语句,您可以查询要使用的列的信息架构,然后伪造要执行的查询:

这是一个案例:

-- first query all the blogs column minus id and lan

SELECT GROUP_CONCAT(c.COLUMN_NAME)
INTO @cols
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE
 c.TABLE_NAME = 'blogs'
 AND c.COLUMN_NAME not in ('id', 'lan');

-- second build the query with the gathered columns
-- like INSERT INTO blogs(lan, col1, ...) SELECT 2, col1, ... FROM blogs WHERE lan=1

SET @sql=CONCAT(CONCAT(CONCAT(CONCAT('INSERT INTO blogs (lan,', @cols), 
                ') SELECT 2,'), @cols), ' FROM blogs WHERE lan=1');

-- prepare the statement    
PREPARE stmt FROM @sql;

-- and last run the insert
EXECUTE stmt;