0

我想更新由唯一键标识的多行而不插入新行。

下面是我的表:

CREATE TABLE `insert_update_ignore` (
   `obj_id` int(11) NOT NULL,  
   `obj_type` tinyint(4) NOT NULL,
   `value` int(11) DEFAULT '-1',  
   UNIQUE KEY `unique_key` (`obj_id`,`obj_type`)) 
ENGINE=InnoDB DEFAULT  CHARSET=utf8

该表有一些现有记录:

mysql> select * from insert_update_ignore;
+--------+----------+-------+
| obj_id | obj_type | value |
+--------+----------+-------+
|      1 |        1 |    -1 |
|      1 |        2 |    -1 |
|      2 |        1 |    -1 |
|      2 |        2 |    -1 |
+--------+----------+-------+

我有一些值来更新value表中的列。

INSERT INTO insert_update_ignore(obj_id, obj_type, value)
    VALUES(1, 1, 1),
          (1, 2, 3),
          (2, 1, 1),
          (2, 2, 5),
          (3, 1, 10)
    ON DUPLICATE KEY UPDATE
       value = VALUES(value);

这几乎完成了工作,除了最后一个值,即 (3, 1, 10) 被插入到表中。这个不应该插入,因为唯一键 (3, 1) 之前不存在。

我怎么能只做这UPDATE部分,但不是INSERT?如果存在更好的实现,可以更改表模式。要更新的值是从其他数据库计算的(在不同的机器和不同的端口上运行)。

我挖出下面的一个来完成这项工作,但是如果值以千为单位,那么该语句就太大了。还有更优雅的方法吗?感谢有人可以提供帮助。PS 我正在用 Python 编写代码并使用 MySQLdb 库。

UPDATE insert_update_ignore
SET value = CASE
    WHEN (obj_id = 1 AND obj_type = 1) THEN 1
    WHEN (obj_id = 1 AND obj_type = 2) THEN 3
    WHEN (obj_id = 2 AND obj_type = 1) THEN 1
    WHEN (obj_id = 2 AND obj_type = 2) THEN 5
    WHEN (obj_id = 3 AND obj_type = 1) THEN 10
    ELSE value
END 
WHERE (obj_id, obj_type) IN ((1, 1), (1,2), (2, 1), (2, 2), (3, 1));
4

2 回答 2

1

您可以先将要更新的所有值放入临时表中。如果可以连接,则从临时表中更新原始表中的所有值。

create temporary table temp like insert_update_ignore;

insert into temp
    values(1, 1, 1),
          (1, 2, 3),
          (2, 1, 1),
          (2, 2, 5),
          (3, 1, 10);

update insert_update_ignore i
 join temp t
 using (obj_id, obj_type)
 set i.value = t.value;

drop temporary table temp;

我也将所有这些都放入了SQLFiddle中。

于 2013-01-02T18:31:49.857 回答
0

The entire purpose of INSERT is to insert new rows, so of course it's going to insert a new row (if a duplicate key is not found; otherwise, update it). If you only want to update existing rows then use UPDATE queries.

Rather than use CASE ... WHEN ... THEN ... ELSE ... END iterate over each unique key and UPDATE ... WHERE ....

Edit:

For example:

UPDATE `insert_update_ignore` SET `value` = 1 WHERE `obj_id` = 1 AND `obj_type` = 1;
UPDATE `insert_update_ignore` SET `value` = 3 WHERE `obj_id` = 1 AND `obj_type` = 2;
UPDATE `insert_update_ignore` SET `value` = 1 WHERE `obj_id` = 2 AND `obj_type` = 1;
UPDATE `insert_update_ignore` SET `value` = 5 WHERE `obj_id` = 2 AND `obj_type` = 2;
UPDATE `insert_update_ignore` SET `value` = 10 WHERE `obj_id` = 3 AND `obj_type` = 1;

The first 4 queries will update the rows which match the criteria in the WHERE clause whereas the last will not as no row satisfies the conditions.

于 2013-01-02T17:18:58.610 回答