Documentation Home
MySQL 8.0 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 36.1Mb
PDF (A4) - 36.2Mb


このページは機械翻訳したものです。

13.5.1 PREPARE ステートメント

PREPARE stmt_name FROM preparable_stmt

PREPARE ステートメントは SQL ステートメントを準備し、それに名前 stmt_name を割り当てます。この名前は、あとでそのステートメントを参照するために使用されます。 この準備済みステートメントは EXECUTE で実行され、DEALLOCATE PREPARE で解放されます。 例については、セクション13.5「プリペアドステートメント」を参照してください。

ステートメント名では大/小文字は区別されません。preparable_stmt は、SQL ステートメントのテキストを含む文字列リテラルまたはユーザー変数です。 このテキストは複数のステートメントではなく、1 つのステートメントを表している必要があります。 このステートメント内では、? 文字を、あとでクエリーを実行するときに、そのクエリーのどこにデータ値をバインドするかを示すパラメータマーカーとして使用できます。 文字列値にバインドしようとしている場合でも、? 文字を引用符で囲んではいけません。 パラメータマーカーは、SQL キーワードや識別子などではなく、データ値を指定するべき場所にしか使用できません。

指定された名前を持つ準備済みステートメントがすでに存在する場合、そのステートメントは、新しいステートメントが準備される前に暗黙的に解放されます。 つまり、新しいステートメントにエラーが含まれていて準備できない場合は、エラーが返され、指定された名前を持つステートメントは存在しなくなります。

準備済みステートメントのスコープは、そのステートメントが作成されたセッションです。これには、次のいくつかの注意点があります。

  • あるセッションで作成された準備済みステートメントを別のセッションで使用することはできません。

  • セッションが (正常または異常にかかわらず) 終了すると、その準備済みステートメントは存在しなくなります。 自動再接続が有効になっていると、クライアントには接続が失われたことが通知されません。 このため、クライアントは自動再接続を無効にすることが必要になる場合があります。 Automatic Reconnection Controlを参照してください。

  • ストアドプログラム内で作成された準備済みステートメントは、そのプログラムが実行を完了したあとも引き続き存在し、あとでそのプログラムの外部で実行できます。

  • ストアドプログラムのコンテキストで準備されたステートメントは、ストアドプロシージャーやストアドファンクションのパラメータまたはローカル変数を参照できません。これらは、そのプログラムが終了するとスコープから外れ、このステートメントがあとでプログラムの外部で実行されたときに使用できなくなるためです。 回避方法として、代わりに、同様にセッションスコープを持つユーザー定義変数を参照します。セクション9.4「ユーザー定義変数」を参照してください。

