Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Umgang mit Fremdschlüsselausnahmen in PHP

Ich handhabe dies so, dass ich meine Datenbank-Wrapper-Klasse so einrichte, dass sie immer eine Ausnahme auslöst, wenn ein Datenbankfehler auftritt. So könnte ich zum Beispiel eine Klasse namens MySQL haben mit folgenden Funktionen:

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());
}

Jedes Mal, wenn eine Abfrage fehlschlägt, wird eine reguläre PHP-Ausnahme ausgelöst. Beachten Sie, dass ich diese auch von anderen Stellen aus werfen würde, wie ein connect() Funktion oder eine selectDb() abhängig davon, ob die Operation erfolgreich war oder nicht.

Mit dieser Einrichtung können Sie loslegen. Überall dort, wo Sie erwarten, dass Sie möglicherweise einen Datenbankfehler behandeln müssen, tun Sie etwas wie das Folgende:

//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.
    }
}

Bearbeiten

Als Antwort auf den Kommentar des Posters unten stehen Ihnen einige begrenzte Informationen zur Verfügung, um bei der Diagnose eines Fremdschlüsselproblems zu helfen. Der Fehlertext, der durch eine fehlgeschlagene Fremdschlüsselbeschränkung erstellt und von mysql_error() zurückgegeben wird sieht in etwa so aus:

Cannot delete or update a parent row:
a foreign key constraint fails
(`dbname`.`childtable`, CONSTRAINT `FK_name_1` FOREIGN KEY
(`fieldName`) REFERENCES `parenttable` (`fieldName`));

Wenn Ihre Fremdschlüssel so komplex sind, dass Sie nicht sicher sind, was einen Fremdschlüsselfehler für eine bestimmte Abfrage verursachen könnte, könnten Sie diesen Fehlertext wahrscheinlich analysieren, um ihn herauszufinden. Der Befehl SHOW ENGINE INNODB STATUS gibt auch ein detaillierteres Ergebnis für den letzten Fremdschlüsselfehler zurück.

Andernfalls müssen Sie wahrscheinlich selbst etwas graben. Die folgende Abfrage gibt Ihnen eine Liste von Fremdschlüsseln für eine bestimmte Tabelle, die Sie nach Informationen durchsuchen können:

select * from information_schema.table_constraints
WHERE table_schema=schema() AND table_name='table_name';

Leider glaube ich nicht, dass es eine Wunderwaffe für Ihre Lösung gibt, außer die Fehler und Einschränkungen sehr sorgfältig zu untersuchen.