2010-02-05 56 views
5

我正确理解mysql的LAST_INSERT_ID()函数在插入尝试之间没有重置(因为@@ identity在sql-server中)...如果立即前面的插入操作失败,LAST_INSERT_ID()将返回任何该连接的最后一个插入的pk的pk为任意表中包含自动递增主键。如果我在这方面是正确的,这是否看起来不像是关于这个功能的最迟钝的行为,而是人们可以想到的?是否没有与sql-server的@@标识类似的mysql函数?如果前面的插入尝试创建没有新的记录将返回NULL?或者,如何确定最新插入操作的主键?mysql @@ identity vs sql-server last_insert_id()

+5

@@身份为您提供最新的在任何范围内插入。这可能是触发器的结果,与您刚刚运行的插入语句无关。在SQL服务器中,您通常希望使用scope_identity()函数。 – feihtthief 2010-02-05 18:20:58

+0

@feihtthief - thx,很好的说明+1 – codemonkey 2010-02-05 18:22:10

+0

请注意,当SQL Server的@@ identity和scope_identity()与多处理器的服务器上的多行插入一起使用时,可能会给出错误的答案!使用OPTION(MAXDOP 1)是一种解决方法。 – ErikE 2010-02-06 01:31:09

回答

6

@@ identity在sql server中通常也是错误的。在大多数情况下,您应该使用scope_identity()

在MySql中,last_insert_id()应该是安全的,因为插入错误后您可以调用此函数的唯一方法是您已经正确捕获并解释了插入错误。否则,你仍然会在处理命令。换句话说,last_insert_id()不是你的错误处理机制。

+0

@paragraph 2 - 让我重新思考构造插入语句的方式......在这种情况下,提供插入的select语句的where子句决定插入是否发生。换句话说,根据where子句的条件,插入是0+条记录。我想我可以拉外插入和有条件地执行插入。很好的解决方法,但它确实感觉像我的解决方法。 – codemonkey 2010-02-05 18:29:57

1

您必须先检查插入是否成功。如果插入成功,则可以依赖LAST_INSERT_ID()。

编辑:在PHP中:

<?php 
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password'); 
if (!$link) { 
    die('Could not connect: ' . mysql_error()); 
} 
mysql_select_db('mydb'); 

mysql_query('<PUT YOUR INSERT HERE'); 
if(mysql_affected_rows()>0){ 
    $last_id=mysql_insert_id(); 
}else{ 
    //panic! 
} 
?> 
+0

我不知道是否有一个本地mysql函数类似于php的msyql_affected_rows()?我们所有的dml都作为存储过程/函数驻留在数据库中。 – codemonkey 2010-02-05 18:31:34

+0

http://php.net/manual/en/function.mysql-query.php对于其他类型的SQL语句,INSERT,UPDATE,DELETE,DROP等,mysql_query()在成功时返回TRUE或在错误时返回FALSE。 – Notinlist 2010-02-05 18:43:34

+1

插入语句可能“成功”,并且不会进行任何插入。考虑INSERT IGNORE语句。在这种情况下,依靠mysql_query()的返回值会产生错误的结果。 – 2010-02-05 21:21:06