Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment SQL Server décide-t-il du format pour la conversion datetime implicite ?

Cela peut dépendre de divers facteurs - les paramètres régionaux du système d'exploitation, la langue de l'utilisateur actuel et les paramètres de format de date. Par défaut, Windows utilise l'US English , et les paramètres de l'utilisateur sont US English et MDY .

Mais voici quelques exemples pour montrer comment cela peut changer.

L'utilisateur utilise les paramètres de langue britannique :

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

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

(Erreur)

L'utilisateur utilise Français :

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

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

(Erreur)

L'utilisateur utilise à nouveau 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

(Erreur)

L'utilisateur utilise DMY au lieu de 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

(Erreur)

Votre meilleur pari, toujours, est d'utiliser des formats de date standard ISO, non régionaux, sûrs et sans ambiguïté. Les deux que je recommande généralement sont :

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

Aucun de ceux-ci n'échoue :

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

Par conséquent, je recommande fortement qu'au lieu de laisser les utilisateurs saisir des formats de date en texte libre (ou que vous utilisiez vous-même des formats non fiables), contrôlez vos chaînes d'entrée et assurez-vous qu'elles respectent l'un de ces formats sûrs. Ensuite, peu importe les paramètres de l'utilisateur ou les paramètres régionaux sous-jacents, vos dates seront toujours interprétées comme les dates auxquelles elles étaient censées être. Si vous autorisez actuellement les utilisateurs à saisir des dates dans un champ de texte sur un formulaire, arrêtez de le faire et implémentez un contrôle de calendrier ou au moins une liste de sélection afin de pouvoir contrôler le format de chaîne qui est renvoyé à SQL Server.

Pour plus d'informations, veuillez lire "The ultimate guide to the datetime-datatypes" de Tibor Karaszi types de données" et mon message "Mauvais Habitudes à éliminer : Mauvaise gestion des requêtes de date/plage."