MySQL UPSERT没有ON DUPLICATE KEY

时间:2014-03-25 15:39:46

标签: php mysql database upsert

我希望在具有以下字段的MySQL表上UPSERTUPDATE,如果存在,否则插入):

CREATE TABLE item (
  uid int(11) NOT NULL AUTO_INCREMENT,
  timestamp int(11) NOT NULL DEFAULT '0',
  category1 int(11) NOT NULL DEFAULT '0',
  category2 int(11) NOT NULL DEFAULT '0',
  counter int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`uid`)
)

此表已投入使用,(timestamp,category1,category2)的组合适用于INSERT唯一,但不适用于整个表格内容。这就是为什么我不能使用“ ON DUPLICATE KEY ”功能的原因。

有关UNIQUE问题的说明: 如果category1 = 9,则这是我的插入,(timestamp,category1,category2)是唯一的。但该表正在高效使用,如果category1 = 1,2,则(timestamp,category1,category2)不是唯一的。 据我所知,我无法添加UNIQUE密钥,因为它会产生类别1 + 2的问题。

我需要的是这样的事情:

 IF (timestamp,category1,category2) exists 
     counter=existingCount + newCount
 ELSE 
     insert new record

我使用PHP和MySQL,因此两种语言的任何组合都可以。

我已经尝试过但需要花费太多时间的是:

  • 单个PHP SELECT语句,然后是UPDATEINSERT
  • INSERT然后UPDATEDELETE重复行

感谢我现在创建的这个存储过程的答案,语法没问题,但程序无效:

DROP PROCEDURE IF EXISTS myUpsert;
DELIMITER |
CREATE PROCEDURE myUpsert (IN v_timestamp INT, IN v_category1 INT, IN v_category2 INT, IN v_counter INT)        
BEGIN
  DECLARE existingCounter INT;
  SELECT COUNT(counter) AS existingCounter from item 
  WHERE timestamp =v_timestamp  AND category1=v_category1 AND category2=v_category2;

  IF existingCounter=0 THEN
    INSERT INTO item (timestamp,category1,category2,counter) 
    VALUES (v_timestamp,v_category1,v_category2,v_counter);
  ELSE
    UPDATE item SET count=v_counter+existingCounter
    WHERE timestamp=v_timestamp AND category1=v_category1 AND category2=v_category2;
  END IF;
END
|
DELIMITER ;

2 个答案:

答案 0 :(得分:1)

我建议为这三列添加唯一索引:

ALTER TABLE项ADD UNIQUE(timestamp,category1,category2)

答案 1 :(得分:0)

DROP PROCEDURE IF EXISTS myUpsert;
DELIMITER |
CREATE PROCEDURE myUpsert (IN v_timestamp INT, IN v_category1 INT, IN v_category2 INT, IN v_counter INT)        
BEGIN
DECLARE existingCounter INT;
  SET existingCounter = (SELECT COUNT(counter) from item 
  WHERE timestamp =v_timestamp  AND category1=v_category1 AND category2=v_category2);

IF existingCounter=0 THEN
 INSERT INTO item (timestamp,category1,category2,counter) 
 VALUES (v_timestamp,v_category1,v_category2,v_counter);
ELSE
 UPDATE item SET count=v_counter+existingCounter
 WHERE timestamp=v_timestamp AND category1=v_category1 AND category2=v_category2;
 END IF;
END
|
DELIMITER ;