2012-12-10 14 views
20

Sono stato molto sorpreso quando MySQL mi ha permesso di inserire un NULL in un campo che è stato creato con NOT NULL. Ho fatto alcune ricerche e ho scoperto come abilitare la modalità rigorosa. Tuttavia, io non sono abbastanza sicuro che cosa convalida MySQL fa quando STRICT_ALL_TABLES è abilitato.Che convalida fa MySQL fare quando modalità rigorosa è abilitata?

Il manuale dice:

modalità Strict controlla come MySQL gestisce i valori di ingresso non validi o mancanti. Un valore può essere valido per diversi motivi. (sottolineatura mia) Ad esempio, si potrebbe avere il tipo di dati sbagliato per la colonna, o potrebbe essere fuori portata.

Capisco quello che considera mancante e come lo gestisce. Sono poco chiaro quello che considera non valida . Ho fatto alcuni test e scoperto i seguenti:

  • stringhe troppo lunghe non sono validi
  • i numeri che sono fuori portata sono validi
  • NULL s per un NULL colonna non sono validi
  • TRUE e FALSE sembrano essere sempre valido (che diventano 1 e 0, rispettivamente) non sono validi sono validi
  • a zero date
  • date non valide (Addit modalità ionale possono essere abilitati per modificare questo comportamento)
  • galleggia in un campo intero sono validi (ottengono arrotondata)
  • lettere in un campo numerico non sono validi

Ha MySQL fare altri controlli di convalida diverse cosa è menzionato sopra?

Il manuale indica "tipo di dati errato per la colonna", ma l'unica situazione che vedo dove questo entra effettivamente in gioco è le lettere in un campo numerico. Ci sono altri esempi di errori nel tipo di dati?

Esiste una lista di ciò che esegue esattamente MySQL?

MODIFICA: Per la cronaca, la mia applicazione ha già un'ampia convalida. Sto usando la modalità rigorosa come controllo dell'ultima possibilità, in caso di necessità. Se mi dimentico di controllare qualcosa, lo voglio a fail fast anziché "silenziare silenziosamente i miei dati".

+0

Ho la sensazione che si vogliono che il DB faccia la convalida dei dati per te. Se è così, è un brutto percorso da percorrere. – siride

+3

@siride: il DBMS *** è lì per fare la convalida (chiavi esterne, chiavi primarie, vincoli di controllo, tipo di convalida). Il fatto che MySQL ti permetta di memorizzare "31 febbraio" è un bug secondo me. O per dirla in altro modo: è un pessimo percorso da percorrere se il DBMS non esegue alcuna convalida. –

+4

Ho già effettuato la convalida nell'applicazione. Non sto * usando * la modalità rigorosa come * sostituzione * per una buona programmazione, ma piuttosto come un modo per assicurarmi una buona programmazione. – toxalot

risposta

8

Una buona risorsa è controllare la sorgente MySQL e leggere mysql-test/t/strict.test per vedere tutti i casi per cui testano dopo aver impostato la modalità STRICT o TRADITIONAL (che è un superset di STRICT).

Hai fatto un'ottima ricerca e sperimentazione, ma ci sono un paio di casi, come ad esempio:

  • cercando di inserire un valore ENUM indefinito.
  • Tentativo di inserire un valore predefinito per una colonna NOT NULL senza DEFAULT definito.
  • Cercando di utilizzare CAST() per convertire le stringhe di numeri interi, ecc
  • Conversione di VARCHAR di MEDIUMTEXT o LONGTEXT se si dà una lunghezza superiore a 65536.
  • troncamento di stringhe commento per tabelle e colonne.
  • Conversione di stringa in tipo YEAR.
  • Definizione di una colonna SET o ENUM con voci duplicate.

Inoltre mysql-test/include/strict_autoinc.inc, perché i test per troppo pieno quando un valore auto-inc diventa troppo grande.

Esistono alcuni altri file di test che utilizzano la modalità STRISTA per test specifici, ma non li ho esaminati.

+0

Come/dove trovo il codice sorgente? – toxalot

+0

Un altro caso sta tentando di inserire un numero negativo in una colonna UNSIGNED. – toxalot

+0

http://dev.mysql.com/downloads/mysql/#downloads, selezionare "Codice sorgente" come piattaforma. –

3

Ho inserito il codice sorgente di MySQL 5.5.28 (Community Server Edition) per trovare istanze di STRICT_ALL_TABLES in uso.

Da quello che ho visto, sembra che la tua lista sia già abbastanza completa, ma qui di seguito ci sono alcune altre cose che ho imparato sull'uso di STRICT_ALL_TABLES. Il primo è un'altra convalida, mentre il resto riguarda tutti gli errori e gli avvertimenti.

  • Le colonne di geometria non possono avere un valore predefinito. (SQL/field.cc: 9394)
  • Se un commento tavolo è più lungo di 2048 caratteri, MySQL genera un errore invece di troncare il commento con un avvertimento. (sql/unireg.cc: 231)
  • Se un commento di campo supera i 1024 caratteri, MySQL genera un errore anziché troncare il commento con un avviso. (sql/unireg.cc: 739)
  • Su un inserto o un aggiornamento, se esiste un valore duplicato in un SET o ENUM MySQL produce un errore anziché un avvertimento. (sql/sql_table.cc: 2503)
  • Ci sono un sacco di operazioni che si interrompono in caso di avviso con STRICT_ALL_TABLES anziché procedere con un semplice avviso. Questi sono troppo numerosi per me da elencare, e l'impostazione della bandiera abort_on_warning è troppo lontana dal codice che crea gli avvisi per me per documentarli facilmente (o persino capirli) tutti. Ma se qualcuno vuole sporcarsi le mani nel codice sorgente, alcuni posti per iniziare sarebbe sql/sql_update.cc: 630 e sql/sql_insert.cc: 841
Problemi correlati