Question

J'ai affaire à une table MySQL qui définit la colonne JobName comme UNIQUE.Si quelqu'un essaie de sauvegarder un nouveau Job dans la base de données en utilisant un JobName déjà présent dans la base de données, MySQL génère un avertissement.

J'aimerais pouvoir détecter cet avertissement, tout comme une erreur, dans mon script PHP et le traiter de manière appropriée.Idéalement, j'aimerais savoir quel type d'avertissement MySQL a émis afin que je puisse créer une branche dans le code pour le gérer.

Est-ce possible?Sinon, est-ce parce que MySQL n'a pas cette capacité, PHP n'a pas cette capacité, ou les deux ?

Était-ce utile?

La solution

Pour que les avertissements soient « signalés » nativement à PHP, il faudrait modifier le pilote mysql/mysqli, ce qui dépasse évidemment la portée de cette question.Au lieu de cela, vous devrez essentiellement vérifier chaque requête que vous effectuez sur la base de données pour détecter les avertissements :

$warningCountResult = mysql_query("SELECT @@warning_count");
if ($warningCountResult) {
    $warningCount = mysql_fetch_row($warningCountResult );
    if ($warningCount[0] > 0) {
        //Have warnings
        $warningDetailResult = mysql_query("SHOW WARNINGS");
        if ($warningDetailResult ) {
            while ($warning = mysql_fetch_assoc(warningDetailResult) {
                //Process it
            }
        }
    }//Else no warnings
}

Évidemment, cela coûtera horriblement cher à appliquer en masse, vous devrez donc peut-être réfléchir attentivement au moment et à la manière dont les avertissements peuvent survenir (ce qui peut vous amener à refactoriser pour les éliminer).

Pour référence, MySQL AFFICHER LES AVERTISSEMENTS

Bien sûr, vous pouvez vous passer de la requête initiale pour le SELECT @@warning_count, ce qui vous éviterait une requête par exécution, mais je l'ai inclus par souci d'exhaustivité.

Autres conseils

D'abord, vous devriez désactiver les avertissements pour que vos visiteurs ne voient pas votre MySQL les erreurs.Deuxièmement, quand vous appelez mysql_query(), vous devriez vérifier s'il a renvoyé false.Si c'est le cas, appelez mysql_errno() pour découvrir ce qui n'allait pas.Faites correspondre le numéro renvoyé aux codes d'erreur sur cette page.

Il semble que ce soit le numéro d'erreur que vous recherchez :

Erreur:1169 ÉTAT SQL :23000 (ER_DUP_UNIQUE)

Message:Impossible d'écrire, en raison d'une contrainte unique, dans la table '%s'

ini_set('mysql.trace_mode', 1)

c'est peut-être ce que vous recherchez.

Les erreurs PHP peuvent ensuite être traitées avec un gestionnaire d'erreurs PHP personnalisé, mais vous pouvez également simplement désactiver l'affichage des erreurs php car elles sont généralement enregistrées dans un fichier journal (cela dépend de votre configuration php).

en fonction du framework (le cas échéant) que vous utilisez, je vous suggère de faire une requête pour vérifier vous-même le nom du travail et de créer les informations appropriées pour l'utilisateur avec le reste des validations du formulaire.

En fonction du nombre de noms de tâches, vous pouvez envoyer les noms à la vue qui contient le formulaire et utiliser javascript pour indiquer l'utilisation qui est utilisée.

Si cela n'a pas de sens pour vous, alors pour résumer mon point de vue, c'est ceci :Ne concevez pas votre programme et/ou votre utilisateur pour essayer de faire des choses illégales et détecter les erreurs lorsqu'ils le font et les gérer ensuite.Il est bien préférable, à mon humble avis, de concevoir votre système pour ne pas créer d'erreurs.Gardez les erreurs aux bugs réels :)

Mise à jour pour supprimer les éléments concernant les fonctions errno dont je réalise maintenant qu'ils ne s'appliquent pas à votre situation...

Une chose dont il faut se méfier dans MySQL UPDATE déclarations: mysqli_affected_rows() renverra zéro même si le WHERE la clause correspondait aux lignes, mais la SET La clause n'a pas réellement modifié les valeurs des données.Je mentionne cela uniquement parce que ce comportement a provoqué un bug dans un système que j'ai examiné une fois : le programmeur a utilisé cette valeur de retour pour vérifier les erreurs après une mise à jour, en supposant qu'un zéro signifiait qu'une erreur s'était produite.Cela signifiait simplement que l'utilisateur n'avait modifié aucune valeur existante avant de cliquer sur le bouton de mise à jour.

Donc je suppose qu'en utilisant mysqli_affected_rows() on ne peut pas non plus compter sur de tels avertissements, à moins que vous n'ayez quelque chose comme un update_time colonne de votre table qui se verra toujours attribuer une nouvelle valeur d'horodatage lors de la mise à jour.Ce genre de solution de contournement semble cependant un peu compliqué.

Vous pouvez détecter les violations de clé unique à l'aide de l'erreur d'instruction mysqli no.L'instruction mysqli renvoie l'erreur 1062, c'est-à-dire ER_DUP_ENTRY.Vous pouvez rechercher l'erreur 1062 et imprimer un message d'erreur approprié.Si vous souhaitez également imprimer votre colonne (jobName) dans le cadre de votre message d'erreur, vous devez analyser la chaîne d'erreur de l'instruction.

  if($stmt = $mysqli->prepare($sql)){
            $stmt->bind_param("sss",
            $name,
            $identKey,
            $domain);


            $stmt->execute();
            if($mysqli->affected_rows != 1)  {
                        //This will return errorno 1062
                trigger_error('mysql error >> '.$stmt->errno .'::' .$stmt->error, E_USER_ERROR);
                exit(1);
            }
            $stmt->close();
        } else {

            trigger_error('mysql error >> '. $mysqli->errno.'::'.$mysqli->error,E_USER_ERROR);
        }

Il est possible d'obtenir les avertissements, et de manière plus efficace avec mysqli qu'avec mysql.

Voici le code proposé sur le manuel page sur php.net pour la propriété mysqli->warning_count :

$mysqli->query($query);

if ($mysqli->warning_count) {
    if ($result = $mysqli->query("SHOW WARNINGS")) {
        $row = $result->fetch_row();
        printf("%s (%d): %s\n", $row[0], $row[1], $row[2]);
        $result->close();
    }
}

Remarque sur la suppression des avertissements :En général, ce n'est pas une bonne idée d'empêcher l'affichage des avertissements, car vous pourriez manquer quelque chose d'important.Si vous devez absolument masquer les avertissements pour une raison quelconque, vous pouvez le faire individuellement en plaçant un @ signez devant la déclaration.De cette façon, vous n'avez pas besoin de désactiver tous les rapports d'avertissement et pouvez les limiter à une instance spécifique.

Exemple:

 // this suppresses warnings that might result if there is no field titled "field" in the result
 $field_value = @mysql_result($result, 0, "field");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top