GET [CURRENT] DIAGNOSTICS
{
statement_information_item
[, statement_information_item] ...
| CONDITION condition_number
condition_information_item
[, condition_information_item] ...
}
statement_information_item:
target = statement_information_item_name
condition_information_item:
target = condition_information_item_name
statement_information_item_name:
NUMBER
| ROW_COUNT
condition_information_item_name:
CLASS_ORIGIN
| SUBCLASS_ORIGIN
| RETURNED_SQLSTATE
| MESSAGE_TEXT
| MYSQL_ERRNO
| CONSTRAINT_CATALOG
| CONSTRAINT_SCHEMA
| CONSTRAINT_NAME
| CATALOG_NAME
| SCHEMA_NAME
| TABLE_NAME
| COLUMN_NAME
| CURSOR_NAME
condition_number, target:
(see following discussion)
SQL ステートメントは、診断領域を移入する診断情報を生成します。GET DIAGNOSTICS
ステートメントを使用すると、アプリケーションでこの情報を検査できます。これは、MySQL 5.6.4 の時点で使用できます。(SHOW WARNINGS
または SHOW ERRORS
を使用して、条件またはエラーを確認することもできます。)
GET DIAGNOSTICS
を実行するために特殊な権限は必要ありません。
キーワード CURRENT
は、現在の診断領域から情報を取得することを示します。MySQL では、それがデフォルトの動作であるため、これは何の効果もありません。
GET DIAGNOSTICS
は通常、ストアドプログラム内のハンドラで使用されますが、これは、任意の SQL ステートメントの実行をチェックするためにハンドラのコンテキストの外部で許可される MySQL 拡張です。たとえば、mysql クライアントプログラムを呼び出す場合は、プロンプトで次のステートメントを入力できます。
mysql> DROP TABLE test.no_such_table;
ERROR 1051 (42S02): Unknown table 'test.no_such_table'
mysql> GET DIAGNOSTICS CONDITION 1
-> @p1 = RETURNED_SQLSTATE, @p2 = MESSAGE_TEXT;
mysql> SELECT @p1, @p2;
+-------+------------------------------------+
| @p1 | @p2 |
+-------+------------------------------------+
| 42S02 | Unknown table 'test.no_such_table' |
+-------+------------------------------------+
診断領域については、セクション13.6.7.7「MySQL の診断領域」を参照してください。簡単に言うと、ここには次の 2 種類の情報が含まれています。
発生した条件の数や、影響を受けた行数などのステートメント情報。
エラーコードやメッセージなどの条件情報。ステートメントが複数の条件を発生させた場合、診断領域のこの部分には条件ごとの条件領域が含まれています。ステートメントがどの条件も発生させない場合、診断領域のこの部分は空です。
3 つの条件を生成するステートメントの場合、診断領域には、次のようなステートメント情報と条件情報が含まれています。
Statement information:
row count
... other statement information items ...
Condition area list:
Condition area 1:
error code for condition 1
error message for condition 1
... other condition information items ...
Condition area 2:
error code for condition 2:
error message for condition 2
... other condition information items ...
Condition area 3:
error code for condition 3
error message for condition 3
... other condition information items ...
GET DIAGNOSTICS
はステートメントまたは条件情報のどちらかを取得できますが、同じステートメントで両方を取得することはできません。
-
ステートメント情報を取得するには、目的のステートメント項目をターゲット変数に取得します。
GET DIAGNOSTICS
の次の例では、使用可能な条件の数と影響を受けた行数をユーザー変数@p1
と@p2
に割り当てます。GET DIAGNOSTICS @p1 = NUMBER, @p2 = ROW_COUNT;
-
条件情報を取得するには、条件番号を指定し、目的の条件項目をターゲット変数に取得します。
GET DIAGNOSTICS
の次の例では、SQLSTATE 値とエラーメッセージをユーザー変数@p3
と@p4
に割り当てます。GET DIAGNOSTICS CONDITION 1 @p3 = RETURNED_SQLSTATE, @p4 = MESSAGE_TEXT;
取得リストには、カンマで区切られた 1 つ以上の
代入を指定します。各代入では、ターゲット変数と、このステートメントがステートメントまたは条件情報のどちらを取得するかに応じて target
= item_name
statement_information_item_name
または condition_information_item_name
指示子のどちらかを指定します。
項目情報を格納するための有効な target
指示子は、ストアドプロシージャーやストアドファンクションのパラメータ、DECLARE
で宣言されたストアドプログラムのローカル変数、ユーザー定義変数のいずれかです。
有効な condition_number
指示子は、ストアドプロシージャーやストアドファンクションのパラメータ、DECLARE
で宣言されたストアドプログラムのローカル変数、ユーザー定義変数、システム変数、リテラルのいずれかです。文字リテラルには、_charset
イントロデューサを含めることができます。条件番号が 1 から、情報が含まれている条件領域の数までの範囲にない場合は、警告が発生します。この場合、この警告は、診断領域にその領域をクリアすることなく追加されます。
現在は、条件が発生したときに、MySQL が GET DIAGNOSTICS
によって認識されるすべての条件項目を移入するわけではありません。例:
mysql> GET DIAGNOSTICS CONDITION 1
-> @p5 = SCHEMA_NAME, @p6 = TABLE_NAME;
mysql> SELECT @p5, @p6;
+------+------+
| @p5 | @p6 |
+------+------+
| | |
+------+------+
標準 SQL では、複数の条件が存在する場合、最初の条件は前の SQL ステートメントに対して返された SQLSTATE
値に関連しています。MySQL では、これが保証されません。メインのエラーを取得するために、次のように行うことはできません。
GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;
代わりに、まず条件数を取得し、次にそれを使用してどの条件番号を検査するかを指定します。
GET DIAGNOSTICS @cno = NUMBER;
GET DIAGNOSTICS CONDITION @cno @errno = MYSQL_ERRNO;
許可されるステートメント情報と条件情報の項目、および条件が発生したときにどの項目が移入されるかについては、セクション13.6.7.7.2「診断領域の情報項目」を参照してください。
ストアドプロシージャーのコンテキストで GET DIAGNOSTICS
と例外ハンドラを使用して、挿入操作の結果を評価する例を次に示します。挿入が成功した場合、このプロシージャーは GET DIAGNOSTICS
を使用して、影響を受けた行数を取得します。これは、診断領域がクリアされていないかぎり、GET DIAGNOSTICS
を複数回使用してステートメントに関する情報を取得できることを示しています。
CREATE PROCEDURE do_insert(value INT)
BEGIN
-- Declare variables to hold diagnostics area information
DECLARE code CHAR(5) DEFAULT '00000';
DECLARE msg TEXT;
DECLARE rows INT;
DECLARE result TEXT;
-- Declare exception handler for failed insert
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
END;
-- Perform the insert
INSERT INTO t1 (int_col) VALUES(value);
-- Check whether the insert was successful
IF code = '00000' THEN
GET DIAGNOSTICS rows = ROW_COUNT;
SET result = CONCAT('insert succeeded, row count = ',rows);
ELSE
SET result = CONCAT('insert failed, error = ',code,', message = ',msg);
END IF;
-- Say what happened
SELECT result;
END;
t1.int_col
が、NOT NULL
として宣言された整数カラムであるとします。このプロシージャーは、NULL
以外の値と NULL
値を挿入するために呼び出されると、それぞれ次の結果を生成します。
mysql> CALL do_insert(1);
+---------------------------------+
| result |
+---------------------------------+
| insert succeeded, row count = 1 |
+---------------------------------+
mysql> CALL do_insert(NULL);
+-------------------------------------------------------------------------+
| result |
+-------------------------------------------------------------------------+
| insert failed, error = 23000, message = Column 'int_col' cannot be null |
+-------------------------------------------------------------------------+
GET DIAGNOSTICS
は、条件ハンドラ内で、診断領域をクリアしたり、そのハンドラをアクティブ化した条件に関する情報が失われたりする可能性のあるほかのステートメントの前に使用するようにしてください。診断領域がいつ設定およびクリアされるかについては、セクション13.6.7.7「MySQL の診断領域」を参照してください。