mysql @@identity 与 sql-server last_insert_id()

Posted

技术标签:

【中文标题】mysql @@identity 与 sql-server last_insert_id()【英文标题】:mysql @@identity vs sql-server last_insert_id() 【发布时间】:2011-01-13 15:20:42 【问题描述】:

我是否正确理解mysql的 LAST_INSERT_ID() 函数在插入尝试之间不会重置(就像@@identity 在 sql-server 中所做的那样)...如果前面的插入操作失败,LAST_INSERT_ID() 将返回该连接最后一次插入具有自动递增主键的 any 表的任何 pk 的 pk 是。如果我在这点上是正确的,这似乎不只是人们可以想出的这个功能最迟钝的行为吗?是否没有 mysql 函数的行为类似于 sql-server 的@@identity?如果 紧接在前面 插入尝试没有创建新记录,则返回 NULL 的方法?或者,如何确定最近一次插入操作的主键?

【问题讨论】:

@@identity 为您提供任何范围内的最新插入。这可能是与您刚刚运行的插入语句无关的触发器的结果。在 SQL Server 中,您通常希望使用 scope_identity() 函数。 @feihtthief - 谢谢,很好的说明 +1 请注意,SQL Server 的 @@identity 和 scope_identity() 在具有多个处理器的服务器上与多行插入一起使用时,可能会给出错误的答案!使用 OPTION (MAXDOP 1) 是一种解决方法。 【参考方案1】:

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

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

【讨论】:

@paragraph 2 - 让我重新思考构建插入语句的方式......在这种情况下,提供插入的 select 语句中的 where 子句决定了插入是否发生。换句话说,插入是 0+ 条记录,具体取决于 where 子句条件。我想我可以将它们拉到插入之外并有条件地执行插入。不错的解决方法,但对我来说确实是一种解决方法。【参考方案2】:

您必须先检查插入是否成功。如果插入成功,则可以依赖 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!

?>

【讨论】:

不知道有没有类似于php的msyql_affected_rows()的原生mysql函数?我们所有的 dml 作为存储过程/函数驻留在数据库中。 php.net/manual/en/function.mysql-query.php 对于其他类型的 SQL 语句,INSERT、UPDATE、DELETE、DROP 等,mysql_query() 成功返回 TRUE,错误返回 FALSE。 插入语句可能是“成功的”并且不进行任何插入。考虑一个 INSERT IGNORE 语句。在这种情况下,依赖 mysql_query() 的返回值会产生错误的结果。

以上是关于mysql @@identity 与 sql-server last_insert_id()的主要内容,如果未能解决你的问题,请参考以下文章

Identity server4改用MySQL存储数据

休眠中的 GenerationType.AUTO 与 GenerationType.IDENTITY

相当于mySQL中的SQL Server函数SCOPE_IDENTITY()?

identity使用mysql

MySQL中MSSQL IDENTITY列的等价物

mySQL workbench中定义identity(1,1)一直提示有错误是怎么回事?