pg_prepare

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

pg_prepare 指定したパラメータでプリペアドステートメントを作成するリクエストを 送信し、その完了を待つ

説明

pg_prepare(resource $connection = ?, string $stmtname, string $query): resource|false

pg_prepare() は、 pg_execute() あるいは pg_send_execute() で後に実行するためのプリペアドステートメントを作成します。これにより、 繰り返し使用されるコマンドについての構文解析や実行計画作成が最初の 一度だけですみます。pg_prepare() は PostgreSQL 7.4 以降の接続でのみ使用可能です。それ以前のバージョンでは失敗します。

この関数は stmtname という名前の プリペアドステートメントを query 文字列から作成します。 この文字列には 1 つの SQL コマンドが含まれている必要があります。 stmtname を "" にすることで無名ステートメントを 作成することが可能で、既存の無名ステートメントは自動的に上書きされます。 それ以外の場合、もしカレントのセッションで既に定義済みのステートメント名を 使用した場合にはエラーとなります。パラメータを使用する際は、 query 内で $1、$2 のような形式で参照されます。

pg_prepare() で使用するプリペアドステートメントは、 SQLの PREPARE 文を実行することでも作成可能です (しかし、パラメータの型を事前に指定する必要がないという点で pg_prepare() のほうがより柔軟です)。 また、PHP にはプリペアドステートメントを削除する関数がありませんが、 この目的のためには SQLの DEALLOCATE 文が使用可能です。

パラメータ

connection

PostgreSQL データベース接続リソース。connection が指定されていない場合はデフォルトの接続が使用されます。 デフォルトの接続は、直近の pg_connect() あるいは pg_pconnect() によって作成されたものです。

stmtname

プリペアドステートメントにつける名前。接続内で一意である必要があります。 "" が指定された場合は無名ステートメントが作成され、以前に定義された 無名ステートメントを上書きします。

query

パラメータ化した SQL 文。ひとつの文のみである必要があります (複数の文をセミコロンで区切る形式は使用できません)。パラメータを 使用する際は $1、$2 などの形式で参照されます。

返り値

成功した場合にクエリ結果リソース、失敗した場合に false を返します。

例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() - 指定したパラメータでプリペアドステートメントを実行するリクエストを 送信し、その結果を待たない

add a note add a note

User Contributed Notes 6 notes

up
3
rodrigo at fabricadeideias dot com
17 years ago
If you decide to deallocate (unprepare) a previously prepared sql command it might be better to quote the sql name as in

  DEALLOCATE "theNameOfMySQL"

instead of (the more natural)

  DEALLOCATE theNameOfMySQL

PostgerSQL preserves the case of your identifiers if, and only if, you quote them. The pg_prepare function preserves the case of the sql name you use.

A complete example would be

  $sql = 'SELECT * FROM user WHERE cod_user = $1';
  $sqlName = 'selectUserByCode';
  if (!pg_prepare ($sqlName, $sql)) {
    die("Can't prepare '$sql': " . pg_last_error());
  }
  $rs = pg_execute($sqlName, array(1));
  do whatever you want with $rs and finally
  $sql = sprintf(
    'DEALLOCATE "%s"',
    pg_escape_string($sqlName)
  );
  if(!pg_query($sql)) {
    die("Can't query '$sql': " . pg_last_error());
  }
up
2
geompse at gmail dot com
12 years ago
The given name cannot be the statement itself.
It has a maximum length and will truncate.

If two queries begin the same way, only the first one will be used.
up
2
david at fetter dot org
19 years ago
SQL is often a complicated piece of code by itself, so you may wish put it inside a "here doc."  This will help you read it wherever it appears and test it by itself via a command-line or gui client.

$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;
up
1
mike at musskopf dot com
16 years ago
I had some problems with this function. When you use pg_prepare() with a function like date_trunc('day', $1) you need to specify the data type.

The solution was use the Pear MDB2 but with some changes in code. The original code try to use pg_prepare() too, with errors.
up
0
andy at petdance dot com
16 years ago
Any error in the prepare is available from pg_last_error().
up
-1
scott dot marlowe at gmail dot com
18 years ago
Note that if you are preparing a query with an in clause with a list of items, you will need to prepare each item separately.

$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"));

This means that you can't just prepare a query with an arbitrary in() list.
To Top