MySQL 8.0.22 以降、プリペアドステートメントで使用されるパラメータのタイプは、そのステートメントが最初に準備されたときに決定され、このプリペアドステートメントに対して EXECUTE が起動されるたびに保持されます (このセクションで後述するようにステートメントが再準備されないかぎり)。 パラメータタイプを決定するためのルールを次に示します:

  • バイナリ算術演算子のオペランドであるパラメータは、他のオペランドと同じデータ型を持ちます。

  • バイナリ算術演算子の両方のオペランドがパラメータの場合、パラメータの型は演算子のコンテキストによって決定されます。

  • パラメータが単項算術演算子のオペランドである場合、パラメータタイプは演算子のコンテキストによって決定されます。

  • 算術演算子に型決定コンテキストがない場合、関係するパラメータの導出型は DOUBLE PRECISION です。 これは、たとえば、パラメータが SELECT リストの最上位ノードである場合や、比較演算子の一部である場合に発生することがあります。

  • 文字列演算子のオペランドであるパラメータは、他のオペランドの集計型と同じ導出型を持ちます。 演算子のすべてのオペランドがパラメータの場合、導出タイプは VARCHAR で、その照合は collation_connection の値によって決定されます。

  • 時間演算子のオペランドであるパラメータは、演算子が DATETIME を返す場合は DATETIME 型、演算子が TIME を返す場合は TIME、演算子が DATE を返す場合は DATE 型になります。

  • バイナリ比較演算子のオペランドであるパラメータは、比較の他のオペランドと同じ導出型を持ちます。

  • BETWEEN などの 3 項比較演算子のオペランドであるパラメータは、他のオペランドの集計型と同じ導出型を持ちます。

  • 比較演算子のすべてのオペランドがパラメータの場合、各オペランドの導出タイプは VARCHAR で、照合は collation_connection の値によって決定されます。

  • CASE, COALESCE, IF, IFNULL または NULLIF の出力オペランドであるパラメータは、演算子の集計型と同じ導出型を持ちます。

  • CASE, COALESCE, IF, IFNULL または NULLIF のすべての出力オペランドがパラメータであるか、すべて NULL である場合、パラメータのタイプは演算子のコンテキストによって決定されます。

  • パラメータが CASE, COALESCE(), IF または IFNULL のオペランドであり、型決定コンテキストがない場合、関連する各パラメータの導出型は VARCHAR であり、その照合は collation_connection の値によって決定されます。

  • CAST() のオペランドであるパラメータの型は、CAST() で指定されたものと同じです。

  • パラメータが INSERT ステートメントの一部ではない SELECT リストの直接のメンバーである場合、パラメータの導出タイプは VARCHAR であり、その照合は collation_connection の値によって決定されます。

  • パラメータが INSERT ステートメントの一部である SELECT リストの直接のメンバーである場合、パラメータの導出型は、パラメータが挿入される対応するカラムの型になります。

  • パラメータが UPDATE ステートメントの SET 句または INSERT ステートメントの ON DUPLICATE KEY UPDATE 句で割当てのソースとして使用される場合、パラメータの導出タイプは、SET 句または ON DUPLICATE KEY UPDATE 句によって更新される対応するカラムのタイプになります。

  • パラメータが関数の引数である場合、派生型は関数の戻り型によって異なります。

実際のタイプと導出タイプの一部の組合せでは、ステートメントの自動再準備がトリガーされ、以前のバージョンの MySQL との互換性が確保されます。 次のいずれかの条件に該当する場合、再準備は行われません:

  • NULL は、実際のパラメータ値として使用されます。

  • パラメータは、CAST() のオペランドです。 (かわりに、派生型へのキャストが試行され、キャストが失敗した場合は例外が発生します。)

  • パラメータは文字列です。 (この場合、暗黙的な CAST(? AS derived_type) が実行されます。)

  • パラメータの導出タイプと実際のタイプはどちらも INTEGER であり、同じ符号を持ちます。

  • パラメータ導出タイプは DECIMAL で、その実際のタイプは DECIMAL または INTEGER のいずれかです。

  • 導出型は DOUBLE で、実際の型は任意の数値型です。

  • 導出型と実際の型はどちらも文字列型です。

  • 導出された型が temporal で、実際の型が temporal の場合。 例外: 導出タイプは TIME で、実際のタイプは TIME ではありません。導出タイプは DATE で、実際のタイプは DATE ではありません。

  • 導出型は時間的で、実際の型は数値です。

前述以外の場合は、ステートメントが再準備され、導出されたパラメータタイプのかわりに実際のパラメータタイプが使用されます。

これらのルールは、プリペアドステートメントで参照されるユーザー変数にも適用されます。

最初の実行後にステートメントを実行するために、プリペアドステートメント内の特定のパラメータまたはユーザー変数に異なるデータ型を使用すると、ステートメントが再準備されます。 これは効率的ではありません。また、パラメータ (または変数) の実際の型が異なる可能性があるため、準備されたステートメントの後続の実行と結果に一貫性がなくなる可能性があります。 このような理由から、プリペアドステートメントを再実行する場合は、特定のパラメータに同じデータ型を使用することをお薦めします。