【问题标题】:pdo lastInsertId returns zero(0)pdo lastInsertId 返回零(0)
【发布时间】:2019-11-25 16:30:49
【问题描述】:

所有查询都成功执行,当我检查 MySQL 行中的表成功插入且没有任何错误,但 lastInsertId() 返回 0。为什么?

我的代码:

// queries executes successfully, but lastInsetId() returns 0
// the menus table has `id` column with primary auto_increment index
// why lastInsertId return 0 and doesn't return actual id?


$insertMenuQuery = " 
 SELECT @rght:=`rght`+2,@lft:=`rght`+1 FROM `menus` ORDER BY `rght` DESC limit 1; 
 INSERT INTO `menus`(`parent_id`, `title`, `options`, `lang`, `lft`, `rght`) 
      values 
  (:parent_id, :title, :options, :lang, @lft, @rght);";
     try {
           // menu sql query
           $dbSmt = $db->prepare($insertMenuQuery);

           // execute sql query
           $dbSmt->execute($arrayOfParameterOfMenu);
           // menu id
           $menuId = $db->lastInsertId();

           // return
           return $menuId;

     } catch (Exception $e) {
          throw new ForbiddenException('Database error.' . $e->getMessage());
     }

【问题讨论】:

标签: php mysql pdo lastinsertid


【解决方案1】:

我们必须使用 PDO_MySQL

$DB->setAttribute(PDO::ATTR_EMULATE_PREPARES,TRUE); // there are other ways to set attributes. this is one

这样我们就可以运行多个查询,例如:

$foo = $DB->prepare("SELECT * FROM var_lst;INSERT INTO var_lst (value) VALUES ('durjdn')");

但遗憾的是,这样做可以减轻 $DB 返回正确插入 ID 的负担。您必须单独运行它们才能检索插入 ID。这将返回正确的插入 ID:

$DB->setAttribute(PDO::ATTR_EMULATE_PREPARES,TRUE);
$foo = $DB->prepare("INSERT INTO var_lst (value) VALUES ('durjdn')");
$foo->execute();
echo $DB->lastInsertId();

但这不会:

$DB->setAttribute(PDO::ATTR_EMULATE_PREPARES,TRUE);
$foo = $DB->prepare("SELECT * FROM var_lst;INSERT INTO var_lst (value) VALUES ('durjdn')");
$foo->execute();
echo $DB->lastInsertId();

这甚至不会运行这两个查询:

$DB->setAttribute(PDO::ATTR_EMULATE_PREPARES,FALSE); // When false, prepare() returns an error
$foo = $DB->prepare("SELECT * FROM var_lst;INSERT INTO var_lst (value) VALUES ('durjdn')");
$foo->execute();
echo $DB->lastInsertId();

【讨论】:

  • Felix:设置 PDO 属性救了我。谢谢。
【解决方案2】:

将$dbh->lastInsertId(); 放在$dbh->commit() 之前和$stmt->execute(); 之后

【讨论】:

  • 这行得通!谢谢,我认为 php 应该在文档中提到这一点!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-31
  • 1970-01-01
  • 2022-12-19
  • 1970-01-01
  • 2021-12-27
  • 2020-10-30
  • 1970-01-01
相关资源
最近更新 更多