插入mysql时出现密钥冲突

时间:2013-06-28 22:27:58

标签: php mysql insert-update

我将此SQL代码插入名为daily的数据库中。我定期更新daily数据库,如下所示:

INSERT INTO daily 
(SELECT * FROM dailytemp 
WHERE trim(`Point`) <>'' 
AND trim(`Point`) IN (Select trim(`Point`) FROM `data`));

我相信我收到了错误,因为这两个表都有id主列。

我希望插入数据,但会为找到的任何重复生成新的ID。

我试图列出列名,但它大约有20列,这可能会使这个过程变得很麻烦。

我最好的选择是什么?

修改

daily和daily_temp的表定义是相同的,所有列都是varchar(100)和id(bigint)

id bigint
col1 varchar(100)
col2 varchar(100)
col3 varchar(100)
etc..

3 个答案:

答案 0 :(得分:1)

确实,您肯定会尝试插入id中已存在daily的行。

如果这不会造成任何参照完整性问题,您可以在id中重新生成dailytemp,以便它们不会与daily中的任何一个重叠。这可能会起到作用:

SET @offset =  (SELECT MAX(id) FROM daily) - (SELECT MIN(id) FROM dalytemp) +1;
UPDATE dailytemp SET id = id + @offset;

然后尝试INSERT

如果行可以通过您描述的其他进程插入daily,或者由于任何原因在此表中跳过id(例如,如果列为AUTO_INCREMENT }),然后问题将再次发生。您可能希望在日常程序中包含此初步UPDATE

答案 1 :(得分:1)

可能的解决方案可能是使用BEFORE INSERT触发器和单独的表进行排序(如果您不介意的话)。

序列表

CREATE TABLE daily_seq(id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY);

现在是触发器

DELIMITER $$
CREATE TRIGGER tg_daily_insert
BEFORE INSERT ON daily
FOR EACH ROW
BEGIN
  INSERT INTO daily_seq VALUES(NULL);
  SET NEW.id = LAST_INSERT_ID();
END$$
DELIMITER ;

现在你可以每天插入你想要的任何东西,id值将替换为唯一的自动递增的。

这是 SQLFiddle 演示

答案 2 :(得分:0)

我决定使用存储的进程来执行操作,列出所有列名称而不是头痛

感谢所有帮助过的人。我这样做的另一个原因是我需要为插入的每组数据插入每日表的日期,所以我只为dail表创建了一个日期列

INSERT INTO daily (col1, col2, etc..., created) 
SELECT col1, col2, etc..., 'mydate' from daily_temp  WHERE 
trim(`Point`) <>'' AND trim(`Point`) IN 
(Select trim(`Point`) FROM `data`));

感谢所有