PDO::query(PHP環境下同)和PDOStatement::execute函數均能實現SELECT查詢功能,但官方文檔並未見對此設計初衷的說明,此外還有個PDO::exec函數功能也很類似。天緣自己也很納悶(也可能未發現或是未能完全理解),既然PDO::query函數功能做的如此單一,而且還和exec、execute之間有交疊,那為何不重新調整部分函數執行方法,只保留一個或保留兩個足夠,難道只是照顧到一些傳統編程人員的習慣?下面是官方給這三個函數定義:
PDO::exec — Execute an SQL statement and return the number of affected rows PDO::query — Executes an SQL statement, returning a result set as a PDOStatement object PDOStatement::execute — Executes a prepared statement
原文參見:http://www.php.net/manual/en/book.pdo.php
特別注意:PDO::exec跟PDOStatement::execute是兩個不同函數,前者跟PDO::query地位是並列的,而後者則是PDOStament類下子函數。
PDO::query執行一條SQL語句,如果通過,則返回一個PDOStatement對象。PDO::query函數有個“非常好處”,就是可以直接遍歷這個返回的記錄集。
示例如下:
$sql = 'SELECT name FROM url'; foreach ($dbh->query($sql) as $row) { print $row['name'] . "\t"; }
query同傳統的mysql query函數類似,同樣需要對開發者自行對輸入的sql語句進行安全檢查。
query因為會返回PDOStament對象,似乎用在SELECT語句執行上更合適,這跟上文提到的query支持直接遍歷不謀而合。
query執行後,在下一次query執行之前,如果不取走所有返回的記錄集,則query將會執行失敗,除非我們調用 PDOStatement::closeCursor()來釋放數據庫資源與PDOStatement對象。
原話:If you do not fetch all of the data in a result set before issuing your next call to PDO::query(), your call may fail. Call PDOStatement::closeCursor() to release the database resources associated with the PDOStatement object before issuing your next call to PDO::query().
PDO::exec執行一條SQL語句,並返回受影響的行數。此函數不會返回結果集合。官方建議:
PDO::exec支持SELECT/DELETE/UPDATE/INSERT等全部SQL語句執行,所以相比PDO query()函數功能要強大的多。由於只返回受影響的函數,所以,如果執行SELECT則無法得到PDOStatement對象,故也無法遍歷結果集,只能按照官方建議去使用query或execute函數。
再看一下PDOStatement::execute函數,execute函數是用於執行已經預處理過的語句,只是返回執行結果成功或失敗。也就是說execute需要配合prepare函數使用,這個的確是麻煩了一點,每次都要先prepare,然後才能exec。所以,如果執行SELECT等SQL語句,則還需要借助fetch等函數進行結果讀取(當然上文的query也是可使用fetch等函數)。
execute支持綁定參數,無需考慮安全問題(綁定時!其它語句還需要自己考慮),示例如下:
$sth= $dbh->prepare('SELECT name FROM foo WHERE width < :width AND height = :height'); $sth->bindParam(':width', $width); $sth->bindParam(':height', $height); $sth->execute();
execute支持多次運行,這在某些方面,有助於性能提升。示例如下:
$sth = $db->prepare("SELECT * FROM foo WHERE width = ?"); $sth->execute(array(1)); $results = $sth->fetchAll(PDO::FETCH_ASSOC); $sth->execute(array(2)); $results = $sth->fetchAll(PDO::FETCH_ASSOC);
盡管PDOStatement::execute也很強大,但跟PDO::exec地位是不同的,不可混淆。