【问题标题】:mysqli_insert_id still returning a value even after select queries即使在选择查询之后 mysqli_insert_id 仍然返回一个值
【发布时间】:2015-04-08 22:20:41
【问题描述】:

我有一个功能不符合我的预期。其目的是为选择查询返回一个行数组,或为插入查询返回插入 ID。由于某种原因,如果有一个插入查询后跟一个选择查询,则测试查询是否为插入的函数部分会失败,因为 inesrt_id 仍然返回插入行的 id。我可以围绕这个进行编程,但我真的很想了解它为什么会发生。

我的理解是,如果最近的查询是一个选择,那么应该没有插入 id。我是 mysqli 的新手,所以当我认为查询确实“结束”时,也许查询并没有真正“结束”,所以新的选择算作同一查询的一部分?如果我在每个查询上重新创建连接,我可以让它正常工作,但这不切实际。这是查询功能的代码。

public function __construct(){
    parent::__construct();
    //        @mysql_select_db ('public') OR die('Could not select the database: ' . mysql_error() );
    $this->connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_TABLE, DB_PORT)OR die ('Could not connect to MySQL: ' . mysql_error());
    $this->db = $this;
}

public function query_return($querystring){

    $response = array();
    $this->result_object = $this->connection->query($querystring);
    if($this->result_object != FALSE) {
        $last_id = $this->connection->insert_id;
        if (!empty($last_id)) {
            $response = $last_id;
        }
        else {
            while ($row = mysqli_fetch_assoc($this->result_object)) {
                array_push($response, $row);
            }
        }
    }
    else{
        $response = PEAR::raiseError('There was a problem with the query: '. mysql_error());
    }
    return $response;


}

编辑:好的,感谢下面的人,我在函数中添加了一个 is_object 测试。我无法直接替换真/假测试,因为我实际上也使用此功能进行删除,我想知道它何时失败。我用 is_object 测试包装了 insert_id 测试,现在看来一切正常。我猜如果连接上有先前的插入,删除查询将返回一个 insert_id,但我认为这不会导致问题,因为这些函数只有在从 query_return 收到 FALSE 时才会失败。

我仍然不明白为什么 mysqli_insert_id 会在选择查询后返回一个值,而文档让我相信它不应该但至少我的代码正在工作。这个 query_return 函数是从这些方法的“mysql_”(没有“i”)程序版本调整而来的,它适用于这些版本,所以有些东西我仍然不明白。无论如何,这是调整后的功能。

private function query_return($querystring){

    $response = array();
    $this->result_object = $this->connection->query($querystring);
    if($this->result_object != FALSE) {
        if (!is_object($this->result_object)) {
            $last_id = $this->connection->insert_id;
            if (!empty($last_id)) {
                $response = $last_id;
            }
        }
        else {
            while ($row = mysqli_fetch_assoc($this->result_object)) {
                array_push($response, $row);
            }
        }
    }
    else{
        $response = PEAR::raiseError('There was a problem with the query: '. mysql_error());
    }
    return $response;
}

【问题讨论】:

  • 您插入的列是否具有 AUTO_INCREMENT 属性?

标签: php mysql sql


【解决方案1】:

Looking though the source 的 PHP 是 https://dev.mysql.com/doc/refman/5.0/en/mysql-stmt-insert-id.html 的包装器

本文档说明如下

LAST_INSERT_ID()(不带参数)返回一个 BIGINT(64 位)值,表示第一个自动生成的值 由最近执行的 INSERT 为 AUTO_INCREMENT 列设置 影响此类列的声明

https://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

我建议将您的 if 语句更改为

 if (!is_object($this->result_object)) {

这将检查是否有要检索的结果

PHP 文档可能应该更新以反映这一点,因为它表现出明显的行为

【讨论】:

  • 它不是直接包装器,它通过旧的 mysql_insert_id 并且该函数的文档似乎是正确的:php.net/manual/en/function.mysql-insert-id.php 并且还警告该值未重置。在文档中报告了一个错误,这是一个不错的发现。
  • 我不这么认为?该函数已从 php 中的当前 master 分支中删除
  • 链接中的第 1568 行怎么样?
  • 这不是PHP函数调用,PHP函数已被移除。
  • 供参考 bugs.php.net/bug.php?id=69400 是报告的错误,但旧函数确实记录了此行为。 MySQLi 也应该报告它
【解决方案2】:

这就是它的工作原理,mysqli_insert_id 仍然返回一个值,因为它是同一个连接。您需要关闭并打开一个新的,才能将其设置为 0。

【讨论】:

  • "如果最后一个查询不是 INSERT 或 UPDATE 语句,或者修改后的表没有具有 AUTO_INCREMENT 属性的列,则此函数将从文档返回零",也许文档应该会更新吗?
  • mysqli_insert_id 几乎可以肯定不会使用LAST_INSERT_ID() 来获取其价值。作为有线协议的一部分,服务器在插入后主动发送值。
【解决方案3】:

我相信该变量会保留上次调用的值。尝试添加一个 unset($last_id);如下所示。让我知道它是否不起作用。干杯。

public function __construct(){
    parent::__construct();
    //        @mysql_select_db ('public') OR die('Could not select the database: ' . mysql_error() );
    $this->connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_TABLE, DB_PORT)OR die ('Could not connect to MySQL: ' . mysql_error());
    $this->db = $this;
}

public function query_return($querystring){

    $response = array();
    $this->result_object = $this->connection->query($querystring);
    if($this->result_object != FALSE) {
        $last_id = $this->connection->insert_id;
        if (!empty($last_id)) {
            $response = $last_id;
        }
        else {
            while ($row = mysqli_fetch_assoc($this->result_object)) {
                array_push($response, $row);
            }
        }
        unset($last_id);    //<--------here
    }
    else{
        $response = PEAR::raiseError('There was a problem with the query: '. mysql_error());
    }
    return $response;


}

【讨论】:

  • 它是一个局部变量,它的值会在函数结束时被遗忘
猜你喜欢
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
  • 2020-11-10
  • 1970-01-01
  • 2021-08-27
相关资源
最近更新 更多