La façon dont je gère cela est de configurer ma classe wrapper de base de données pour toujours lever une exception lorsque vous rencontrez une erreur de base de données. Ainsi, par exemple, je pourrais avoir une classe appelée MySQL
avec les fonctions suivantes :
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());
}
Chaque fois qu'une requête échoue, une exception PHP normale est levée. Notez que je les lancerais également depuis d'autres endroits, comme un connect()
fonction ou un selectDb()
fonction, selon que l'opération a réussi ou non.
Avec cette configuration, vous êtes prêt à partir. Partout où vous pensez avoir besoin de gérer une erreur de base de données, procédez comme suit :
//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.
}
}
Modifier
En réponse au commentaire de l'affiche ci-dessous, vous disposez d'informations limitées pour vous aider à diagnostiquer un problème de clé étrangère. Le texte d'erreur créé par une contrainte de clé étrangère ayant échoué et renvoyé par mysql_error()
ressemble à ceci :
Cannot delete or update a parent row:
a foreign key constraint fails
(`dbname`.`childtable`, CONSTRAINT `FK_name_1` FOREIGN KEY
(`fieldName`) REFERENCES `parenttable` (`fieldName`));
Si vos clés étrangères sont suffisamment complexes pour que vous ne puissiez pas être sûr de ce qui pourrait provoquer une erreur de clé étrangère pour une requête donnée, vous pouvez probablement analyser ce texte d'erreur pour vous aider à le comprendre. La commande SHOW ENGINE INNODB STATUS
renvoie également un résultat plus détaillé pour la dernière erreur de clé étrangère.
Sinon, vous devrez probablement creuser vous-même. La requête suivante vous donnera une liste de clés étrangères sur une table donnée, que vous pourrez examiner pour information :
select * from information_schema.table_constraints
WHERE table_schema=schema() AND table_name='table_name';
Malheureusement, je ne pense pas qu'il y ait une solution miracle à votre solution autre que d'examiner très attentivement les erreurs et les contraintes.