Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

In che modo SQL Server decide il formato per la conversione data/ora implicita?

Ciò può dipendere da una varietà di fattori:le impostazioni internazionali del sistema operativo, la lingua dell'utente corrente e le impostazioni del formato della data. Per impostazione predefinita, Windows utilizza US English e le impostazioni dell'utente sono US English e MDY .

Ma ecco alcuni esempi per mostrare come questo può cambiare.

L'utente sta utilizzando le impostazioni della lingua BRITANNICA:

-- works:
SET LANGUAGE BRITISH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');

-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO

(Errore)

L'utente sta usando Français:

-- works:
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');

-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO

(Errore)

L'utente sta utilizzando di nuovo Français:

SET LANGUAGE FRENCH;

-- fails (proving that, contrary to popular belief, YYYY-MM-DD is not always safe):
SELECT CONVERT(DATETIME, '2012-04-30');
GO

(Errore)

L'utente utilizza DMY anziché MDY:

SET LANGUAGE ENGLISH;
SET DATEFORMAT DMY;

-- works:
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');

-- fails:
SELECT CONVERT(DATETIME, '04-30-2012');
GO

(Errore)

La soluzione migliore, sempre, è utilizzare formati di data standard ISO, non regionali, sicuri e non ambigui. I due che consiglio in genere sono:

YYYYMMDD                  - for date only.
YYYY-MM-DDTHH:MM:SS[.mmm] - for date + time, and yes that T is important.

Nessuno di questi fallisce:

SET DATEFORMAT MDY;
SET LANGUAGE ENGLISH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET LANGUAGE BRITISH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET DATEFORMAT DMY;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');

Pertanto, consiglio vivamente che invece di consentire agli utenti di digitare formati di data di testo liberi (o di utilizzare tu stesso formati inaffidabili), controllare le stringhe di input e assicurarsi che aderiscano a uno di questi formati sicuri. Quindi non importa quali impostazioni ha l'utente o quali sono le impostazioni regionali sottostanti, le tue date verranno sempre interpretate come le date che dovevano essere. Se al momento consenti agli utenti di inserire le date in un campo di testo in un modulo, smetti di farlo e implementa un controllo del calendario o almeno un elenco di selezione in modo da poter controllare in definitiva il formato della stringa che viene passato a SQL Server.

Per un po' di background, leggi "The ultimate guide to the datetime" di Tibor Karaszi tipi di dati" e il mio post "Bad Abitudini da eliminare:gestione errata delle query di date/intervallo."