SQL文は診断領域の診断情報を生成できます。標準SQLには、1つの診断領域のスタックが含まれており、各ネストされた実行コンテキストの診断領域も含まれます。標準SQLはまた、条件処理プログラムの実行中に2番目の診断領域を参照するために使用されるGET STACKED DIAGNOSTICS構文もサポートしています。本記事では主に、診断領域の構造、識別される情報項目、診断領域のクリアと設定方法、および診断領域のスタックへの追加とスタックからの削除方法について説明します。
診断領域の構造
診断領域には、以下の2種類の情報が含まれます:
ステートメント情報。例えば、発生した条件数や影響を受けた行数などです。
条件情報。例えば、エラーコードやメッセージなどです。1つのステートメントが複数の条件を引き起こした場合、診断領域のこの部分には各条件ごとに条件領域があります。ステートメントがいずれの条件も引き起こさない場合、診断領域のこの部分の情報は空になります。
以下の例は、3つの条件を引き起こすステートメントに対する診断領域に含まれるステートメント情報と条件情報を示しています。
Statement information: -- ステートメント情報
row count
... other statement information items ... -- その他のステートメント情報項目 ...
Condition area list: -- 条件領域リスト
Condition area 1: -- 条件領域 1
error code for condition 1 -- 条件 1 のエラーコード
error message for condition 1 -- 条件 1 のエラーメッセージ
... other condition information items ... -- その他の条件情報項目 ...
Condition area 2: -- 条件領域 2
error code for condition 2: -- 条件 2 のエラーコード
error message for condition 2 -- 条件 2 のエラーメッセージ
... other condition information items ... -- その他の条件情報項目 ...
Condition area 3: -- 条件領域 3
error code for condition 3 -- 条件 3 のエラーコード
error message for condition 3 -- 条件 3 のエラーメッセージ
... other condition information items ... -- その他の条件情報項目 ...
診断領域の情報項目
診断領域には、ステートメント情報と条件情報項目が含まれます。そのうち、数値項目は整数であり、文字項目の文字セットはUTF-8です。項目がない場合はNULLとなります。診断領域を埋めるステートメントでステートメントまたは条件情報項目が設定されていない場合、その値はデータ型に応じて0または空の文字列になります。
診断領域には、以下のステートメント情報が含まれます:
NUMBER:情報を持つ条件領域の数を表す整数です。ROW_COUNT:ステートメントによって影響を受ける行数を表す整数です。ROW_COUNTはROW_COUNT()関数と同じ値を持ちます。
診断領域の条件情報部分には、各条件の条件領域が含まれます。条件領域は、ステートメント条件のNUMBER項目の値から1までの番号が付けられます。NUMBERが0の場合、条件領域はありません。
標準SQLの各条件領域には、以下のリストの項目が含まれます(ただしMYSQL_ERRNOは拡張項目です):
RETURNED_SQLSTATE:条件を示すSQLSTATE値の文字列です。MESSAGE_TEXT:条件エラーメッセージを示す文字列です。MYSQL_ERRNO:条件のエラーコードを表す整数です。
上記の定義は、シグナル(つまりSIGNALまたはRESIGNALステートメント)によって生成されない条件に適用されます。
SIGNAL(またはRESIGNAL)ステートメントが診断領域を埋める場合、そのSET句はRETURNED_SQLSTATE以外の任意の条件情報項目にデータ型の有効な値を割り当てることができます。SIGNALはまた、SIGNALステートメントのSQLSTATEパラメータから取得したRETURNED_SQLSTATE値を設定します。これは、直接そのSET句で設定されるわけではありません。
SIGNALはまた、ステートメント情報項目のNUMBERを1に設定し、ROW_COUNTを-1に設定してエラーを示します。それ以外の場合は0に設定されます。
診断領域のクリアとフィル
非診断SQL文は自動的に診断領域を埋め、SIGNAL および RESIGNAL ステートメントを使用して診断領域の内容を明示的に設定できます。GET DIAGNOSTICS を使用して診断領域を確認し、指定された情報を抽出することができます。また、SHOW WARNINGS または SHOW ERRORS を使用して条件やエラーを表示することもできます。
SQL文が診断領域をクリアして設定する方法は次のとおりです:
サーバーが解析後にステートメントの実行を開始すると、診断領域内の非診断ステートメントをクリアします。診断ステートメントは診断領域をクリアしません。以下のステートメントは診断ステートメントに該当します:
GET DIAGNOSTICSSHOW ERRORSSHOW WARNINGS
ステートメントが条件を発生させた場合、診断領域はそれより前のステートメントに属する条件をクリアします。例外として、
GET DIAGNOSTICSおよびRESIGNALによって発生した条件は、診断領域に追加されてクリアされることはありません。
したがって、診断領域のステートメントは、実行開始時にクリアされない場合でも、ステートメントが条件を発生させた場合にはクリアされます。
以下の例は、さまざまなステートメントが診断領域に与える影響を示し、SHOW WARNINGS を使用してストレージに関する条件情報を表示します。
例1:DROP TABLE ステートメントは診断領域をクリアし、条件が発生した場合に診断領域を埋めます。
obclient> DROP TABLE IF EXISTS test.no_table_found;
Query OK, 0 rows affected, 1 warning
obclient> SHOW WARNINGS;
+-------+------+-------------------------------------+
| Level | Code | Message |
+-------+------+-------------------------------------+
| Note | 1051 | Unknown table 'test.no_table_found' |
+-------+------+-------------------------------------+
1 row in set
例2:SET ステートメントはエラーを生成するため、診断領域をクリアして埋めます。
obclient> SET @var1 = @@var;
ERROR 1193 (HY000): Unknown system variable 'var'
obclient> SHOW WARNINGS;
+-------+------+-------------------------------+
| Level | Code | Message |
+-------+------+-------------------------------+
| Error | 1193 | Unknown system variable 'var' |
+-------+------+-------------------------------+
1 row in set
例3:前の例の SET ステートメントは条件を生成したため、この時点で GET DIAGNOSTICS の唯一有効な条件番号は1です。以下のステートメントは警告を生成し、条件番号2を使用して、診断領域に追加されてクリアされることはありません。
obclient> GET DIAGNOSTICS CONDITION 2 @var2 = MESSAGE_TEXT;
Query OK, 0 rows affected, 1 warning
obclient> SHOW WARNINGS;
+-------+------+------------------------------+
| Level | Code | Message |
+-------+------+------------------------------+
| Error | 1193 | Unknown system variable 'var'|
| Error | 1753 | Invalid condition number |
+-------+------+------------------------------+
2 rows in set
例4:上記の例に基づいて、現在診断領域には2つの条件があるため、同じ GET DIAGNOSTICS ステートメントは正常に実行されます。
obclient> GET DIAGNOSTICS CONDITION 2 @var2 = MESSAGE_TEXT;
Query OK, 0 rows affected
obclient> SELECT @var2;
+---------------------------+
| @var2 |
+---------------------------+
| Invalid condition number |
+---------------------------+
1 row in set
診断領域スタックの動作原理
診断領域がスタックにプッシュされると、最初の(現在の)診断領域は2番目の(スタックの)診断領域となり、新しい現在の診断領域がそのレプリカとして作成されます。以下の場合、診断領域はスタックにプッシュされ、またスタックからポップアップされます:
ステートメントの実行
ステートメントの実行前に診断領域にプッシュされ、その後診断領域がポップアップされます。ステートメントが処理中に終了した場合、複数の診断領域をポップアップできます。これは、適切な処理手順が例外を引き起こさない場合や、処理手順内の
RETURNによって引き起こされる場合です。その後、ポップアップされた診断領域のアラートまたはエラー条件が現在の診断領域に追加されます。ただし、トリガーの場合はエラー条件のみが追加されます。ステートメントが終了すると、呼び出し元は現在の診断領域でこれらの条件を確認できます。
ステートメント内で条件処理手順を実行する
条件処理手順のアクティベーションによりプッシュが発生した場合、スタック上の診断領域はプッシュ前の現在の領域(ステートメント内)です。新しい現在の診断領域は処理手順の現在の診断領域です。
GET [CURRENT] DIAGNOSTICSおよびGET STACKED DIAGNOSTICSは、処理手順内で現在(処理手順)およびスタック(ステートメント)の診断領域の内容にアクセスするために使用できます。最初は同じ結果を返しますが、処理手順内で実行される文は現在の診断領域を変更し、一般的なルールに基づいてその内容をクリアして設定します。RESIGNALを除き、処理手順内で実行される文はスタック上の診断領域を変更できません。処理手順が正常に実行された場合、現在(処理手順)の診断領域がポップアップされ、スタック(ステートメント)の診断領域が再び現在の診断領域となります。処理手順の実行中に処理手順の診断領域に追加された条件は、現在の診断領域に追加されます。
RESIGNALの実行ステートメント内の複合文で条件処理手順が実行される際、
RESIGNALステートメントは利用可能なエラー条件情報を渡すために使用されます。RESIGNALは情報を渡す前に一部または全部の情報を変更し、スタック上の診断領域を変更する可能性があります。詳細については、RESIGNALを参照してください。