Domanda

Ho a che fare con una tabella MySQL che definisce la colonna JobName come UNICA.Se qualcuno tenta di salvare un nuovo lavoro nel database utilizzando un JobName già presente nel database, MySQL lancia un avviso.

Vorrei poter rilevare questo avviso, proprio come un errore, nel mio script PHP e gestirlo in modo appropriato.Idealmente, vorrei sapere che tipo di avviso ha lanciato MySQL in modo da poter ramificare il codice per gestirlo.

È possibile?In caso contrario, è perché MySQL non ha questa capacità, PHP non ha questa capacità o entrambi?

È stato utile?

Soluzione

Affinché gli avvisi vengano "contrassegnati" in PHP in modo nativo, sarebbero necessarie modifiche al driver mysql/mysqli, che ovviamente va oltre lo scopo di questa domanda.Dovrai invece controllare sostanzialmente ogni query effettuata sul database per eventuali avvisi:

$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
}

Ovviamente sarà terribilmente costoso applicarlo in massa, quindi potresti dover pensare attentamente a quando e come potrebbero sorgere gli avvisi (il che potrebbe portarti al refactoring per eliminarli).

Per riferimento, MySQL MOSTRA AVVERTENZE

Naturalmente, potresti fare a meno della query iniziale per il file SELECT @@warning_count, che ti farebbe risparmiare una query per esecuzione, ma l'ho incluso per pedante completezza.

Altri suggerimenti

Per prima cosa dovresti disattivare gli avvisi in modo che i tuoi visitatori non vedano il tuo MySQL errori.Secondo, quando chiami mysql_query(), dovresti controllare se ha restituito false.Se così fosse, chiama mysql_errno() per scoprire cosa è andato storto.Abbina il numero restituito ai codici di errore su questa pagina.

Sembra che questo sia il numero di errore che stai cercando:

Errore:1169 STATOSQL:23000 (ER_DUP_UNIQUE)

Messaggio:Impossibile scrivere nella tabella '%s' a causa di un vincolo univoco

ini_set('mysql.trace_mode', 1)

potrebbe essere quello che stai cercando.

Gli errori PHP possono quindi essere gestiti con un gestore errori PHP personalizzato, ma puoi anche semplicemente disattivare la visualizzazione degli errori php poiché solitamente vengono registrati in un file di registro (dipende dalla configurazione php).

a seconda del framework (se presente) che stai utilizzando, ti suggerisco di eseguire una query per verificare tu stesso il nome del lavoro e creare le informazioni corrette per l'utente con il resto delle convalide per il modulo.

A seconda del numero di nomi di lavoro, potresti inviare i nomi alla vista che contiene il modulo e utilizzare javascript per indicare quale viene utilizzato.

Se questo non ha senso per te, allora per riassumere il mio punto di vista è questo:non progettare il tuo programma e/o utente per provare a fare cose illegali e individuare gli errori quando lo fanno e gestirli in seguito.È molto meglio, secondo me, progettare il proprio sistema in modo da non creare errori.Mantieni gli errori nei bug reali :)

Aggiornato per rimuovere elementi relativi alle funzioni errno che ora mi rendo conto non si applicano alla tua situazione...

C'è una cosa a cui prestare attenzione in MySQL UPDATE dichiarazioni: mysqli_affected_rows() restituirà zero anche se il WHERE la clausola corrispondeva alle righe, ma la clausola SET la clausola non ha effettivamente modificato i valori dei dati.Ne parlo solo perché quel comportamento ha causato un bug in un sistema che ho esaminato una volta: il programmatore ha utilizzato quel valore restituito per verificare la presenza di errori dopo un aggiornamento, presupponendo che uno zero significasse che si era verificato qualche errore.Significava semplicemente che l'utente non ha modificato alcun valore esistente prima di fare clic sul pulsante di aggiornamento.

Quindi immagino di usare mysqli_affected_rows() non si può fare affidamento nemmeno per trovare tali avvisi, a meno che tu non abbia qualcosa come un update_time colonna nella tabella a cui verrà sempre assegnato un nuovo valore timestamp una volta aggiornata.Questo tipo di soluzione alternativa sembra però un po' goffa.

È possibile rilevare violazioni di chiavi univoche utilizzando l'errore n. dell'istruzione mysqli.L'istruzione mysqli restituisce l'errore 1062, ovvero ER_DUP_ENTRY.È possibile cercare l'errore 1062 e stampare un messaggio di errore adatto.Se vuoi stampare la tua colonna (jobName) anche come parte del tuo messaggio di errore, allora dovresti analizzare la stringa di errore dell'istruzione.

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

È possibile ricevere gli avvisi e in modo più efficiente con mysqli che con mysql.

Ecco il codice suggerito sul manuale pagina su php.net per la proprietà 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();
    }
}

Nota sulla soppressione degli avvisi:In genere, non è una buona idea impedire la visualizzazione degli avvisi poiché potresti perdere qualcosa di importante.Se per qualche motivo devi assolutamente nascondere gli avvisi, puoi farlo su base individuale inserendo un file @ firmare davanti alla dichiarazione.In questo modo non è necessario disattivare tutti i report sugli avvisi e limitarli a un'istanza specifica.

Esempio:

 // this suppresses warnings that might result if there is no field titled "field" in the result
 $field_value = @mysql_result($result, 0, "field");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top