OSWikiHK: 請協力 GPLv3 的中文翻譯工作。
PEAR::DB SQL statement
OSWikiHK,自由中文開源知識庫
大家都應該知道什麼是 SQL,我也不想花時間在這類基本慨念問題 ,有興趣的可以到 http://www.onlamp.com/mysql/onlamp/general/mysql.csp ,裡面一些 SQL 的淺介。
SELECT 命令可算是 SQL 中最重要的命令,其他命令如 INSERT 、
UPDATE 和 DELETE 主要都是用作修改資料庫上的資料,
傳回結果也只是成功或失敗兩種。而 SELECT 命令就會傳回查詢得到的資料,
而這些資料可能佔用很大的資源,所以處理兩類命令亦有點分別。
目录 |
query 及 simpleQuery
前面的例子都顯示了要求資料庫執行 SQL 命令的動作是由
$dbh->query() 去做的,但其實還有個 $dbh->simpleQuery()
。事實上, $dbh->query() 本身都是透過 $dbh->simpleQuery()
去向資料庫發出執行 SQL 的要求。 $dbh->simpleQuery() 執行成功,
如執行的 SELECT 命令則會傳回有關資料庫的 result handle ,
其他則傳回 DB_OK 。 $dbh->query 的作用是把 simpleQuery()
傳回的 result handle 變成 DB_result 物件。在一般情況下
,我都建議大家用 $dbh->query 。
$dbh->quoteString($str)
quoteString 的作用是將和 addslashes 一樣,處理 $str
中引數 (', ") 這類可能會做成 SQL 命令語法錯誤的字元。例如:
$dbh->query("SELECT * FROM posts WHERE subj = '$subj'")
如果 $subj 的值是 "peter's box" , 中間含單引號,整個 SQL
命令就變成:
"SELECT * FROM posts WHERE subj = 'peter's box'"
做成語法錯誤。如果您事前經 quoteString 處理,問題就可以解法了:
$subj = $dbh->quoteString($subj);
$subj 如在 PostgreSQL 或 MySQL 就會變成 "peter\'s box" ,在 Oracle 則變成 "peter''s box" 。
要留意現時 PEAR 的 cvs 中,新增了一個方法 quote ,和 quoteString 的分別是 quote 還會在字串的前後加單引號。
prepare 、 execute 及 executeMultiple
其實有些資料庫管埋系統有提供預先編譯 SQL 命令的功能,可以加快查詢 的速度。
$sql = $dbh->prepare("INSERT INTO test_table (name) VALUES('test')");
for( $i = 0; $i < 10; $i++ ) {
$dbh->execute($sql);
}
以上例子和重覆執行十次同一句 INSERT 命令的結果一樣,但在一些資料庫管埋系統
,因為 INSERT 命令已預先被編譯,所以速度會較快。被編譯的 SQL 命令
亦可以有參數。
$data = array('mary', 'peter', 'john', 'robert');
$sql = $dbh->prepare("INSERT INTO test_table (id, name) VALUES(?, ?)");
for( $i = 0; $i < count($array); $i++ ) {
$dbh->execute($sql, array( $i, $name) );
}
$data = array(
array('mary', 'mary@foo.com'),
array('peter', 'peterl@bar.com'),
array('john', 'john@foo.com'),
array('robert', 'robert@baz.net')
);
$sql = $dbh->prepare("INSERT INTO test_table (name, mail) VALUES(?, ?)");
$dbh->executeMultiple($sql, $data);
prepare 等會自動幫您將參數用 quoteString 處理,所以您不用擔心
參數中的引號。但要留意 ? 只可以是實際的資料,您不可以以 table
名或欄名作為參數,以以下的用法都是錯誤的:
SELECT ?, name FROM test_table DELETE FROM ? WHERE id = ?
現時只有 InterBase 及 Oracle 支援 prepare 等方法,
未有支援的則由 PEAR::DB 模擬出來。
$dbh->limitQuery($query, $from, $count)
$dbh->limitQuery 的作用是只讀取查詢中的部份
結果,這對編寫網站程式很有作用。
<?php
$p = intVal($p);
$dbh = DB::connect('mysql://jrandom:@localhost/forum');
$dbh->setFetchMode(DB_FETCHMODE_ASSOC);
$sql = 'SELECT subj, author, posttime FROM posts ORDER BY posttime DESC';
$result = $dbh->limitQuery($sql, $p * 10, 10);
?>
<table>
<tr><td>Subject</td><td>Author</td><td>Time</td></tr>
<?php while ( $row = $result->resultRow() ) : ?>
<tr>
<td><?=$row['subj']?></td>
<td><?=$row['author']?></td>
<td><?=$row['posttime']?></td>
</tr>
<?php endwhile; ?>
</table>
<p>
<a href="<?=$PHP_SELF?>?p=<?=$p - 1?>">Prev</a> |
<a href="<?=$PHP_SELF?>?p=<?=$p + 1?>">Next</a>
</p>
作者: 來醫

