【问题标题】:prepared statement causing while loop error准备好的语句导致while循环错误
【发布时间】:2010-10-05 16:17:42
【问题描述】:

我有以下简单的 mysqli php 应用程序,它应该可以正常工作。 $pk 被完美地接受并且是一个有效的 ARTICLE_NO,并且当直接由 mysql 执行时,查询可以完美地工作。我在每个事件之后都放置了输出语句,除了测试时执行之外的所有语句。永远不会进入 while 循环,我不确定为什么。

编辑:我已将问题缩小到返回 0 行的事实,但我不知道为什么 phpmyadmin 中的相同查询会给出正确的结果。

edit2:如果我摆脱了 while 循环而只拥有

    if (!$getRecords->fetch()) {
    printf("<p>ErrorNumber: %d\n", $getRecords->errno);
}

说明errno为0,所以没有取到任何记录,也没有错误,是一个有效的查询。

<?php
ini_set('display_errors', '1');
error_reporting(E_ALL);
$pk = $_GET["pk"];
$con = mysqli_connect("localhost", "", "", "");
if (!$con) {
    echo "Can't connect to MySQL Server. Errorcode: %s\n". mysqli_connect_error();
    exit;
}
$con->set_charset("utf8");
echo "test outside loop";
if(1 < 2) {
    echo "test inside loop";
    $query1 = 'SELECT ARTICLE_NO FROM AUCTIONS WHERE ARTICLE_NO = ?';
    if ($getRecords = $con->prepare($query1)) {
echo "inside second loop";
        $getRecords->bind_param("i", $pk);
echo "test after bind param";
        $getRecords->execute();
echo "test after bind execute";
        $getRecords->bind_result($ARTICLE_NO);
echo "test after bind result";
        while ($getRecords->fetch()) {
            echo "test inside while";
            echo "<h1>".$ARTICLE_NO."</h1>";
        }
    }
}

编辑:

我尝试使用此代码:

<?php
$mysqli = new mysqli("localhost", "", "", "");
$pk = $_GET["pk"];
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}
/* prepare statement */
if ($stmt = $mysqli->prepare("SELECT ARTICLE_NAME, WATCH FROM AUCTIONS WHERE ARTICLE_NO = ? LIMIT 5")) {
    $stmt->bind_param("i", $pk);
    $stmt->execute();
    /* bind variables to prepared statement */
    $stmt->bind_result($col1, $col2);
    /* fetch values */
    while ($stmt->fetch()) {
        printf("%s %s\n", $col1, $col2);
    }
    /* close statement */
    $stmt->close();
}
/* close connection */
$mysqli->close();
?>

这在没有 $pk 的情况下工作,如果我去掉参数它工作正常。通过 GET 获取 pk 不是问题,因为如果我指定 $pk = 1;相反,它仍然失败。 1 是有效的 ARTICLE_NO,SELECT ARTICLE_NAME, WATCH FROM AUCTIONS WHERE ARTICLE_NO = 1 LIMIT 5 在 phmyadmin 中工作正常。

编辑:问题是mysqli无法处理bigint,我现在使用k作为字符串,它工作正常。

【问题讨论】:

  • 我没有使用 bind_param,所以我只是在这里猜测,但这绝对正确:bind_param("i", $pk) 还是应该是 bind_param(1, $pk)?

标签: php mysql ajax mysqli


【解决方案1】:

检查以下值:

$getRecords->num_rows

这应该有助于揭示早期的 SELECT 是否实际上正在返回任何数据

您可能还需要添加:

$getRecords->store_result()

首先确保您已经完成了整个查询,然后再询问结果集中的行数。

另外 - 确保将 $pk 转换为整数!传入的值可能会被破坏。

【讨论】:

  • num_rows 为 0。我已将 pk 转换为整数无济于事,是否 pk 太长有关系吗?它的值是 110313660559。这个问题只发生在参数上
  • 是的,这可能很重要。 bind_param() 可能无法处理 bigint
  • 啊,有什么解决办法吗?
  • 在您的平台上,PHP 可能只有 32 位 int/long 类型。也许尝试忽略昨天问题的建议并将 $pk 视为字符串!
  • 另外,即使 $pk = 1 也会发生这种情况,这表明存在某种数据转换问题。
【解决方案2】:

我不确定您是否修改了该代码,但您似乎没有选择要连接的数据库。

如果这是问题,请使用 mysqli_select_db(...)。

编辑:看起来您也在使用大写的列、表名等。

正确区分大小写,这可能是您假设不区分大小写,因为它可以从命令行运行。据我所知,PHP 中的 mysqlI 驱动程序至少对列名区分大小写。

【讨论】:

  • 如果您检查前面的问题,您会发现数据库名称以及他的根用户名和密码...
  • 不,您不会,您会发现这些字段中填写了虚假信息。 Phil:我只是把所有的信息都注释掉了,我肯定是在选择数据库,Alnitak 无缘无故地制造麻烦。
  • 不完全是 - 几个月前您确实发布了包含密码的脚本。很高兴看到现在情况并非如此 :)
  • 我发布的密码是 geheim,它是德语的秘密。我从未公布过我的真实密码。
  • 刚刚发布了更新。可能是区分大小写吗?您将所有大写字符用于列名和表名。
猜你喜欢
  • 2012-07-07
  • 1970-01-01
  • 1970-01-01
  • 2019-11-04
  • 2018-08-29
  • 1970-01-01
  • 2013-12-17
  • 1970-01-01
相关资源
最近更新 更多