PHP Conference Japan 2024

pg_prepare

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

pg_prepare提交请求到服务器,创建具有给定参数的预处理语句,并等待完成

描述

pg_prepare(PgSql\Connection $connection = ?, string $stmtname, string $query): PgSql\Result|false

pg_prepare() 创建一个预处理语句,以便稍后使用 pg_execute()pg_send_execute() 执行。此功能允许对将重复使用的命令只解析和规划一次,而不是每次执行时都进行解析和规划。pg_prepare() 仅支持针对 PostgreSQL 7.4 或更高版本的连接;使用早期版本时,它将失败。

该函数根据 query 字符串创建一个名为 stmtname 的预处理语句,该字符串必须包含单个 SQL 命令。stmtname 可以是 "" 以创建未命名的语句,在这种情况下,任何预先存在的未命名语句都会自动替换;否则,如果在当前会话中已定义语句名称,则会出错。如果使用了任何参数,则在 query 中将其称为 $1$2 等。

可用于 pg_prepare() 的预处理语句也可以通过执行 SQL PREPARE 语句来创建。(但 pg_prepare() 更灵活,因为它不需要预先指定参数类型。)此外,尽管没有用于删除预处理语句的 PHP 函数,但可以使用 SQL DEALLOCATE 语句来实现此目的。

参数

connection

一个 PgSql\Connection 实例。当 connection 未指定时,使用默认连接。默认连接是 pg_connect()pg_pconnect() 最后建立的连接。

警告

从 PHP 8.1.0 开始,使用默认连接已弃用。

stmtname

要赋予预处理语句的名称。每个连接必须唯一。如果指定 "",则创建未命名的语句,覆盖任何先前定义的未命名语句。

query

参数化的 SQL 语句。必须只包含单个语句(不允许用分号分隔的多个语句)。如果使用了任何参数,则将其称为 $1$2 等。

返回值

成功时返回 PgSql\Result 实例,失败时返回 false

变更日志

版本 描述
8.1.0 现在返回 PgSql\Result 实例;以前返回的是 资源
8.1.0 connection 参数现在需要一个 PgSql\Connection 实例;以前需要的是 资源

示例

示例 #1 使用 pg_prepare()

<?php

// 连接到名为“mary”的数据库
$dbconn = pg_connect("dbname=mary");

// 准备要执行的查询
$result = pg_prepare($dbconn, "my_query", 'SELECT * FROM shops WHERE name = $1');

// 执行预处理查询。请注意,无需以任何方式转义字符串“Joe's Widgets”
$result = pg_execute($dbconn, "my_query", array("Joe's Widgets"));

// 执行相同的预处理查询,这次使用不同的参数
$result = pg_execute($dbconn, "my_query", array("Clothes Clothes Clothes"));

?>

参见

  • pg_execute() - 发送请求以使用给定参数执行预处理语句,并等待结果
  • pg_send_execute() - 发送请求以使用给定参数执行预处理语句,无需等待结果

添加备注

用户贡献的笔记 6 条笔记

david at fetter dot org
19 年前
SQL 本身通常是一段复杂的代码,因此您可能希望将其放在“here doc”中。这将帮助您在任何出现的地方阅读它,并通过命令行或 GUI 客户端对其进行单独测试。

$sql = <<<SQL
SELECT a.foo, b.bar, c.baz
FROM
table_a a
LEFT JOIN
table_b b
ON (
a.a_id = b.a_id
)
JOIN
table_c c
ON (
b.c_id = c.c_id
)
WHERE c.name = $1
SQL;
mike at musskopf dot com
17 年前
我使用此函数时遇到了一些问题。当您将 pg_prepare() 与 date_trunc('day', $1) 等函数一起使用时,需要指定数据类型。

解决方案是使用 Pear MDB2,但代码需要做一些更改。原始代码也尝试使用 pg_prepare(),但会出错。
rodrigo at fabricadeideias dot com
18年前
如果您决定释放(取消准备)之前准备好的SQL命令,最好引用SQL名称,例如:

DEALLOCATE "theNameOfMySQL"

而不是(更自然的方式):

DEALLOCATE theNameOfMySQL

只有当您使用引号引用标识符时,PostgreSQL 才会保留其大小写。pg_prepare 函数会保留您使用的 SQL 名称的大小写。

一个完整的例子:

$sql = 'SELECT * FROM user WHERE cod_user = $1';
$sqlName = 'selectUserByCode';
if (!pg_prepare ($sqlName, $sql)) {
die("无法准备 '$sql': " . pg_last_error());
}
$rs = pg_execute($sqlName, array(1));
对 $rs 做任何你想做的操作,最后:
$sql = sprintf(
'DEALLOCATE "%s"',
pg_escape_string($sqlName)
);
if(!pg_query($sql)) {
die("无法执行查询 '$sql': " . pg_last_error());
}
geompse at gmail dot com
12年前
给定的名称不能是语句本身。
它有最大长度限制,会截断。

如果两个查询以相同的方式开始,则只使用第一个查询。
scott dot marlowe at gmail dot com
18年前
请注意,如果您正在准备一个包含项目列表的 in 子句的查询,则需要分别准备每个项目。

$result = pg_prepare($dbconn, "my_query", 'SELECT * FROM shops WHERE name IN($1,$2,$3)');

$result = pg_execute($dbconn, "my_query", array("coffee", "beer", "hard"));

这意味着您不能只准备一个带有任意 in() 列表的查询。
andy at petdance dot com
16年前
准备过程中的任何错误都可从 pg_last_error() 获取。
To Top