PHP Prepare语句 - 在while循环中获取有查询的错误

时间:2014-09-25 11:39:04

标签: php html mysql sql prepared-statement

我正在尝试使用查询执行查询。第一个循环显示所有客户数据,第二个循环显示该客户的订单。我到目前为止的代码:

$stmt = $conn->prepare("SELECT * FROM Customers 
                                  WHERE travel_Date >= ?
                                  AND   travel_Date <= ?
                                  ".$searchOption."
                                  LIMIT ? 
                                  OFFSET ?");
        $todayDateFrom = $todayDate." 00:00:00";
        $todayDateTo = $todayDate." 23:59:59";
        $stmt->bind_param("ssii", $todayDateFrom, $todayDateTo, $limit, $offset);
        $stmt->execute();
        /* bind variables to prepared statement */
        $stmt->bind_result($customer_ID, $name, $etc);

while ($stmt->fetch()) {
    $stmt_Order = $conn->prepare("SELECT * FROM Orders 
                                  WHERE customer_ID= ?");
    $stmt_Order->bind_param("i", $customer_ID);
    $stmt_Order->execute();
    $stmt_Order->bind_result($order_ID, $order_Name);
}

第一个循环对我来说很好,当我添加第二个查询时,我得到以下错误:

必须在

中进行新的语句准备之前获取所有数据

与此行有关:

$stmt_Order = $conn->prepare("SELECT * FROM Orders 
                              WHERE customer_ID= ?");

中的非对象上调用成员函数bind_param()

这与这一行有关:

$stmt_Order->bind_param("i", $cust_Customer_ID);

我不明白发生了什么。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

如果您与MySQL交谈,您一次只能提出一个问题(查询)。你必须等待完整的回复,然后再问下一个。在您的情况下,第一个查询返回多个响应 - 并且在收集所有行之前运行第二个查询。

在PHP中,您有缓冲和非缓冲SQL请求的函数(在您的情况下为$stmt->store_result())。缓冲意味着:整个响应从MySQL收集并由PHP缓冲。有关Buffered and Unbuffered queries

的详细信息,请查看PHP手册

因此,无论何时在查询中需要查询,都必须缓冲外部查询。使用mysqli_stmt时,请检查mysqli_stmt::store_result()。还可以选择将所有行收集到数组中,然后通过此数组执行辅助查询(请参阅来自iNaD的回答)。

注意:使用大型数据集时,缓冲结果可能需要大量内存。完美的SQL解决方案是LEFT JOIN。这也可以帮助您避免运行持久的查询,这非常慢。

$stmt = $conn->prepare("SELECT * FROM Customers c
                              LEFT JOIN Orders o ON (o.customer_ID = c.id)
                              WHERE travel_Date >= ?
                              AND   travel_Date <= ?
                              ".$searchOption."
                              LIMIT ? 
                              OFFSET ?");

BurninLeo

答案 1 :(得分:1)

编辑我的回答是错误的,我认为这些是基于PDO的语句,但是使用了mysqli。 但是fetch_all仍应提供帮助:

http://php.net/manual/en/mysqli-result.fetch-all.php


无法尝试,但这应该有效:

$stmt = $conn->prepare("SELECT * FROM Customers 
                              WHERE travel_Date >= ?
                              AND   travel_Date <= ?
                              ".$searchOption."
                              LIMIT ? 
                              OFFSET ?");
$todayDateFrom = $todayDate." 00:00:00";
$todayDateTo = $todayDate." 23:59:59";
$stmt->bind_param("ssii", $todayDateFrom, $todayDateTo, $limit, $offset);
$stmt->execute();
/* bind variables to prepared statement */
$stmt->bind_result($customer_ID, $name, $etc);

foreach ($stmt->fetch_all() as $customer) {
    $stmt_Order = $conn->prepare("SELECT * FROM Orders 
                              WHERE customer_ID= ?");
    $stmt_Order->bind_param("i", $customer_ID);
    $stmt_Order->execute();
    $stmt_Order->bind_result($order_ID, $order_Name);
}

->fetch_all()获取所有结果,因此查询已“完成”。这允许您启动另一个语句。 希望它有效。

答案 2 :(得分:0)

我想你可以替换这段代码

   while ($stmt->fetch()) {

而你可以写

   while ($row = $stmt->fetch()) {