MySQL:INSERT到具有autoincrement列的表后意外的SELECT结果

时间:2014-05-15 18:13:42

标签: mysql mariadb

当我将一些数据插入表中然后在同一个表上运行SELECT查询时,我看到了一种奇怪的行为。此表有一个自动增量主键(uid),当我尝试选择“uid为空”的结果时会出现此问题。

我已将其归结为以下SQL命令:

DROP TABLE IF EXISTS test_users;
CREATE TABLE test_users (uid INTEGER PRIMARY KEY AUTO_INCREMENT, name varchar(20) NOT NULL);
INSERT INTO test_users(name) values('foo');
SELECT uid FROM test_users WHERE uid IS NULL;
SELECT uid FROM test_users WHERE uid IS NULL; -- no output from this query

我希望SELECT uid FROM test_users WHERE uid IS NULL永远不会返回任何内容,但有时会这样做。这是我发现的:

  • MySQL / MariaDB的版本似乎很重要。有这个问题的机器运行MySQL 5.1.73(CentOS 6.5,32位和64位)。我的另一台机器运行5.5.37-MariaDB(Fedora 19,64位)。两者都运行默认配置,除了配置为使用MyISAM表。
  • 仅影响INSERT后的第一个SELECT查询。
  • 如果我为uid指定一个值而不是让它自动递增,那么它没问题。
  • 如果我在INSERT和SELECT之间断开连接并重新连接,那么我得到预期的无结果。这是我在管理连接对象的Perl中最容易看到的。我有一个测试脚本在https://gist.github.com/avuserow/1c20cc03c007eda43c82
  • 上演示了这一点

1 个答案:

答案 0 :(得分:0)

此行为是设计使然。

它明显等同于SELECT * FROM t1 WHERE id = LAST_INSERT_ID();,它也只能用于您刚刚插入的连接,正如您所描述的那样。

这显然是一种解决方法,您可以在某些环境中使用,这使得难以以更传统的方式获取最后插入的(通过您的连接)行的自动增量值。

准确地说,它实际上是分配给连接的 last 插入语句插入的第一个行的auto_increment值。当你只插入一行时,这是同样的事情,但当你用一个插入语句插入多行时,这是不一样的。

http://dev.mysql.com/doc/connector-odbc/en/connector-odbc-usagenotes-functionality-last-insert-id.html