0

我遇到一个问题,当我将“ON DUPLICATE KEY UPDATE”与 UNIQUE 字段一起使用时,会出现静默失败。这是场景:

1)我有一个这样的映射表:

CREATE TABLE index_user_username (
    username VARCHAR(255) NOT NULL UNIQUE,
    id INT NOT NULL UNIQUE,
    PRIMARY KEY (username, id)
);

通知username被标记为UNIQUE

2)我插入一些条目:

mysql> INSERT INTO index_user_username (username,id) VALUES ('dude', 1) ON DUPLICATE KEY UPDATE username=VALUES(username);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO index_user_username (username,id) VALUES ('man', 2) ON DUPLICATE KEY UPDATE username=VALUES(username);
Query OK, 1 row affected (0.00 sec)

这是我对数据库的健全性检查:

mysql> SELECT * FROM index_user_username;
+----------+----+
| username | id |
+----------+----+
| dude     |  1 |
| man      |  2 |
+----------+----+
2 rows in set (0.00 sec)

3)我将其中一行更新为另一行的用户名之一,但我没有失败(我得到“ Query OK”):

mysql> INSERT INTO index_user_username (username,id) VALUES ('dude', 2) ON DUPLICATE KEY UPDATE username=VALUES(username);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM index_user_username;
+----------+----+
| username | id |
+----------+----+
| dude     |  1 |
| man      |  2 |
+----------+----+
2 rows in set (0.00 sec)

所以我的主要问题是,这不应该引发错误吗?如果没有,关于变通选项的任何建议(另请参见下面的注释)?另外,我正在运行版本 5.6.13

澄清:“id”字段映射到另一个表。本质上,这是一个唯一的用户名到用户 ID 映射表。


作为旁注:我确实注意到在命令行中我收到一个响应,告诉我有多少行受到影响,并认为如果出现 0 个受影响的行,我可以做一些检查并在我的代码中抛出错误。但是,我使用 node.js 模块(https://github.com/felixge/node-mysql)实现了这一切,它似乎对上述所有 INSERT 语句都返回了相同的响应:

{ fieldCount: 0,
    affectedRows: 1,
    insertId: 0,
    serverStatus: 2,
    warningCount: 0,
    message: '',
    protocol41: true,
    changedRows: 0 }

任何帮助弄清楚为什么这似乎给了我错误的反馈也会有所帮助。

4

3 回答 3

1

ON DUPLICATE KEY 子句不需要更新唯一键。它已经在那里了。只需从更新中删除该列。

于 2013-11-09T03:20:23.857 回答
0

好的,经过一番调查,我想我找到了答案。来自“INSERT ... ON DUPLICATE KEY UPDATE Syntax”的 mysql 文档

通常,您应该尽量避免对具有多个唯一索引的表使用 ON DUPLICATE KEY UPDATE 子句。

(我认为这部分是因为在我的情况下,UNIQUEs 上的多个匹配项不明确)

此外,从 node.js 方面来看,我相信我找到了一种解决方法,可以让我弄清楚更新后发生了什么并做出相应的响应。我发现了一些描述我遇到的类似问题的问题/拉动,例如:

这使我将 FOUND_ROWS 列入黑名单:

所以,给定:

CREATE TABLE index_user_username (
    username VARCHAR(255) NOT NULL UNIQUE,
    id INT NOT NULL UNIQUE,
    PRIMARY KEY (username, id)
);

如果我有以下脚本:

var mysql      = require('mysql');
var connection = mysql.createConnection('mysql://root:rootpass@localhost/user?flags=-FOUND_ROWS');
connection.connect()
connection.query('INSERT INTO index_user_username (username,id) VALUES (\'dude\', 1) ON DUPLICATE KEY UPDATE username=VALUES(username)', function(err,result) {
  console.log('1:',result.affectedRows)
  connection.query('INSERT INTO index_user_username (username,id) VALUES (\'man\', 2) ON DUPLICATE KEY UPDATE username=VALUES(username)', function(err,result) {
    console.log('2:',result.affectedRows)
    connection.query('INSERT INTO index_user_username (username,id) VALUES (\'dude\', 2) ON DUPLICATE KEY UPDATE username=VALUES(username)', function(err,result) {
      console.log('3:',result.affectedRows)
      connection.query('INSERT INTO index_user_username (username,id) VALUES (\'dude\', 3) ON DUPLICATE KEY UPDATE username=VALUES(username)', function(err,result) {
        console.log('4:',result.affectedRows)
        connection.end()
      })
    })
  })
})

我得到输出:

1: 1
2: 1
3: 0
4: 0

这就是我需要的,以前我得到的是:

1: 1
2: 1
3: 1
4: 1

这并没有给我关于刚刚发生的事情的反馈。

于 2013-11-10T17:05:44.453 回答
0

但它确实使用相同的名称进行了更新。唯一键只防止两个相同的值,而不是使用相同的值进行更新。你的意思是

ON DUPLICATE KEY UPDATE id=VALUES(id)
于 2013-11-09T00:47:45.723 回答