[英]Fatal Error in mysqli prepared statement
我正在嘗試使用下面的一些示例代碼來學習如何編寫准備好的語句。
我有一個初始SQL語句,對於該返回的每個記錄,針對返回的結果執行另一個SQL檢查。
<?php
$sql_b = "SELECT fld_title, fld_tag FROM j_oracle_cat WHERE fld_tag IS NOT NULL ORDER BY fld_title";
if (!$result_b = $conn -> query($sql_b)) {
die('There was an error running the query [' . $conn -> error . ']');
} else {
if (!$result_b -> num_rows) {
echo "<h4>No Categories Defined</h4>";
} else {
while($row_b = $result_b -> fetch_assoc()) {
$cat_ttl = $row_b["fld_title"];
$cat_tag = $row_b["fld_tag"];
echo "<h4><a href='category.php?tag=" . $cat_tag . "'>" . $cat_ttl . "</a></h4>";
$sql_c = "SELECT p.fld_tag FROM j_oracle_cat c, j_oracle_pages p WHERE c.fld_id = p.fld_catid AND c.fld_tag = ?";
/* Prepare statement */
$stmt = $conn->prepare($sql_c);
if($stmt === false) {
trigger_error('Wrong SQL: ' . $sql_c . '<hr />Error: ' . $conn->error, E_USER_ERROR);
}
/* Bind parameters. Types: s = string, i = integer, d = double, b = blob */
$stmt->bind_param('s',$cat_tag);
/* Execute statement */
$stmt->execute();
}
$result_b -> free();
}
}
?>
當我運行代碼時,它可以做到這一點:
<h4><a href='category.php?tag=accounts-payable'>Accounts Payable</a></h4>
<h4><a href='category.php?tag=accounts-receivable'>Accounts Receivable</a></h4>
但隨后出現以下錯誤:
致命錯誤 :錯誤的SQL:從j_oracle_cat c,j_oracle_pages p中選擇p.fld_is_parent,c.fld_id = p.fld_catid和c.fld_tag =嗎? 錯誤:第95行的C:\\ xampp \\ htdocs \\ php \\ a.php中
95行就是這個:
trigger_error('Wrong SQL: ' . $sql_c . '<hr />Error: ' . $conn->error, E_USER_ERROR);
表結構:
CREATE TABLE `j_oracle_cat` (
`fld_id` int(11) NOT NULL AUTO_INCREMENT,
`fld_title` varchar(255) DEFAULT NULL,
`fld_desc` varchar(255) DEFAULT NULL,
`fld_tag` varchar(255) DEFAULT NULL,
`fld_label` varchar(255) DEFAULT NULL,
`fld_parent` int(2) DEFAULT '0',
PRIMARY KEY (`fld_id`)
) ENGINE=MyISAM AUTO_INCREMENT=16 DEFAULT CHARSET=latin1
CREATE TABLE `j_oracle_pages` (
`fld_id` int(11) NOT NULL AUTO_INCREMENT,
`fld_title` varchar(255) DEFAULT NULL,
`fld_catid` int(11) DEFAULT NULL,
`fld_cols` int(2) DEFAULT '1',
`fld_left` text,
`fld_content` text,
`fld_tag` varchar(255) DEFAULT NULL,
`fld_date` date DEFAULT NULL,
`fld_is_parent` char(1) DEFAULT NULL,
PRIMARY KEY (`fld_id`)
) ENGINE=MyISAM AUTO_INCREMENT=83 DEFAULT CHARSET=latin1
我試過直接運行sql並沒有錯誤,對於示例標簽,它返回例如3行:
SELECT p.fld_tag FROM j_oracle_cat c, j_oracle_pages p WHERE c.fld_id = p.fld_catid AND c.fld_tag = 'accounts-receivable';
連接到數據庫:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "mydb";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
if($conn -> connect_errno > 0){
die('Unable to connect to database [' . $conn->connect_error . ']');
}
?>
大概我在做些愚蠢的事情,但是我看不到什么?
所以這是我的建議; 我沒有發現您的代碼有任何明顯的錯誤,但是這些步驟應該可以更輕松地診斷問題,即使不能完全解決問題。 首先,將prepare()
調用移出循環*。 接下來, 顯式創建statement對象 ,這樣,如果准備工作存在問題,則可以直接從Statement對象獲取錯誤。 最后,在流程的每個階段檢查有效的返回值,包括參數綁定和語句執行 。
$sql_b = "SELECT fld_title, fld_tag FROM j_oracle_cat WHERE fld_tag IS NOT NULL ORDER BY fld_title";
if (!$result_b = $conn->query($sql_b)) {
trigger_error("Error executing query: $conn->error<br/>SQL query: $sql_b", E_USER_ERROR);
} else {
if (!$result_b->num_rows) {
echo "<h4>No Categories Defined</h4>";
} else {
/* Prepare statement */
$sql_c = "SELECT p.fld_tag FROM j_oracle_cat c, j_oracle_pages p WHERE c.fld_id = p.fld_catid AND c.fld_tag = ?";
$stmt = $conn->stmt_init();
if (!$stmt) {
trigger_error("Error creating statement: $conn->error", E_USER_ERROR);
}
$result = $stmt->prepare($sql_c);
if(!$result) {
trigger_error("Error preparing statement: $stmt->error<br/>SQL query: $sql_c", E_USER_ERROR);
}
/* Bind parameters. Types: s = string, i = integer, d = double, b = blob */
// needs a dummy value for the initial bind
$row_b = array("fld_tag"=>"");
$result = $stmt->bind_param("s", $row_b["fld_tag"]);
if(!$result) {
trigger_error("Error binding parameter: $stmt->error<br/>", E_USER_ERROR);
}
while($row_b = $result_b -> fetch_assoc()) {
$cat_ttl = htmlspecialchars($row_b["fld_title"]);
$cat_tag = htmlspecialchars($row_b["fld_tag"]);
echo "<h4><a href='category.php?tag=$cat_tag'>$cat_ttl</a></h4>";
/* Execute statement */
$result = $stmt->execute();
if(!$result) {
trigger_error("Error executing statement: $stmt->error<br/>Bound parameter value: $row_b[fld_tag]", E_USER_ERROR);
}
// I assume you'll be doing something with $result down here?
}
$result_b->free();
$stmt->close();
}
}
附帶說明:在將數據庫結果放入HTML之前,應始終使用htmlspecialchars()
進行轉義,以避免注入的風險。 您可以使用雙引號將變量包含在字符串中,並避免使用許多不必要的.
操作員無處不在。 這是個人喜好問題,但許多人認為它更具可讀性。
*預准備語句的一大好處是它們將查詢的准備與執行分開 ,從而避免了設置MySQL以運行查詢所帶來的開銷。 通過反復准備一份聲明,您可以完全刪除該好處。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.