給新手用戶的快速提示:當從維護資料庫連線的網頁表單欄位收集輸入時,*永遠不要*使用 pg_query 從欄位執行查詢。請務必使用 pg_prepare 和 pg_execute 對輸入進行過濾。
(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)
pg_query — 執行查詢
pg_query() 會在指定的資料庫 connection
連線上執行 query
。在大多數情況下,建議使用 pg_query_params()。
如果發生錯誤並返回 false
,則在連線有效的情況下,可以使用 pg_last_error() 函式取得錯誤的詳細資訊。
注意: 雖然可以省略
connection
參數,但不建議這樣做,因為這可能會導致腳本中難以發現的錯誤。
注意事項:
此函式以前稱為 pg_exec()。基於相容性考量,pg_exec() 仍然可用,但鼓勵使用者使用新的名稱。
connection
一個 PgSql\Connection 實例。當未指定 connection
時,將使用預設連線。預設連線是 pg_connect() 或 pg_pconnect() 建立的最後一個連線。
從 PHP 8.1.0 開始,不建議使用預設連線。
query
要執行的 SQL 陳述式。當傳遞多個陳述式給函式時,除非查詢字串中包含明確的 BEGIN/COMMIT 命令,否則它們會自動作為一個事務執行。然而,不建議在一個函式呼叫中使用多個事務。
使用者提供資料的字串插值非常危險,而且可能導致 SQL 注入 漏洞。在大多數情況下,應該優先使用 pg_query_params(),將使用者提供的數值作為參數傳遞,而不是將它們替換到查詢字串中。
任何直接替換到查詢字串中的使用者提供資料都應該 正確地跳脫。
成功時返回 PgSql\Result 實例,失敗時返回 false
。
版本 | 說明 |
---|---|
8.1.0 | 現在返回 PgSql\Result 實例;以前返回的是 資源。 |
8.1.0 | connection 參數現在需要一個 PgSql\Connection 實例;以前需要的是 資源。 |
範例 #1 pg_query() 範例
<?php
$conn = pg_pconnect("dbname=publisher");
if (!$conn) {
echo "發生錯誤。\n";
exit;
}
$result = pg_query($conn, "SELECT author, email FROM authors");
if (!$result) {
echo "發生錯誤。\n";
exit;
}
while ($row = pg_fetch_row($result)) {
echo "作者: $row[0] 電子郵件: $row[1]";
echo "<br />\n";
}
?>
範例 #2 使用 pg_query() 執行多個語句
<?php
$conn = pg_pconnect("dbname=publisher");
// 這些語句將作為一個事務執行
$query = "UPDATE authors SET author=UPPER(author) WHERE id=1;";
$query .= "UPDATE authors SET author=LOWER(author) WHERE id=2;";
$query .= "UPDATE authors SET author=NULL WHERE id=3;";
pg_query($conn, $query);
?>
給新手用戶的快速提示:當從維護資料庫連線的網頁表單欄位收集輸入時,*永遠不要*使用 pg_query 從欄位執行查詢。請務必使用 pg_prepare 和 pg_execute 對輸入進行過濾。
這樣會更好
<?php
$result=pg_query($conn, "SELECT COUNT(*) AS rows FROM x WHERE a=b;");
if (!$result) {
echo "query did not execute";
}
if ($line = pg_fetch_assoc($result)) {
if ($line['rows'] == 0) {
echo "0 records"
}
}
else {
while ($row = pg_fetch_array($result)) {
//處理 $row
}
}
?>
這個解決方案不會因為移動符合條件的列(可能是 0、1 列,也可能是 100、1000、……列)而增加系統負載。
擴展 "cmoore" 留下的註記 -
要檢查記錄集是否沒有返回任何記錄,
<?php
$result=pg_query($conn, "SELECT * FROM x WHERE a=b;");
if (!$result) {
echo "query did not execute";
}
$rs = pg_fetch_assoc($result);
if (!$rs) {
echo "0 records"
}
?>
-jack
$GLOBALS["PG_CONNECT"]=pg_connect(...);
....
function query ($sqlQuery,$var=0) {
if (!$GLOBALS["PG_CONNECT"]) return 0;
$lev=error_reporting (8); //不要警告!!
$result=pg_query ($sqlQuery);
error_reporting ($lev); //預設!!
if (strlen ($r=pg_last_error ($GLOBALS["PG_CONNECT"]))) {
if ($var) {
echo "<p color=\"red\">錯誤:<pre>";
echo $sqlQuery;
echo "</pre>";
echo $r;
echo "</p>";
}
close_db ();
return 0;
}
return $result;
}
有一點需要注意,一開始我並沒有注意到。如果您的查詢返回零列,那並非「失敗」的查詢。所以以下寫法是錯誤的
$result=pg_query($conn, "SELECT * FROM x WHERE a=b;");
if (!$result) {
echo "x 中沒有 a=b\n";
}
如果查詢因故無法執行,pg_query 會返回 FALSE。如果查詢已執行但返回零列,則您會得到一個沒有列的結果。
我發布的程式碼中有一個錯字
<?php
$result=pg_query($conn, "SELECT * FROM x WHERE a=b;");
if (!$result) {
echo "查詢未執行";
}
if (pg_num_rows($result) == 0) {
echo "0 筆記錄"
}
else {
while ($row = pg_fetch_array($result)) {
//處理 $row
}
}
?>
使用 pg_query 呼叫您的預存程序,並在取得預存程序傳回的值(例如本例中的 smallint)時使用 pg_fetch_result。
<?php
$pgConnection = pg_connect("dbname=users user=me");
$userNameToCheckFor = "metal";
$result = pg_query($pgConnection, "SELECT howManyUsersHaveThisName('$userNameToCheckFor')");
$count = pg_fetch_result($result, 0, 'howManyUsersHaveThisName');
?>
改進 jsuzuki 的說法
使用 pg_num_rows() 來查看是否沒有傳回任何列可能會更好,因為這樣可以將結果集游標指向第一列,以便您可以在迴圈中使用它。
範例
<?php
$result=pg_query($conn, "SELECT * FROM x WHERE a=b;");
if (!$result) {
echo "查詢未執行";
}
if (pg_num_rows($result) == 0) {
echo "0 筆記錄"
}
else {
while ($row = pg_fetch_array($result)) {
//處理 $row
}
}
?>
我個人也覺得這樣更具可讀性。
這是我的小函式,可以讓我更容易使用來自 select 查詢的數據(注意,它容易受到 SQL 注入的攻擊)
<?php
function requestToDB($connection,$request){
if(!$result=pg_query($connection,$request)){
return False;
}
$combined=array();
while ($row = pg_fetch_assoc($result)) {
$combined[]=$row;
}
return $combined;
}
?>
範例
<?php
$conn = pg_pconnect("dbname=mydatabase");
$results=requestToDB($connect,"select * from mytable");
//您可以像這樣存取表格的「儲存格」:
$rownumber=0;
$columname="mycolumn";
$mycell=$results[$rownumber][$columname];
var_dump($mycell);