Måden jeg håndterer dette på er at konfigurere min databaseindpakningsklasse til altid at kaste en undtagelse, når du støder på en databasefejl. Så for eksempel kan jeg have en klasse kaldet MySQL
med følgende funktioner:
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());
}
Hver gang en forespørgsel mislykkes, udløses en almindelig PHP-undtagelse. Bemærk, at jeg også ville smide disse inde fra andre steder, som en connect()
funktion eller en selectDb()
funktion, afhængig af om operationen lykkedes eller ej.
Med den opsætning er du godt i gang. Ethvert sted, du forventer, at du muligvis skal håndtere en databasefejl, skal du gøre noget i stil med følgende:
//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.
}
}
Rediger
Som svar på plakatens kommentar nedenfor, har du nogle begrænsede oplysninger til rådighed for dig til at hjælpe med at diagnosticere et problem med en udenlandsk nøgle. Fejlteksten oprettet af en fejlbehæftet fremmednøgle og returneret af mysql_error()
ser sådan ud:
Cannot delete or update a parent row:
a foreign key constraint fails
(`dbname`.`childtable`, CONSTRAINT `FK_name_1` FOREIGN KEY
(`fieldName`) REFERENCES `parenttable` (`fieldName`));
Hvis dine fremmednøgler er komplekse nok til, at du ikke kan være sikker på, hvad der kan forårsage en fremmednøglefejl for en given forespørgsel, så kan du sandsynligvis parse denne fejltekst for at hjælpe med at finde ud af det. Kommandoen SHOW ENGINE INNODB STATUS
returnerer også et mere detaljeret resultat for den seneste udenlandske nøglefejl.
Ellers bliver du sikkert nødt til at grave lidt selv. Følgende forespørgsel vil give dig en liste over fremmednøgler på en given tabel, som du kan undersøge for information:
select * from information_schema.table_constraints
WHERE table_schema=schema() AND table_name='table_name';
Desværre tror jeg ikke, der er en magisk kugle til din løsning ud over at undersøge fejlene og begrænsningerne meget omhyggeligt.