33

我们有一个每天午夜通过 cronjob 更新的数据库,我们从外部 XML 获取新数据。

我们所做的是插入所有新内容,如果有重复的键,我们会更新该字段。

INSERT INTO table (id, col1, col2, col3)
values (id_value, val1, val2, val3),
(id_value, val1, val2, val3),
(id_value, val1, val2, val3),
(id_value, val1, val2, val3),
ON DUPLICATE KEY UPDATE 
col1 = VALUES (col1), 
col2 = VALUES (col2), 
col3 = VALUES (col3);

我们想知道实际插入了哪些行,这意味着我们想要一个新项目的列表。是否有任何可能返回新插入的查询?基本上,我们需要获取所有新 ID,而不是新插入的数量。

谢谢

4

3 回答 3

40

您可以在插入/更新时通过检查结果集中受影响的行数来获取此信息。

MySQL文档指出:

使用 ON DUPLICATE KEY UPDATE,如果将行作为新行插入,则每行的受影响行值为 1,如果更新现有行,则值为 2。

您需要将 ROW_COUNT 与 LAST_INSERT_ID 结合起来以获得答案并一次插入一行。

于 2012-05-22T20:12:16.440 回答
8

添加一update_count INT NOT NULL DEFAULT 1列并更改您的查询:

INSERT
INTO    table (id, col1, col2, col3)
VALUES
(id_value, val1, val2, val3),
(id_value, val1, val2, val3,),
(id_value, val1, val2, val3),
(id_value, val1, val2, val3),
ON DUPLICATE KEY
UPDATE 
        col1 = VALUES (col1), 
        col2 = VALUES (col2), 
        col3 = VALUES (col3),
        update_count = update_count + 1;

您还可以在BEFORE UPDATE触发器中增加它,这将允许您保持查询不变。

于 2012-05-22T20:33:12.703 回答
0

我可以说我在 PHP 中的表现:

1) 简单查询 SELECT MAX(id) 并在 Insert On Duplicate 之前将其记住到 $max_id 从表中。

2)然后在更新过程中收集受影响行的ID(无论是新的还是存在的): $ids[] = mysql_insert_id();

3) 然后$inserted_rows = max($ids)-$max_id;

4) 更新行数 = count($ids_srt)-$inserted_rows

$max_id = mysql_query("SELECT MAX(id) from table");
$max_id = mysql_result($max_id, 0);

// !!! prepare here 'insert on duplicate' query in a cycle

$result=mysql_query($query);
$ids[] = mysql_insert_id();

// finish inserting and collecting affected ids and close cycle

$inserted_rows = max($ids)- $max_id;
$updated_rows = count($ids)- $inserted_rows
于 2017-11-15T22:13:49.000 回答