MySQL 5.1
は、サーバー側の準備済みステートメントに対するサポートを提供します。妥当なクライアントプログラムインタフェースを利用するという条件で、このサポートは
MySQL 4.1
内でインプリメントされた有効なクライアント/サーバーバイナリプロトコルを駆使します。インタフェース候補は、MySQL
C API クライアントライブラリ (C
プログラムのためのもの)、MySQL
コネクタ/J(プログラムのためのもの)、そして
MySQL コネクタ/NET です。たとえば、C API
はその準備済みステートメント API
を構成する関数呼び出しのセットを提供します。詳しくはC API Prepared Statementsを参照してください。ほかの言語インタフェースは、C
クライアントライブラリ内でリンクすることによって、バイナリプロトコルを使用する準備済みステートメントに対するサポートを提供できます。その
1 つの例が、PHP 5.0 以降で使用可能な
mysqli
拡張機能です。
準備済みステートメントの代替 SQL インタフェースが有効です。このインタフェースは準備済みステートメント API にバイナリプロトコルを利用することほど有効ではありませんが、これは SQL レベルで直接有効なのでプログラミングを必要としません。
有効なプログラミングインタフェースがないときにこれを利用することができます。
mysql クライアントプログラムのように、実行されるサーバーに SQL ステートメントを送ることを許容するすべてのプログラムからこれを利用することができます。
もしクライアントが古いバージョンのクライアントライブラリを利用していてもこれを利用することができます。たった 1 つ要求されることは、準備済みステートメントの SQL 構文をサポートするのに充分新しいサーバーに接続できなければいけないということです。
準備済みステートメントの SQL 構文は、次のような場合に利用するためのものです。
準備済みステートメントが、それをコード化する前に自分のアプリケーション内でどのように機能するかをテストしたい。
アプリケーションが、準備済みステートメントを実行するに当たり問題が発生し、何が原因なのかを調査したい。
バグリポートをファイルするために、準備済みステートメントについて起きている問題を説明するテストケースを作成したい。
準備済みステートメントを利用したいが、それらをサポートするプログラム API へのアクセスがない。
準備済みステートメントの SQL 構文が 3 つの SQL ステートメントに基づいている。
PREPARE
は、実行のためのステートメントを準備します
(項8.7.1. 「PREPARE
構文」 を参照)。
EXECUTE
は、準備済みステートメントを実行します
(項8.7.2. 「EXECUTE
構文」 を参照)。
DEALLOCATE
PREPARE
は、準備済みステートメントを解放します
(項8.7.3. 「DEALLOCATE PREPARE
構文」 を参照)。
次の例は、2 辺の長さが分かっている 3 角形の斜辺を算出するステートメントを準備するための、2 つの同等な方法を表しています。
最初の例は、ステートメントのテキストを提供するために、文字列直定数を利用して準備済みステートメントを作成する方法を表しています。
mysql>PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql>SET @a = 3;
mysql>SET @b = 4;
mysql>EXECUTE stmt1 USING @a, @b;
+------------+ | hypotenuse | +------------+ | 5 | +------------+ mysql>DEALLOCATE PREPARE stmt1;
2 つめの例も似ていますが、ステートメントのテキストをユーザー変数として提供しています。
mysql>SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql>PREPARE stmt2 FROM @s;
mysql>SET @a = 6;
mysql>SET @b = 8;
mysql>EXECUTE stmt2 USING @a, @b;
+------------+ | hypotenuse | +------------+ | 10 | +------------+ mysql>DEALLOCATE PREPARE stmt2;
次に示すのは、テーブルの名前をユーザー変数として格納することによって、実行時にクエリーを実行するテーブルを選択する方法を示すその他の例です。
mysql>USE test;
mysql>CREATE TABLE t1 (a INT NOT NULL);
mysql>INSERT INTO t1 VALUES (4), (8), (11), (32), (80);
mysql>SET @table = 't1';
mysql>SET @s = CONCAT('SELECT * FROM ', @table);
mysql>PREPARE stmt3 FROM @s;
mysql>EXECUTE stmt3;
+----+ | a | +----+ | 4 | | 8 | | 11 | | 32 | | 80 | +----+ mysql>DEALLOCATE PREPARE stmt3;
準備済みステートメントは、そのステートメントが作成されたセッションに固有です。以前に作成された準備済みステートメントを解放せずにセッションを終了した場合、そのステートメントはサーバーによって自動的に解放されます。
準備済みステートメントはまた、セッションに対してグローバルでもあります。ストアドルーチン内で準備済みステートメントを作成した場合、そのステートメントはストアドルーチンが終了しても解放されません。
同時に作成される準備済みステートメントが多くなりすぎないようにするには、max_prepared_stmt_count
システム変数を設定します。準備済みステートメントの使用を回避するには、この値を
0 に設定します。
準備済みステートメントでは、ALTER
TABLE
、CALL
、COMMIT
、CREATE
INDEX
、CREATE
TABLE
、DELETE
、DO
、DROP
INDEX
、DROP
TABLE
、INSERT
、RENAME
TABLE
、REPLACE
、SELECT
、SET
、UPDATE
の各 SQL ステートメントと、ほとんどの
SHOW
ステートメントを使用できます。
MySQL 5.1.10 では、次のステートメントがサポートされています:
ANALYZE TABLE OPTIMIZE TABLE REPAIR TABLE
MySQL 5.1.12 では、次のステートメントがサポートされています:
CACHE INDEX CHANGE MASTER CHECKSUM {TABLE | TABLES} {CREATE | DROP} DATABASE {CREATE | RENAME | DROP} USER FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES | LOGS | STATUS | MASTER | SLAVE | DES_KEY_FILE | USER_RESOURCES} GRANT REVOKE KILL LOAD INDEX INTO CACHE RESET {MASTER | SLAVE | QUERY CACHE} SHOW BINLOG EVENTS SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW} SHOW {AUTHORS | CONTRIBUTORS | WARNINGS | ERRORS} SHOW {MASTER | BINARY} LOGS SHOW {MASTER | SLAVE} STATUS SLAVE {START | STOP} INSTALL PLUGIN UNINSTALL PLUGIN
その他のステートメントはまだサポートされていません。
SQL 準備済みステートメントで許可されていないステートメントは一般に、ストアドルーチンでも許可されません。この規則の例外はすべて、Using Stored Routines (Procedures and Functions) で説明されています。
プレースホルダは、準備済みステートメントを利用するときに
LIMIT
節の引数に対して利用できます。項8.2.8. 「SELECT
構文」
を参照してください。
PREPARE
および
EXECUTE
とともに使用される準備済みの
CALL
ステートメントの場合、OUT
および INOUT
パラメータに対するプレースホルダのサポートは
MySQL 5.1
では使用できません。例および回避方法については、項8.2.1. 「CALL
構文」
を参照してください。バージョンには関係なく、IN
パラメータではプレースホルダを使用できます。
準備済みステートメントの SQL
構文は、ネスト化された種類の中では利用できません。これは、PREPARE
にパスしたステートメント自体は
PREPARE
、EXECUTE
、または
DEALLOCATE PREPARE
ステートメントになり得ないということです。
準備済みステートメントの SQL
構文は、準備済みステートメント API
コールを利用することとは違います。たとえば、PREPARE
、EXECUTE
、または
DEALLOCATE PREPARE
ステートメントを準備するために
mysql_stmt_prepare()
C API 関数を利用することはできません。
準備済みステートメントの SQL
構文はストアドプロシージャー内で利用できますが、ストアドファンクションやトリガー内では利用できません。ただし、準備済みであり、PREPARE
および EXECUTE
とともに実行される動的ステートメントではカーソルを使用できません。カーソルのステートメントはカーソル作成時に確認されるため、このステートメントが動的になることはできません。
準備済みステートメントの SQL
構文では、マルチステートメント (つまり、1
つの文字列内にある
「;
」
文字で区切られた複数のステートメント)
はサポートされません。
MySQL 5.1.17 より前のバージョンでは、準備済みステートメントでクエリーキャッシュは使用されません。5.1.17 の時点では、準備済みステートメントは、項4.5.5.1. 「クエリキャッシュの動作」 で説明されている条件の下でクエリーキャッシュを使用します。
CALL
SQL
ステートメントを使用して、準備済みステートメントを含むストアドプロシージャーを実行する
C
プログラムを記述するには、CLIENT_MULTI_RESULTS
フラグが有効になっている必要があります。これは、各
CALL
によって、プロシージャー内で実行されるステートメントによって返される可能性のある結果セットに加えて、呼び出しステータスを示すための結果が返されるためです。
CLIENT_MULTI_RESULTS
は
mysql_real_connect()
を呼び出すときに、CLIENT_MULTI_RESULTS
フラグ自体を引き渡すことによって明示的に、または
CLIENT_MULTI_STATEMENTS
(これによっても
CLIENT_MULTI_RESULTS
が有効になる)
を引き渡すことによって暗黙的に有効にすることができます。追加情報については
項8.2.1. 「CALL
構文」 を参照してください。