Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 27.1Mb
PDF (A4) - 27.2Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


MySQL 5.6 リファレンスマニュアル  /  SQL ステートメントの構文  /  準備済みステートメントのための SQL 構文

13.5 準備済みステートメントのための SQL 構文

MySQL 5.6 は、サーバー側の準備済みステートメントをサポートしています。このサポートでは、MySQL 4.1 から使用可能な、効率的なクライアント/サーバーのバイナリプロトコルを利用しています。パラメータ値のためのプレースホルダを含む準備済みステートメントの使用には、次の利点があります。

  • ステートメントを実行のたびに解析するためのオーバーヘッドが少なくなります。通常、データベースアプリケーションは、クエリーや削除の場合の WHERE、更新の場合の SET、挿入の場合の VALUES などの句でリテラルまたは変数値しか変更されていない、ほぼ同一の大量のステートメントを処理します。

  • SQL インジェクション攻撃からの保護。パラメータ値には、エスケープされていない SQL 引用符および区切り文字を含めることができます。

アプリケーションプログラムでの準備済みステートメント

サーバー側の準備済みステートメントは、C プログラムのための MySQL C API クライアントライブラリまたは MySQL Connector/C、Java プログラムのための MySQL Connector/J、.NET テクノロジを使用したプログラムのための MySQL Connector/Net などのクライアントプログラミングインタフェース経由で使用できます。たとえば、C API は、その準備済みステートメント API を構成する一連の関数呼び出しを提供しています。セクション23.8.8「C API プリペアドステートメント」を参照してください。ほかの言語インタフェースは、C クライアントライブラリ内でリンクすることによって、バイナリプロトコルを使用する準備済みステートメントに対するサポートを提供できます。その 1 つの例が、PHP 5.0 以降で使用可能な mysqli 拡張機能です。

SQL スクリプトでの準備済みステートメント

準備済みステートメントへの代替 SQL インタフェースを使用できます。このインタフェースは、準備済みステートメント API 経由でのバイナリプロトコルの使用ほど効率的ではありませんが、SQL レベルで直接使用できるためプログラミングが必要ありません。

  • 使用できるプログラミングインタフェースが存在しない場合でも使用できます。

  • mysql クライアントプログラムなどの、サーバーに SQL ステートメントを送信して実行させることのできる任意のプログラムから使用できます。

  • MySQL 4.1 以降を実行しているサーバーに接続しているかぎり、クライアントが古いバージョンのクライアントライブラリを使用している場合でも使用できます。

準備済みステートメントのための SQL 構文は、次のような状況で使用されるように考慮されています。

  • 準備済みステートメントのコーディングの前に、それがアプリケーションでどのように動作するかをテストする場合。

  • サポートしているプログラミング API にアクセスできないときに準備済みステートメントを使用する場合。

  • 準備済みステートメントに関するアプリケーションの問題を対話的にトラブルシューティングする場合。

  • バグレポートを提出できるように、準備済みステートメントに関する問題を再現するテストケースを作成する場合。

PREPARE、EXECUTE、および DEALLOCATE PREPARE ステートメント

準備済みステートメントのための SQL 構文は、次の 3 つの SQL ステートメントに基づいています。

次の例は、2 辺の長さが与えられた三角形の斜辺を計算するステートメントを準備するための 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 に設定します。

準備済みステートメント内で許可される SQL 構文

次の SQL ステートメントは、準備済みステートメントとして使用できます。

ALTER TABLE
ALTER USER (as of MySQL 5.6.8)
ANALYZE TABLE
CACHE INDEX
CALL
CHANGE MASTER
CHECKSUM {TABLE | TABLES}
COMMIT
{CREATE | RENAME | DROP} DATABASE
{CREATE | DROP} INDEX
{CREATE | RENAME | DROP} TABLE
{CREATE | RENAME | DROP} USER
{CREATE | DROP} VIEW
DELETE
DO
FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES
  | LOGS | STATUS | MASTER | SLAVE | DES_KEY_FILE | USER_RESOURCES}
GRANT
INSERT
INSTALL PLUGIN
KILL
LOAD INDEX INTO CACHE
OPTIMIZE TABLE
REPAIR TABLE
REPLACE
RESET {MASTER | SLAVE | QUERY CACHE}
REVOKE
SELECT
SET
SHOW {AUTHORS | CONTRIBUTORS | WARNINGS | ERRORS}
SHOW BINLOG EVENTS
SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW}
SHOW {MASTER | BINARY} LOGS
SHOW {MASTER | SLAVE} STATUS
SLAVE {START | STOP}
TRUNCATE TABLE
UNINSTALL PLUGIN
UPDATE

その他のステートメントは、MySQL 5.6 ではサポートされていません。

通常、SQL 準備済みステートメントで許可されていないステートメントは、ストアドプログラムでも許可されません。例外については、セクションD.1「ストアドプログラムの制約」に示されています。

プリペアドステートメントによって参照されているテーブルやビューのメタデータの変更が検出され、それが次に実行されるときに、ステートメントが自動再準備されます。詳細については、セクション8.9.4「プリペアドステートメントおよびストアドプログラムのキャッシュ」を参照してください。

準備済みステートメントを使用する場合は、LIMIT 句の引数にプレースホルダを使用できます。セクション13.2.9「SELECT 構文」を参照してください。

PREPARE および EXECUTE とともに使用される準備済み CALL ステートメントでは、OUT および INOUT パラメータに対するプレースホルダのサポートが MySQL 5.6 から使用できます。例および以前のバージョンでの回避方法については、セクション13.2.1「CALL 構文」を参照してください。IN パラメータには、バージョンには関係なくプレースホルダを使用できます。

準備済みステートメントのための SQL 構文は、ネストされた方法では使用できません。つまり、PREPARE に渡されるステートメント自体を、PREPAREEXECUTE、または DEALLOCATE PREPARE ステートメントにすることはできません。

準備済みステートメントのための SQL 構文は、準備済みステートメント API 呼び出しの使用とは異なります。たとえば、mysql_stmt_prepare() C API 関数を使用して、PREPAREEXECUTE、または DEALLOCATE PREPARE ステートメントを準備することはできません。

準備済みステートメントのための SQL 構文はストアドプロシージャー内で使用できますが、ストアドファンクションまたはトリガー内では使用できません。ただし、PREPAREEXECUTE で準備および実行される動的なステートメントにはカーソルを使用できません。カーソルのステートメントはカーソル作成時にチェックされるため、そのステートメントを動的にすることはできません。

準備済みステートメントのための SQL 構文は、マルチステートメント (つまり、;文字で区切られた 1 つの文字列内の複数のステートメント) をサポートしていません。

プリペアドステートメントは、セクション8.9.3.1「クエリーキャッシュの動作」に説明する状況でクエリーキャッシュを使用します。

CALL SQL ステートメントを使用して、準備済みステートメントを含むストアドプロシージャーを実行する C プログラムを記述するには、CLIENT_MULTI_RESULTS フラグが有効になっている必要があります。これは、各 CALL によって、プロシージャー内で実行されるステートメントによって返される可能性のある結果セットに加えて、呼び出しステータスを示すための結果が返されるためです。

CLIENT_MULTI_RESULTS は、mysql_real_connect() を呼び出すときに、CLIENT_MULTI_RESULTS フラグ自体を渡すことによって明示的に、または CLIENT_MULTI_STATEMENTS を渡すことによって暗黙的に有効にする (これによって CLIENT_MULTI_RESULTS も有効になります) ことができます。詳細は、セクション13.2.1「CALL 構文」を参照してください。


User Comments
Sign Up Login You must be logged in to post a comment.