PDO の errorInfo でエラー内容を確認する

PDO でエラーが起きたとき、何が原因かを特定するには errorInfo メソッドが役に立つ。errorInfo は PDO オブジェクトと PDOStatement オブジェクトの両方に用意されており、直近のエラー情報を配列で返す。

errorInfo の戻り値

errorInfo は 3 要素の配列を返す。

インデックス内容
0SQLSTATE コード42S02
1ドライバ固有エラーコード1146
2ドライバ固有メッセージTable 'mydb.users' doesn't exist

インデックス 0 の SQLSTATE コードは ISO/ANSI SQL の標準規格で定められたもので、データベースの種類を問わず共通のコードが返る。一方、インデックス 1 と 2 はドライバ(MySQL、PostgreSQL など)固有の情報になる。

PDO オブジェクトの errorInfo

PDO オブジェクトの errorInfo は、prepare や exec など PDO 自体のメソッドで発生したエラーを返す。

$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );

$result = $pdo->exec( 'DROP TABLE nonexistent_table' );

if ( $result === false )
{
    $error = $pdo->errorInfo();
    echo $error[0]; // SQLSTATE コード
    echo $error[1]; // ドライバエラーコード
    echo $error[2]; // エラーメッセージ
}

ERRMODE_SILENT の場合はエラーが自動で報告されないため、戻り値を確認してから errorInfo を呼ぶ流れになる。

PDOStatement の errorInfo

PDOStatement の errorInfo は、execute や fetch など、ステートメント単位で発生したエラーを返す。

$stmt = $pdo->prepare( 'SELECT * FROM nonexistent_table' );
$stmt->execute();

$error = $stmt->errorInfo();

if ( $error[0] !== '00000' )
{
    echo 'SQLSTATE: ' . $error[0];
    echo 'コード: ' . $error[1];
    echo 'メッセージ: ' . $error[2];
}

SQLSTATE コード「00000」はエラーなしを意味する。この値でないなら何らかの問題が発生している。

errorCode との違い

PDO には errorInfo のほかに errorCode メソッドもある。

errorCode

SQLSTATE コードだけを文字列で返す。エラーの有無を手早く判定したいときに使う。

errorInfo

SQLSTATE コード、ドライバ固有のコード、メッセージの 3 要素を配列で返す。原因の特定にはこちらが必要になる。

errorCode は errorInfo のインデックス 0 と同じ値を返すだけなので、詳しい原因を知りたければ errorInfo を使うほうがよい。

ERRMODE_EXCEPTION との使い分け

ERRMODE_EXCEPTION を設定している場合、エラーは PDOException として自動的にスローされるため、errorInfo を明示的に呼ぶ場面は少なくなる。PDOException の getMessage() にエラーメッセージが含まれるからだ。

try
{
    $stmt = $pdo->prepare( 'SELECT * FROM nonexistent_table' );
    $stmt->execute();
}
catch ( PDOException $e )
{
    // getMessage() で十分な情報が得られる
    echo $e->getMessage();

    // より詳しく知りたい場合は errorInfo も使える
    $error = $stmt->errorInfo();
    echo 'ドライバコード: ' . $error[1];
}

実務では ERRMODE_EXCEPTION を基本にしつつ、ドライバ固有のエラーコードで処理を分岐させたいときだけ errorInfo を併用する、という使い方が現実的だろう。

よく見る SQLSTATE コード

代表的な SQLSTATE コードを知っておくと、エラーの切り分けが速くなる。

SQLSTATE意味
00000エラーなし
23000一意制約違反(重複)
42S02テーブルが存在しない
42000SQL 構文エラー

たとえば 23000 が返ってきたら、UNIQUE 制約やプライマリキーの重複が原因だとすぐにわかる。errorInfo と組み合わせれば、エラーの種類に応じたハンドリングが可能になる。