在准备好的语句中执行SELECT查询时遇到问题

Gle*_*ito 9 php mysqli prepared-statement

我已经关注了一些关于在预准备语句中使用SELECT的不同示例,但没有返回任何内容. 编辑我已经改变了我的代码看起来像这样:

$date1 = 2012-01-01;
$date2 = 2012-01-31;
$sql_con = new mysqli('db', 'username', 'password', 'database');

if($stmt = $sql_con->prepare("SELECT eventLogID FROM Country WHERE countryCode=? AND date BETWEEN ? AND ?")){

   $stmt->bind_param("sss", $country_code, $date1,$date2); 

    $stmt->execute();

  $i=0;
  while ($stmt->fetch()){
  $stmt->bind_result($row[$i]);
  $i++;
  }

  $stmt->close();
$sql_con->close();
Run Code Online (Sandbox Code Playgroud)

现在除了第一个之外的所有所需条目都被添加到$ row [].为什么不添加第一个条目?提前致谢!

Dav*_*dom 22

编辑 07/2015(问题自原始答案以来已编辑,但基本原则相同)

从来没有 SELECT *在生产环境中,它只会以奇怪的,不可预测的和看似无关的方式回过头来咬你.通过指定所需的列,您将确保列排序,数据类型,约束和各种其他元素从长远来看不会导致问题.

这个答案仍然大部分是有效的,所以我会把它留在原处,但主要的用处是:使用PDO,它可以提供98%的所需东西,使用更清洁,更简洁的API.同样的后端.如果您需要更复杂的RDBMS特定API,那么您已经了解了所遇到的问题以及为什么需要使用mysqli等.


SELECT *使用MySQLi编写的语句不能很好地工作.这是我推荐PDO的主要原因之一- 这和将变量引用而不是值绑定到参数的荒谬要求.

$stmt->bind_result($row);
Run Code Online (Sandbox Code Playgroud)

这不是将结果绑定到变量,它只是绑定一个列.而且因为你已经使用过SELECT *,它没有按你的意愿行事.

如果你想使用的MySQLi比PDO(正如我说的,我会建议)有几个很好的例子如何SELECT *在这样的评论这一块上的bind_result()手册页.

或者您只需指定要检索的列:

$sql_con = new mysqli('db', 'username', 'password', 'database');

if($stmt = $sql_con->prepare("SELECT name, countryCode FROM Country WHERE countryCode = ?")) {

   $stmt->bind_param("s", $country_code); 
   $stmt->execute(); 
   $stmt->bind_result($name, $countryCode);

   while ($stmt->fetch()) {
     // Because $name and $countryCode are passed by reference, their value
     // changes on every iteration to reflect the current row
     echo "<pre>";
     echo "name: $name\n";
     echo "countryCode: $countryCode\n";
     echo "</pre>";
   }

   $stmt->close();
Run Code Online (Sandbox Code Playgroud)

根据您的新代码编辑,您应该这样做:

// $date1 will be int(2010), $date2 will be int(1980) because you didn't
// quote the strings!
//$date1 = 2012-01-01;
//$date2 = 2012-01-31;

// Connect to DB
$sql_con = new mysqli('db', 'username', 'password', 'database');

// Check for connection errors here!

// The query we want to execute
$sql = "
  SELECT eventLogID
  FROM Country
  WHERE countryCode = ?
  AND date BETWEEN ? AND ?
";

// Attempt to prepare the query
if ($stmt = $sql_con->prepare($sql)) {

  // Pass the parameters
  $date1 = '2012-01-01';
  $date2 = '2012-01-31';
  $stmt->bind_param("sss", $country_code, $date1, $date2); 

  // Execute the query
  $stmt->execute();
  if (!$stmt->errno) {
    // Handle error here
  }

  // Pass a variable to hold the result
  // Remember you are binding a *column*, not a row
  $stmt->bind_result($eventLogID);

  // Loop the results and fetch into an array
  $logIds = array();
  while ($stmt->fetch()) {
    $logIds[] = $eventLogID;
  }

  // Tidy up
  $stmt->close();
  $sql_con->close();

  // Do something with the results
  print_r($logIds);

} else {
  // Handle error here
}
Run Code Online (Sandbox Code Playgroud)