Conversione non deterministica di stringhe di valori letterali data in valori DATE

Si applica a: SQL Server Azure SQL DatabaseIstanza gestita di SQL di AzureAzure Synapse Analytics AnalyticsPlatform System (PDW)

Quando si consente la conversione di stringhe di caratteri in tipi di dati DATE, è necessario prestare attenzione. Tali conversioni, infatti, sono spesso non deterministiche.

Per controllare le conversioni non deterministiche è necessario tenere conto delle impostazioni di SET LANGUAGE e SET DATEFORMAT.

Esempio di SET LANGUAGE: nome del mese in polacco

  • SET LANGUAGE Polish;

Una stringa di caratteri può contenere il nome di un mese. Ma questo nome è in croato, in inglese, in polacco o in un'altra lingua? E la sessione dell'utente sarà impostata nella lingua corretta?

Si consideri ad esempio la parola listopad, che corrisponde al nome di un mese. A quale mese corrisponda, però, dipende dalla lingua che il sistema SQL ritiene che sia usata:

  • In polacco, listopad corrisponde al mese 11 (novembre in italiano).
  • In croato, listopad corrisponde al mese 10 (ottobre in italiano).

Esempio di codice per SET LANGUAGE

--SELECT alias FROM sys.syslanguages ORDER BY alias;

DECLARE @yourInputDate  NVARCHAR(32) = '28 listopad 2018';

SET LANGUAGE Polish;
SELECT CONVERT(DATE, @yourInputDate) AS [SL_Polish];

SET LANGUAGE Croatian;
SELECT CONVERT(DATE, @yourInputDate) AS [SL_Croatian];

SET LANGUAGE English;


/***  Actual output:  For the two months, note the 11 versus the 10.
SL_Polish
2018-11-28

SL_Croatian
2018-10-28
***/

Esempio di SET DATEFORMAT

  • SET DATEFORMAT dmy;

Il formato dmy qui sopra indica che la stringa della data di esempio '01-03-2018' viene interpretata come il primo giorno del mese di marzo nell'anno 2018.

Se invece si specifica mdy, la stessa stringa '01-03-2018' significa il terzo giorno del mese di gennaio 2018.

E se ymd è stato specificato, non esiste alcuna garanzia di ciò che l'output sarebbe. Il valore numerico '2018' è troppo grande per corrispondere a un giorno.

Paesi/aree geografiche specifiche

In Cina e in Giappone, il formato DATEFORMAT usato è ymd. Le parti del formato sono in una sequenza ragionevole, dalla più grande alla più piccola. Quindi, questo formato viene ordinato bene. Questo formato viene considerato il formato internazionale. È internazionale perché le quattro cifre dell'anno non sono ambigue e nessun paese/regione sulla Terra usa il formato arcaico di ydm.

In altri paesi/aree geografiche, ad esempio Germania e Francia, DATEFORMAT è dmy, ovvero "dd-mm-aaaa". Il formato dmy non è corretto, ma è una sequenza ragionevole di unità più piccola a più grande.

I Stati Uniti, e gli Stati federati di Micronesia, sono gli unici paesi/aree geografiche che usano mdy, che non ordinano. La sequenza mista del formato corrisponde al modello di pronuncia colloquiale delle date.

Esempio di codice per SET DATEFORMAT: confronto tra mdy e dmy

L'esempio di codice Transact-SQL seguente usa la stessa stringa di caratteri della data con tre diverse impostazioni di DATEFORMAT. Se si esegue il codice, viene generato l'output illustrato nel commento:

DECLARE @yourDateString NVARCHAR(10) = '12-09-2018';
PRINT @yourDateString + '  = the input.';

SET DATEFORMAT dmy;
SELECT CONVERT(DATE, @yourDateString) AS [DMY-Interpretation-of-input-format];

SET DATEFORMAT mdy;
SELECT CONVERT(DATE, @yourDateString) AS [MDY-Interpretation-of-input-format];

SET DATEFORMAT ymd;
SELECT CONVERT(DATE, @yourDateString) AS [YMD-Interpretation--?--NotGuaranteed];


/***  Actual output:
12-09-2018  = the input.

DMY-Interpretation-of-input-format
2018-09-12

MDY-Interpretation-of-input-format
2018-12-09

YMD-Interpretation--?--NotGuaranteed
2018-12-09
***/

Nell'esempio di codice precedente, l'esempio finale presenta una mancata corrispondenza tra il formato ymd e la stringa di input. Il terzo nodo della stringa di input rappresenta un valore numerico troppo grande per corrispondere a un giorno. Microsoft non garantisce il valore di output da tali mancate corrispondenze.

CONVERT rende disponibili codici espliciti per il controllo deterministico dei formati di data

L'articolo della documentazione relativo a CAST e CONVERT elenca i codici espliciti che è possibile usare con la funzione CONVERT per controllare in modo deterministico le conversioni delle date. Ogni mese l'articolo presenta uno dei conteggi di visualizzazione della pagina più alti.

Livello di compatibilità 90 e superiore

In SQL Server 2000, il livello di compatibilità era pari a 80. Per le impostazioni di livello pari a 80 o inferiori, le conversioni di data implicite erano deterministiche.

A partire da SQL Server 2005, grazie al livello di compatibilità pari a 90, le conversioni di data implicite sono ora non deterministiche. A partire dal livello 90, le conversioni di data sono dipendenti da SET LANGUAGE e SET DATEFORMAT.

Unicode

Anche la conversione di dati di tipo carattere non Unicode tra regole di confronto viene considerata non deterministica.

Vedere anche