|
今天我來系統地學習一下PDO |
一派護法 十九級 |
|
一派護法 十九級 |
不過這樣的話,就無法得到生成的SQL字符串了。。。
|
一派護法 十九級 |
$address = "Delaware St";
$sql = "SELECT * FROM WiFiHotSpots WHERE ItemName = ? AND ItemID < 15 AND ItemAddress = ?"; $stmt = $dbh->prepare($sql); $stmt->execute(array($name, $address)); $row = $stmt->fetch(); echo "(" . $row["ItemLatitude"] . ", " . $row["ItemLongitude"] . ")";
|
一派護法 十九級 |
判斷記錄集是否為空: if (!$stmt->rowCount()) { echo "記錄集為空"; }
|
一派護法 十九級 |
$stmt->rowCount()可以直接當布爾值用。
|
一派護法 十九級 |
原始方法: if (mysql_num_rows($rs) == 0) { echo "記錄集為空"; }
|
一派護法 十九級 |
|
一派護法 十九級 |
Error
SQL query:
SELECT * FROM WiFiHotSpots WHERE ItemName = ? AND ItemID < 15 AND ItemAddress = ?
LIMIT 0, 25
MySQL said:
#1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use
near '? AND ItemID < 15 AND ItemAddress = ?
LIMIT 0, 25' at line 1
|
一派護法 十九級 |
bindColumn的用法: <?php include_once("conn.php");
$sql = "SELECT * FROM WiFiHotSpots"; $stmt = $dbh->prepare($sql); $stmt->execute();
$stmt->bindColumn("ItemSuburb", $suburb); foreach ($stmt as $row) { echo $suburb . "<br>"; // $suburb is equivalent to $row["ItemSuburb"] } ?>
|
一派護法 十九級 |
bindColumn將一個字段綁定到一個php變量中,也就是每次循環自動執行: $suburb = $row["ItemSuburb"]
|
一派護法 十九級 |
$stmt->bindColumn("ItemSuburb", $suburb, PDO::PARAM_STR); 相當於$suburb = (string)$row["ItemSuburb"];
|
一派護法 十九級 |
回復:33樓 為了排查SQL的錯誤,可以使用errorInfo直接獲取MySQL輸出的錯誤信息,不用再把輸出的SQL語句複製到PMA中執行了。 比如: $sql = "SELECT * AFROM WiFiHotSpots"; $dbh->query($sql); $error = $dbh->errorInfo(); echo $error[2]; 輸出: You have an error in your SQL syntax; check the manual that corresponds
to your MariaDB server version for the right syntax to use near 'AFROM
WiFiHotSpots' at line 1
|
一派護法 十九級 |
回復:43樓 這樣我們就可以直接看出這個SQL語句中的AFROM出問題了
|
一派護法 十九級 |
|
一派護法 十九級 |
方法 bindParam() 和 bindValue() 非常相似。 唯一的区别就是前者使用一个PHP变量绑定参数,而后者使用一个值。 所以使用bindParam是第二个参数只能用变量名,而不能用变量值,而bindValue至可以使用具体值。 http://www.360doc.com/content/12/0703/16/10337467_222033042.shtml
|
一派護法 十九級 |
fetch();和mysql_fetch_array();一樣 但fetchAll();返回一個二維數組,可以獲取所有行。
|
一派護法 十九級 |
以後要排查sql的錯誤直接用errorInfo,不要再把SQL語句複製到PMA里執行了。而且也沒有辦法獲得最終的SQL語句。
|
一派護法 十九級 |
我還是要硬着頭皮看英文版的PHP文檔,雖然閱讀速度比中文慢了很多,但這是一個適應的過程。
|
一派護法 十九級 |
PDO — The PDO class
PDO::beginTransaction — Initiates a transaction PDO::commit — Commits a transaction PDO::__construct — Creates a PDO instance representing a connection to a database PDO::errorCode — Fetch the SQLSTATE associated with the last operation on the database handle PDO::errorInfo — Fetch extended error information associated with the last operation on the database handle PDO::exec — Execute an SQL statement and return the number of affected rows PDO::getAttribute — Retrieve a database connection attribute PDO::getAvailableDrivers — Return an array of available PDO drivers PDO::inTransaction — Checks if inside a transaction PDO::lastInsertId — Returns the ID of the last inserted row or sequence value PDO::prepare — Prepares a statement for execution and returns a statement object PDO::query — Executes an SQL statement, returning a result set as a PDOStatement object PDO::quote — Quotes a string for use in a query. PDO::rollBack — Rolls back a transaction PDO::setAttribute — Set an attribute PDOStatement — The PDOStatement class
PDOStatement::bindColumn — Bind a column to a PHP variable PDOStatement::bindParam — Binds a parameter to the specified variable name PDOStatement::bindValue — Binds a value to a parameter PDOStatement::closeCursor — Closes the cursor, enabling the statement to be executed again. PDOStatement::columnCount — Returns the number of columns in the result set PDOStatement::debugDumpParams — Dump an SQL prepared command PDOStatement::errorCode — Fetch the SQLSTATE associated with the last operation on the statement handle PDOStatement::errorInfo — Fetch extended error information associated with the last operation on the statement handle PDOStatement::execute — Executes a prepared statement PDOStatement::fetch — Fetches the next row from a result set PDOStatement::fetchAll — Returns an array containing all of the result set rows PDOStatement::fetchColumn — Returns a single column from the next row of a result set PDOStatement::fetchObject — Fetches the next row and returns it as an object. PDOStatement::getAttribute — Retrieve a statement attribute PDOStatement::getColumnMeta — Returns metadata for a column in a result set PDOStatement::nextRowset — Advances to the next rowset in a multi-rowset statement handle PDOStatement::rowCount — Returns the number of rows affected by the last SQL statement PDOStatement::setAttribute — Set a statement attribute PDOStatement::setFetchMode — Set the default fetch mode for this statement
|
一派護法 十九級 |
exec的用法: $sql = "INSERT INTO `timetest` VALUES (null, NOW())"; $num = $dbh->exec($sql); echo "影響了{$num}行。";
輸出:影響了1行。
|
一派護法 十九級 |
$sql = "INSERT INTO `timetest` VALUES (null, NOW())"; $successful = $dbh->exec($sql); if ($successful) { echo "插入記錄成功"; }
|
一派護法 十九級 |
回復:54樓 這段代碼如果改寫成mysql原來的代碼,就很複雜,除了執行mysql_query($sql),還需要執行mysql_affected_rows() 因為對於插入、刪除、修改的SQL語句,mysql_query始終返回true
|
一派護法 十九級 |
PDO::query() returns a PDOStatement object, or FALSE
on failure. query主要用於SELECT語句,返回PDOStatement對象
|
一派護法 十九級 |
$content = join(", ", PDO::getAvailableDrivers()); if (!empty($content)) { $sql = "INSERT INTO Contents (Content, TimeCreated) VALUES (:content, NOW())"; $stmt = $dbh->prepare($sql); $stmt->bindParam(":content", $content); $successful = $stmt->execute(); if ($successful) { $num = $stmt->rowCount(); echo "插入了{$num}條記錄。"; } else { echo "插入記錄失敗!"; } } else { echo "沒有內容"; }
|
一派護法 十九級 |
$content = join(", ", PDO::getAvailableDrivers()); if (!empty($content)) { $sql = "SELECT * FROM Contents WHERE Content = ?"; $stmt = $dbh->prepare($sql); $stmt->execute(array($content)); if ($stmt->rowCount()){ echo "數據表中已經有相同的內容了。"; } else { $sql = "INSERT INTO Contents (Content, TimeCreated) VALUES (:content, NOW())"; $stmt = $dbh->prepare($sql); $stmt->bindParam(":content", $content); $successful = $stmt->execute(); if ($successful) { $num = $stmt->rowCount(); echo "插入了{$num}條記錄。"; } else { echo "插入記錄失敗!"; } } } else { echo "沒有內容"; }
|
一派護法 十九級 |
bindValue的用法 $sql = "SELECT * FROM Contents WHERE Content = ?"; $stmt = $dbh->prepare($sql); $stmt->bindValue(1, $content); $stmt->execute();
|
一派護法 十九級 |
對於$stmt->queryString這個屬性,輸出內容如下: INSERT INTO Contents (Content, TimeCreated) VALUES (:content, NOW()) 也就是語句中仍然沒有包含具體的值。
if ($successful) { $num = $stmt->rowCount(); echo "插入了{$num}條記錄。<br>"; echo $stmt->queryString; } else { echo "插入記錄失敗!"; }
|
一派護法 十九級 |
$dbh->beginTransaction(); $content = "數據表中已經有相同的內容了。"; if (!empty($content)) { $sql = "SELECT * FROM Contents WHERE Content = ?"; $stmt = $dbh->prepare($sql); $stmt->execute(array($content)); /*$stmt->bindValue(1, $content); $stmt->execute();*/ if ($stmt->rowCount()){ echo "數據表中已經有相同的內容了。"; } else { $sql = "INSERT INTO Contents (Content, TimeCreated) VALUES (:content, NOW())"; $stmt = $dbh->prepare($sql); $stmt->bindParam(":content", $content); $successful = $stmt->execute(); $dbh->rollBack(); echo "rollback"; /*if ($successful) { $num = $stmt->rowCount(); echo "插入了{$num}條記錄。"; //echo $stmt->queryString; } else { echo "插入記錄失敗!"; }*/ } } else { echo "沒有內容"; }
|
一派護法 十九級 |
發現一個嚴重的問題,雖然rollback了,但是AUTO_INCREMENT卻增加了!!!!
|
一派護法 十九級 |
|