MySQL の変数とプリペアドステートメント

最終更新: 2021-06-24 18:18:18 +0800 +0800
tags: Mysql | Sql | Databases
原文は英語で書かれています。あなたはAI翻訳版を読んでいます。

MySQL は、サーバーシステム変数、ローカルルーチン変数、セッションユーザー変数を区別します。スコープと評価規則が異なるため、相互に置き換えて使用すべきではありません。

システム変数とユーザー変数 #

システム変数は @@ を使用し、グローバル、セッション、または両方のスコープを持ちます。

sql
SELECT @@GLOBAL.transaction_isolation, @@SESSION.sql_mode;
SET SESSION sql_safe_updates = 1;

グローバル変数を変更すると、その変数がセッションスコープも持つ場合は新しいセッションに影響します。既存の接続のトランザクションポリシーを変更する方法ではありません。動的変数は実行時に変更できますが、読み取り専用変数には起動時の設定が必要です。SET PERSIST は実行時のグローバル値を変更して mysqld-auto.cnf に書き込みます。SET PERSIST_ONLY は実行時の状態を変更せずに永続化された値を書き込みます。どちらかを使用する前に変数が永続化可能であることを確認し、生成されたファイルの所有権はサーバーに保持し、そのファイルを直接編集しないでください。

ユーザー変数は @name を使用し、接続ローカルで、宣言された型を持ちません。

sql
SET @minimum_total = 100;
SELECT id FROM orders WHERE total >= @minimum_total;

手続き型評価を模倣するために、1 つの式またはクエリ内で同じユーザー変数を代入して読み取らないでください。MySQL は、そのようなクエリを信頼できるものにする評価順序を保証しません。代わりにウィンドウ関数、共通テーブル式、ストアドプログラムのローカル変数、またはアプリケーションコードを使用します。値の型は代入時に導出され、プリペアドステートメントの参照は、そのステートメントが最初に準備されたときに確立された変数型を保持します。必要な SQL 型が契約の一部である場合は、値を明示的に CAST してください。

プリペアドステートメント #

クライアントライブラリのプリペアドステートメントは、データを SQL 構文から分離してバインドするため、アプリケーションクエリではデフォルトにすべきです。これにより、値が注入された SQL として解釈されるのを防ぎ、サーバーがステートメント構造を個別に解析できるようにします。

サーバー側 SQL のプリペアドステートメントは、接続スコープのライフサイクルに従います。PREPARE は 1 つのステートメントを解析し、EXECUTE はそれを繰り返し実行し、DEALLOCATE PREPARE は解放します。同じ名前で 2 回目の PREPARE を実行すると、最初に古いステートメントが解放されます。セッション終了時にもプリペアドステートメントは破棄されます。識別子を組み立てる必要がある管理用の動的 SQL で便利です。パラメータマーカーがバインドするのはデータ値であり、識別子、キーワード、SQL フラグメントではありません。

sql
SET @sql = 'SELECT id FROM orders WHERE customer_id = ?';
PREPARE stmt FROM @sql;
SET @customer_id = 42;
EXECUTE stmt USING @customer_id;
DEALLOCATE PREPARE stmt;

動的な識別子を SQL に連結する前に、検証または許可リスト化してください。パラメータマーカーはすべての文法上の位置で任意の式を表せるわけではなく、プリペアドステートメントは max_prepared_stmt_count によって制限されます。短期間の管理用ステートメントは解放し、アプリケーションドライバーには独自のプリペアドステートメントハンドルを管理させます。

参照 #

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)