De manier waarop ik hiermee omga, is door mijn database-wrapperklasse zo in te stellen dat er altijd een uitzondering wordt gegenereerd wanneer u een databasefout tegenkomt. Ik heb bijvoorbeeld een klasse met de naam MySQL
met de volgende functies:
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());
}
Elke keer dat een query mislukt, wordt er een reguliere PHP-uitzondering gegenereerd. Merk op dat ik deze ook vanuit andere plaatsen zou gooien, zoals een connect()
functie of een selectDb()
functie, afhankelijk van of de bewerking is gelukt of niet.
Met die instelling ben je klaar om te gaan. Overal waar u verwacht dat u een databasefout moet afhandelen, doet u zoiets als het volgende:
//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.
}
}
Bewerken
Als reactie op de opmerking van de poster hieronder, heb je beperkte informatie tot je beschikking om te helpen bij het diagnosticeren van een probleem met een externe sleutel. De fouttekst gemaakt door een mislukte externe sleutelbeperking en geretourneerd door mysql_error()
ziet er ongeveer zo uit:
Cannot delete or update a parent row:
a foreign key constraint fails
(`dbname`.`childtable`, CONSTRAINT `FK_name_1` FOREIGN KEY
(`fieldName`) REFERENCES `parenttable` (`fieldName`));
Als uw externe sleutels zo complex zijn dat u niet zeker weet wat een externe sleutelfout voor een bepaalde zoekopdracht kan veroorzaken, kunt u deze fouttekst waarschijnlijk ontleden om erachter te komen. Het commando SHOW ENGINE INNODB STATUS
geeft ook een gedetailleerder resultaat voor de laatste buitenlandse sleutelfout.
Anders moet je waarschijnlijk zelf wat gaan graven. De volgende zoekopdracht geeft u een lijst met externe sleutels in een bepaalde tabel, die u ter informatie kunt bekijken:
select * from information_schema.table_constraints
WHERE table_schema=schema() AND table_name='table_name';
Helaas denk ik niet dat er een wondermiddel voor uw oplossing is, behalve dat u de fouten en beperkingen zeer zorgvuldig onderzoekt.