Il modo in cui lo gestisco è impostare la mia classe wrapper del database per generare sempre un'eccezione quando si verifica un errore del database. Quindi, per esempio, potrei avere una classe chiamata MySQL
con le seguenti funzioni:
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());
}
Ogni volta che una query non riesce, viene generata una normale eccezione PHP. Nota che li getterei anche da altri posti, come un connect()
funzione o un selectDb()
funzione, a seconda che l'operazione sia riuscita o meno.
Con quella configurazione, sei a posto. In qualsiasi luogo in cui ti aspetti di dover gestire un errore del database, esegui una procedura simile alla seguente:
//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.
}
}
Modifica
In risposta al commento del poster di seguito, hai alcune informazioni limitate a tua disposizione per aiutare a diagnosticare un problema di chiave esterna. Il testo di errore creato da un vincolo di chiave esterna fallito e restituito da mysql_error()
assomiglia a questo:
Cannot delete or update a parent row:
a foreign key constraint fails
(`dbname`.`childtable`, CONSTRAINT `FK_name_1` FOREIGN KEY
(`fieldName`) REFERENCES `parenttable` (`fieldName`));
Se le tue chiavi esterne sono abbastanza complesse da non poter essere sicuro di cosa potrebbe causare un errore di chiave esterna per una determinata query, probabilmente potresti analizzare questo testo di errore per capirlo. Il comando SHOW ENGINE INNODB STATUS
restituisce un risultato più dettagliato anche per l'ultimo errore di chiave esterna.
Altrimenti, probabilmente dovrai scavare un po' da solo. La seguente query ti fornirà un elenco di chiavi esterne su una determinata tabella, che puoi esaminare per informazioni:
select * from information_schema.table_constraints
WHERE table_schema=schema() AND table_name='table_name';
Sfortunatamente, non credo che ci sia una bacchetta magica per la tua soluzione oltre all'esaminare gli errori e i vincoli con molta attenzione.