【问题标题】:PHP Mysqli statement returns a single row, -1 rows affected, and no errorPHP Mysqli 语句返回单行,-1 行受影响,并且没有错误
【发布时间】:2012-09-16 04:45:04
【问题描述】:

这太令人费解了,我一定是遗漏了一些简单的东西。我有一个查询来检查我插入的事务是否已经存在,以防止重复。代码如下:

function isaDupe($portableDB, $transactArray)
{
    $ref = $transactArray["reference"];
    $date = $transactArray["qdate"];
    $time =  $transactArray["time"];

  //prints the query so I can run by hand to test
    print "SELECT `counter` FROM transactions WHERE (`reference` = '$ref' AND `qdate` = '$date' AND `time` = '$time') ";

    if ($dupeSelectStmt = $portableDB->prepare("SELECT `counter` FROM transactions WHERE (`reference` = ? AND `qdate` = ? AND `time` = ?)"))
    {
        $dupeSelectStmt->bind_param('sss',$ref, $date, $time);
        $dupeSelectStmt->bind_result($counter);
        $dupeSelectStmt->execute();

        while ($dupeSelectStmt->fetch())
        {
            break;
        }

        $numRows = $portableDB->affected_rows;

        if ($numRows > 0)
            return TRUE;
        else if ($numRows == -1)
        {
            print " ERROR: ";
            print_r($portableDB->error);
            print_r($dupeSelectStmt->error);
            return FALSE;
        }
        else
            return FALSE;
    }
}

-如果我在同一台服务器上通过 Workbench 手动运行查询,我会返回 24 行。

--如果我手动准备、设置和执行语句,这也是一样的。

-affected_rows 返回 -1

--如果我对语句执行 num_rows 则相同

-Statement 或 MySQLi 对象上没有存储错误。

-如果我在 fetch() 语句中添加一个 print,它会打印一行的数据

-如果我将获取的行存储到一个数组中并计算结果,则为 1

-我试过用每个变量分别运行它,同样的事情。

-同一服务器上的其他查询(见鬼,在同一个 MySQLi 对象上)工作正常。选择、更新和插入。

【问题讨论】:

  • 您提到它适用于其他查询,它们是否也有多行响应?
  • 是的,它们是通过相同的 MySQLi 构造函数完成的
  • 您的实际代码是否有一段时间(获取)不做任何事情?如果你回显每一行? while ($row = $dupeSelectStmt->fetch())) { print_r($row); }
  • 啊哈!我忘了 $stmt->store_result();执行后!
  • 感谢您发布这个问题;在这里找到相同的问题和解决方案stackoverflow.com/q/5016253/469643

标签: php mysqli


【解决方案1】:

答案是我忘记在 mysqlistmt::execute() 之后调用 mysqlistmt::store_result。

一旦我添加了 $dupSelectStmt->store_result();我能够调用 $dupSelectStmt->num_rows 和 $portableDB->affected_rows 并且它们都显示了我知道我应该看到的 24。

【讨论】:

    【解决方案2】:

    您需要使用$dupeSelectStmt->num_rows() 来获取SELECT 结果集中的行数。您需要在mysqli_stmt 对象上调用affected_rows(用于插入、删除、更新)或num_rows(),而不是在数据库句柄($portableDB)上。

    【讨论】:

    • b.) 我提到我也尝试过 num_rows。问题不是调用“Store_results”
    • @RembrandtQ.Einstein 我不认为你是对的。这直接来自 PHP 手册:This function only works with queries which update a table. In order to get the number of rows from a SELECT query, use mysqli_stmt_num_rows() instead.php.net/manual/en/mysqli-stmt.affected-rows.php 我的意思是关于affected_rows() 的部分在 SELECT 上像 num_rows() 一样工作。您对不致电store_results() 的问题是正确的。
    • 那是一个声明。如果您在 mysqli 对象上调用受影响的行,它的工作方式就像 num_rows:php.net/manual/en/mysqli.affected-rows.php。此外,在没有 Store_result 的情况下,这也是同样的事情!为什么我需要调用 store_result?我调查了一下,但文档说它用于我显然没有使用的 mysqli_data_seek()。
    • @RembrandtQ.Einstein 啊,是的,您可以以这种方式使用mysql->affected_rows()。我一直认为最好使用 mysqli_stmt 函数,因为它们特定于执行的特定准备语句,而不是连接上的最后一个操作。
    • 关于mysqli->store_result(),我不确定这是必需的,除非您想缓冲客户端上的数据(在这种情况下是您的应用服务器)。不同之处在于,如果在fetch 之前使用store_result,则获取操作将与内存中的整个结果集一起工作,从而提供比在循环遍历结果集时必须加载和删除内存中的每个结果集行更好的性能。当然,这意味着使用store_result 会占用更多内存,因此如果您的结果集很大,可能会影响服务器的内存使用,您可能需要无缓冲数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    • 2011-04-09
    • 2013-01-08
    • 2016-09-24
    相关资源
    最近更新 更多