我已经关注了一些关于在预准备语句中使用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();
现在除了第一个以外,所有需要的条目都被添加到$ row []。为什么不添加第一个条目? 提前谢谢!
答案 0 :(得分:21)
编辑 07/2015(问题自原始答案以来已被编辑,但基本原则相同)
从不 SELECT *
在生产环境中,它只会以奇怪的,不可预测的,看似无关的方式回过头来咬你。通过指定所需的列,您将确保列排序,数据类型,约束和各种其他元素从长远来看不会给您带来任何问题。
这个答案仍然大部分都是有效的,所以我会把它留在原处,但主要的用处是:使用PDO,它可以做到98%的你需要的东西更清洁,更简洁API在同一个后端。如果您需要更复杂的RDBMS特定API,那么您已经了解了所遇到的问题以及为什么需要使用mysqli等。
SELECT *
不能很好地工作。这是我推荐PDO的主要原因之一 - 这是将变量引用而不是值绑定到参数的荒谬要求。
$stmt->bind_result($row);
这不会将结果行绑定到变量,它只会绑定一个列。而且因为您使用了SELECT *
,所以它无法满足您的需求。
如果你确实想使用MySQLi而不是PDO(正如我所说的那样,我会推荐),有一些很好的例子可以说明this one在{{3}}上的SELECT *
bind_result()
1}}手册页。
或者您只需指定要检索的列:
$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();
编辑根据您的新代码,您应该这样做:
// $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
}
答案 1 :(得分:3)
我认为你必须绑定到bind_results()中的列,如
/* prepare statement */
if ($stmt = $mysqli->prepare("SELECT Code, Name FROM Country ORDER BY Name LIMIT 5")) {
$stmt->execute();
/* bind variables to prepared statement */
$stmt->bind_result($col1, $col2);
/* fetch values */
while ($stmt->fetch()) {
printf("%s %s\n", $col1, $col2);
}
这里$ col1和$ col2绑定到Country表的Code和Name列
(而不是SELECT中的*使用列名)
答案 2 :(得分:1)
除了最简单的单行预期查询之外,mysqli完全不喜欢“ bind_result”。
将整行填充到单个数组项中的做法最好是:
$stmt->execute();
$result = $stmt->get_result();
while ($data = $result->fetch_assoc())
{
$retvar[] = $data;
}
$stmt->close();
或
while ($data = $result->fetch_row())
如果您不需要/不需要字段名称。