例外
Nette Database は例外の階層を使います。基底クラスは Nette\Database\DriverException
で、PDOException を継承し、データベースのエラーを扱うための機能を強化します。
getDriverCode()メソッドはデータベースドライバのエラーコードを返します。getSqlState()メソッドは SQLSTATE のコードを返します。getQueryString()とgetParameters()メソッドで、もとのクエリとそのパラメータを取り出せます。
DriverException クラスは、次の特化した例外に継承されます。
ConnectionException– データベースサーバーへの接続に失敗したことを示します。ConnectionLostException.{data-version:3.2.9} – 処理の途中で接続が切れました(サーバーの再起動、ネットワークの障害、idle timeout)。続けて使う前に接続し直す必要があります。
ConstraintViolationException– データベースの制約違反の基底クラスで、次の例外がこれを継承します。ForeignKeyConstraintViolationException– 外部キー制約の違反。NotNullConstraintViolationException– NOT NULL 制約の違反。UniqueConstraintViolationException– 一意性の制約の違反。CheckConstraintViolationException.{data-version:3.2.9} – CHECK 制約の違反。
DeadlockException.{data-version:3.2.9} – サーバーが検出した deadlock または直列化の衝突。トランザクションはロールバックされ、やり直せます。LockTimeoutException.{data-version:3.2.9} – ロック待ちの制限時間を超えました。その文は中止されましたが、それを囲むトランザクションはふつう開いたままです。
次の例は UniqueConstraintViolationException
の捕まえ方を示します。これはデータベースにすでにあるメールアドレスでユーザーを挿入しようとしたときに起きます(email
列に一意インデックスがあるものとします)。
try {
$database->query('INSERT INTO users', [
'email' => 'john@example.com',
'name' => 'John Doe',
'password' => $hashedPassword,
]);
} catch (Nette\Database\UniqueConstraintViolationException $e) {
echo 'このメールアドレスのユーザーはすでに存在します。';
} catch (Nette\Database\DriverException $e) {
echo '登録の途中でエラーが起きました: ' . $e->getMessage();
}