Sättet jag hanterar detta är att ställa in min databasomslagsklass så att den alltid kastar ett undantag när du stöter på ett databasfel. Så till exempel kan jag ha en klass som heter MySQL
med följande 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());
}
Varje gång en fråga misslyckas, skapas ett vanligt PHP-undantag. Observera att jag skulle kasta dessa från andra platser också, som en connect()
funktion eller en selectDb()
funktion, beroende på om operationen lyckades eller inte.
Med den inställningen är du bra att gå. Var som helst där du förväntar dig att du kan behöva hantera ett databasfel, gör något i stil med följande:
//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.
}
}
Redigera
Som svar på affischens kommentar nedan har du en del begränsad information tillgänglig för att hjälpa dig att diagnostisera ett problem med främmande nyckel. Feltexten skapad av en misslyckad spärrnyckel och returneras av mysql_error()
ser ut ungefär så här:
Cannot delete or update a parent row:
a foreign key constraint fails
(`dbname`.`childtable`, CONSTRAINT `FK_name_1` FOREIGN KEY
(`fieldName`) REFERENCES `parenttable` (`fieldName`));
Om dina främmande nycklar är tillräckligt komplexa för att du inte kan vara säker på vad som kan orsaka ett främmande nyckelfel för en given fråga, kan du förmodligen analysera den här feltexten för att hjälpa dig att reda ut det. Kommandot SHOW ENGINE INNODB STATUS
returnerar ett mer detaljerat resultat för det senaste felet med främmande nyckel också.
Annars måste du förmodligen gräva lite själv. Följande fråga ger dig en lista över främmande nycklar i en given tabell, som du kan undersöka för information:
select * from information_schema.table_constraints
WHERE table_schema=schema() AND table_name='table_name';
Tyvärr tror jag inte att det finns en magisk kula i din lösning annat än att undersöka felen och begränsningarna mycket noggrant.