Pg prepare: примеры (PHP)
pg_prepare(PgSql\Connection $connection, string $stmtname, string $query): PgSql\Result|falseФункция pg_prepare в PHP используется для создания подготовленного SQL-запроса на соединении с базой данных PostgreSQL. Подготовленные запросы повышают производительность и безопасность при многократном выполнении одного и того же запроса с разными параметрами.
Функция применяется, когда необходимо выполнить один и тот же запрос много раз с разными значениями. Подготовленный запрос компилируется один раз, что снижает нагрузку на сервер БД и защищает от SQL-инъекций.
- connection (ресурс PostgreSQL): Обязательный параметр. Ресурс подключения к базе данных PostgreSQL, возвращаемый функциями
pg_connectилиpg_pconnect. - statementname (строка): Имя для подготовленного запроса. Должно быть уникальным в пределах соединения. Можно использовать пустую строку, чтобы создать анонимный подготовленный запрос.
- query (строка): SQL-запрос, который необходимо подготовить. В запросе могут использоваться плейсхолдеры
$1,$2и т.д., которые заменяются фактическими значениями при выполнении.
Функция возвращает ресурс результата подготовки при успехе или false в случае ошибки.
$conn = pg_connect('host=localhost dbname=test user=postgres');
$result = pg_prepare($conn, 'user_query', 'SELECT * FROM users WHERE id = $1');
var_dump($result);object(PgSql\Result)#2 (0) {
}$conn = pg_connect('host=localhost dbname=test user=postgres');
$result = pg_prepare($conn, '', 'INSERT INTO logs(message) VALUES ($1)');
var_dump($result);object(PgSql\Result)#2 (0) {
}$conn = pg_connect('host=localhost dbname=test user=postgres');
pg_prepare($conn, 'get_user', 'SELECT name, email FROM users WHERE age > $1');
$res = pg_execute($conn, 'get_user', [25]);
while ($row = pg_fetch_assoc($res)) {
print_r($row);
}Array
(
[name] => Иван
[email] => ivan@example.com
)
Array
(
[name] => Мария
[email] => maria@example.com
)- pg_query_params: Выполняет SQL-запрос с параметрами, но без явного создания именованного подготовленного запроса. Эта функция полезна для однократного выполнения запроса с параметрами. Она автоматически создает и использует анонимный подготовленный запрос.
- pg_send_prepare и pg_send_execute: Асинхронные версии для подготовки и выполнения запросов. Применяются, когда нужно избежать блокировки скрипта на время выполнения запроса.
pg_prepare предпочтительнее использовать, когда один запрос выполняется много раз в рамках одного соединения. pg_query_params удобнее для однократных запросов.
import psycopg2
conn = psycopg2.connect('dbname=test user=postgres')
cur = conn.cursor()
cur.execute('PREPARE userplan AS SELECT * FROM users WHERE id = $1')
cur.execute('EXECUTE userplan (%s)', [5])
print(cur.fetchall())const { Client } = require('pg');
const client = new Client();
await client.connect();
const query = {
name: 'fetch-user',
text: 'SELECT * FROM users WHERE id = $1',
};
const res = await client.query(query, [5]);
console.log(res.rows);Pg prepare в MySQL
PREPARE user_stmt FROM 'SELECT * FROM users WHERE id = ?';
SET @id = 1;
EXECUTE user_stmt USING @id;
DEALLOCATE PREPARE user_stmt;Основное отличие в синтаксисе: в PostgreSQL в запросе используются позиционные плейсхолдеры $1, $2, в то время как в MySQL — знак вопроса ?. В Python и JS подготовка часто происходит неявно через параметризованные запросы.
$conn = false;
$result = pg_prepare($conn, 'my_query', 'SELECT 1');
var_dump($result);bool(false)
Ошибка возникает, если передать неверный ресурс соединения.
$conn = pg_connect('host=localhost dbname=test user=postgres');
$result = pg_prepare($conn, 'my-query', 'SELECT 1');
var_dump($result);bool(false)
Имя запроса не должно содержать дефисы и другие специальные символы. Лучше использовать буквы, цифры и знак подчеркивания.
$conn = pg_connect('host=localhost dbname=test user=postgres');
$result = pg_prepare($conn, 'bad_query', 'SELCT * FROM users');
if ($result === false) {
echo pg_last_error($conn);
}ERROR: syntax error at or near "SELCT" LINE 1: SELCT * FROM users
Начиная с PHP 8.1, ресурсы PostgreSQL были заменены на объекты PgSql\Connection и PgSql\Result. Функция pg_prepare теперь возвращает объект PgSql\Result вместо ресурса, но это изменение обратно совместимо.
В PHP 8.0 существенных изменений в работе функции не было.
$conn = pg_connect('host=localhost dbname=test user=postgres');
pg_query($conn, 'BEGIN');
pg_prepare($conn, 'update_balance', 'UPDATE accounts SET balance = balance + $1 WHERE id = $2');
pg_prepare($conn, 'insert_history', 'INSERT INTO transactions(account_id, amount) VALUES ($1, $2)');
pg_execute($conn, 'update_balance', [100, 123]);
pg_execute($conn, 'insert_history', [123, 100]);
pg_query($conn, 'COMMIT');$conn = pg_connect('host=localhost dbname=test user=postgres');
pg_prepare($conn, 'complex_query', 'INSERT INTO products(name, price, active, tags) VALUES ($1, $2, $3, $4)');
$result = pg_execute($conn, 'complex_query', ['Ноутбук', 999.99, true, '{электроника,техника}']);
var_dump(pg_affected_rows($result));int(1)
$conn = pg_connect('host=localhost dbname=test user=postgres');
pg_prepare($conn, 'insert_data', 'INSERT INTO measurements(value, sensor_id) VALUES ($1, $2)');
$data = [
[22.5, 1],
[23.1, 1],
[21.8, 2],
[24.3, 2]
];
foreach ($data as $row) {
pg_execute($conn, 'insert_data', $row);
}$conn = pg_connect('host=localhost dbname=test user=postgres');
pg_prepare($conn, 'typed_query', 'SELECT $1::text as fixed_text, $2::int[] as numbers');
$res = pg_execute($conn, 'typed_query', ['Пример', '{1,2,3}']);
print_r(pg_fetch_assoc($res));Array
(
[fixed_text] => Пример
[numbers] => {1,2,3}
)$conn = pg_connect('host=localhost dbname=test user=postgres');
$result = pg_prepare($conn, 'meta_query', 'SELECT id, name FROM users WHERE age BETWEEN $1 AND $2');
$desc = pg_result_status($result, PGSQL_STATUS_STRING);
echo $desc;PREPARE meta_query AS SELECT id, name FROM users WHERE age BETWEEN $1 AND $2