Cách tôi xử lý điều này là thiết lập lớp trình bao bọc cơ sở dữ liệu của tôi để luôn ném ra một ngoại lệ khi bạn gặp lỗi cơ sở dữ liệu. Vì vậy, chẳng hạn, tôi có thể có một lớp được gọi là MySQL
với các chức năng sau:
public function query($query_string)
{
$this->queryId = mysql_query($query_string,$this->connectionId);
if (! $this->queryId) {
$this->_throwException($query_string);
}
return $this->queryId;
}
private function _throwException($query = null)
{
$msg = mysql_error().". Query was:\n\n".$query.
"\n\nError number: ".mysql_errno();
throw new Exception($msg,mysql_errno());
}
Bất kỳ khi nào một truy vấn không thành công, một ngoại lệ PHP thông thường sẽ được ném ra. Lưu ý rằng tôi cũng sẽ ném những thứ này từ bên trong những nơi khác, chẳng hạn như connect()
hoặc một selectDb()
chức năng, tùy thuộc vào việc thao tác có thành công hay không.
Với thiết lập đó, bạn đã sẵn sàng. Bất kỳ nơi nào bạn mong đợi rằng bạn có thể cần phải xử lý lỗi cơ sở dữ liệu, hãy làm như sau:
//assume $db has been set up to be an instance of the MySQL class
try {
$db->query("DELETE FROM parent WHERE id=123");
} catch (Exception $e) {
//uh-oh, maybe a foreign key restraint failed?
if ($e->getCode() == 'mysql foreign key error code') {
//yep, it failed. Do some stuff.
}
}
Chỉnh sửa
Đáp lại nhận xét của người đăng dưới đây, bạn có một số thông tin hạn chế dành cho mình để giúp chẩn đoán sự cố khóa ngoại. Văn bản lỗi được tạo bởi khóa ngoại không thành công và được trả về bởi mysql_error()
trông giống như sau:
Cannot delete or update a parent row:
a foreign key constraint fails
(`dbname`.`childtable`, CONSTRAINT `FK_name_1` FOREIGN KEY
(`fieldName`) REFERENCES `parenttable` (`fieldName`));
Nếu khóa ngoại của bạn đủ phức tạp đến mức bạn không thể chắc chắn điều gì có thể gây ra lỗi khóa ngoại cho một truy vấn nhất định, thì bạn có thể phân tích cú pháp văn bản lỗi này để giúp tìm ra nó. Lệnh SHOW ENGINE INNODB STATUS
cũng trả về kết quả chi tiết hơn cho lỗi khóa ngoại mới nhất.
Nếu không, có thể bạn sẽ phải tự mình đào một số thứ. Truy vấn sau sẽ cung cấp cho bạn danh sách các khóa ngoại trên một bảng nhất định, bạn có thể kiểm tra danh sách này để biết thông tin:
select * from information_schema.table_constraints
WHERE table_schema=schema() AND table_name='table_name';
Thật không may, tôi không nghĩ rằng có một viên đạn thần kỳ nào cho giải pháp của bạn ngoài việc kiểm tra các lỗi và ràng buộc rất cẩn thận.