Mysql
 sql >> Base de données >  >> RDS >> Mysql

Gestion des exceptions de clé étrangère en PHP

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.