prepare() と execute*() により、 クエリ実行時に性能の向上と柔軟性の向上を得られます。 準備/実行モードは、ひとつの等しいクエリに さまざまな値を投入して何度も実行しなければならない場合 (例えばデータベースへのアドレスリストの追加など) に有用です。
準備/実行モードは、 SQL 構文の異なる複数のデータベースをサポートする際にも有用となります。 INSERT の構文が異なる二種類ののデータベースをサポートする場合を想像してみて下さい。
db1: INSERT INTO tbl_name (col1, col2) VALUES (expr1, expr2) db2: INSERT INTO tbl_name SET col1=expr1, col2=expr2 |
$statement['db1']['INSERT_PERSON'] = 'INSERT INTO person (surname, name, age) VALUES (?, ?, ?)'; $statement['db2']['INSERT_PERSON'] = 'INSERT INTO person SET surname=?, name=?, age=?'; |
上記の特徴を使用するために、2ステップ進まなければなりません。 ひとつめに命令文を準備することです。 ふたつめはそれを実行することです。
まずはじめに、汎用の SQL 文を prepare() しなければなりません。 汎用の命令文を作成する方法は、通常の SQL クエリを書く際と同様です。
SELECT surname, name, age FROM person WHERE name = 'name_to_find' AND age < age_limit |
SELECT surname, name, age FROM person WHERE name = ? AND age < ? |
prepare() は、さまざまな型の プレースホルダ (ワイルドカードとも言われる) を処理できます。
? - (推奨されます) 文字列や数値のようなスカラー値を意味します。 データベースの要求に応じ、値のエスケープおよびクォートを 自動的に行います。 |
! - スカラー値を意味し、"そのまま"命令文に挿入されます。 |
& - 既存のファイル名を要求とし、このファイルの内容を命令文に含まれます。 (例えば、 データベース内にグラフィックファイルのバイナリデータを 保存するといった場合) |
それらがプレースホールダーとして解釈されることは望まなければ、 プレースホールダー文字を回避するためにバックスラッシュを使用します。
UPDATE foo SET col=? WHERE col='over \& under' |
命令文を準備した後に、クエリを実行することができます。 これは、準備した文に変数を割り当てることを意味します。 これをするには、 execute() は prepare() から返される命令文ハンドル、値を割り当てた配列の 2 つの引数を要求します。
例 39-1execute() にスカラーを渡す
|
プリペアドステートメントに複数のプレースホルダが含まれる場合は、 その値を配列で execute() に渡さなければなりません。 配列の最初のエントリが最初のプレースホルダを、 ふたつめが 2 番目のプレースホルダを、といったようになります。 その順番は使用されたプレースホルダの型には依存しません。
例 39-2execute() に配列を渡す
|
警告 |
$data に渡す値は、リテラルである必要があります。 SQL 関数 (例えば CURDATE() など) を渡さないでください。 実行時に処理される SQL 関数は、プリペアドステートメント内に記述する 必要があります。同様に、識別子 (すなわち テーブル名およびカラム名) も渡すことはできません。なぜなら、それらの名前は準備の段階で 検証されるものだからです。 |
DB には、複数のクエリを一度に実行する機能が含まれています。 それらを手動で実行するかわりに、以下のようにします。
例 39-3execute() に配列を渡す
|
INSERT INTO numbers VALUES ('1', 'one', 'en') INSERT INTO numbers VALUES ('2', 'two', 'to') INSERT INTO numbers VALUES ('3', 'three', 'tre') INSERT INTO numbers VALUES ('4', 'four', 'fire') |
例 39-4 execute()の代わりに executeMultiple()を使用する
|
結果は同じです。 もしレコードの1つが失敗した場合、未実行のクエリは実行されません。
execute*() の返す値は、以下の 3 種類です。 結果を返すクエリ (例えば SELECT クエリなど) の場合は新しい DB_result オブジェクト、 データを操作するクエリ (例えば INSERT クエリなど) の場合は DB_OK、 あるいは失敗した場合には DB_Error オブジェクトを返します。