问题描述
我收到一条错误消息,指出绑定变量的数量与此行上准备好的语句中的字段数量不匹配
$query1->bind_result($book_id,$title,$isbn,$isbn13,$pubyear,$pubname);
除了我 100% 知道,因为该过程返回字段:book_id、book_title、isbn、isbn13、pubyear、pubname 的顺序。
<?PHP
declare(strict_types=1);
if(basename($_SERVER['SCRIPT_NAME']) == basename(__FILE__)) {
header('Location: /spabsa/PHProuter');
}
function showBooksByTitle()
{
include_once '../../blurg.inc';
# VALIDATE THIS YOU MORON!!
$title = $_POST['title'];
$db1 = new MysqLi('localhost','spabsa',$password,'STUspabsa');
if($db1->connect_errno > 0)
{
die('Unable to connect to database [' . $db1->connect_error . ']');
}
$query1 = $db1->prepare("call getbooksbytitle(?)");
$query1->bind_param('s',$title);
$query1->execute();
$query1->bind_result($book_id,$pubname);
while($query1->fetch()) {
echo '<a href="searh/bookinfo/' . $book_id . '">' . $title . '</a><br />';
echo $pubyear . '<br />';
echo $pubname . '<br />';
echo $isbn . '<br />';
echo $isbn13 . '<br />';
}
$query1->free_result();
$db1->close();
}
showBooksByTitle();
?>
流程如下
delimiter $
create procedure getbooksbytitle(booktitle char(200))
BEGIN
DECLARE searchterm CHAR(201);
set searchterm = "%";
IF CHAR_LENGTH(booktitle) > 0 THEN
set searchterm = concat(booktitle,'%');
SELECT gb.book_id,gb.title,gb.isbn,gb.isbn13,gb.pubyear,gp.pubname
FROM grbooks gb
JOIN grpublishers gp ON (gp.publisher_id=gb.publisher_id)
WHERE gb.title LIKE searchterm;
END IF;
END $
delimiter ;
解决方法
您的存储过程存在逻辑缺陷。当 booktitle
为空时,其长度将为 0,您的 SELECT 将永远不会执行。即使没有执行 SELECT,存储过程也总是返回空结果。但是,空结果没有列,因此您无法绑定到它。
从PHP调用SP非常麻烦。你应该尽可能避免它。在您的情况下,除了 SELECT 之外,SP 没有其他逻辑,这意味着您可以摆脱 SP 并使用普通的准备好的语句调用 SELECT。但是,如果您想解决空结果集的问题,那么我可能会建议使用 get_result()
而不是绑定。
$stmt->execute();
if ($result = $stmt->get_result()) {
foreach ($result as $row) {
echo '<a href="searh/bookinfo/' . $row['book_id'] . '">' . $row['title'] . '</a><br />';
echo $row['pubyear'] . '<br />';
echo $row['pubname'] . '<br />';
echo $row['isbn'] . '<br />';
echo $row['isbn13'] . '<br />';
}
$stmt->next_result(); // To consume the empty result
}
但我强烈建议重新设计 SP 或完全摆脱它。