新手用户请注意:在从维护数据库连接的网络表单上的字段收集输入时,*切勿* 使用 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 实例;之前返回一个 resource。 |
8.1.0 | connection 参数现在需要一个 PgSql\Connection 实例;之前需要一个 resource。 |
示例 #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 "查询未执行";
}
if ($line = pg_fetch_assoc($result)) {
if ($line['rows'] == 0) {
echo "0 条记录"
}
}
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 "查询未执行";
}
$rs = pg_fetch_assoc($result);
if (!$rs) {
echo "0 条记录"
}
?>
-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);