Conversion non déterministe de chaînes de date littérale en valeurs DATE
S’applique à : SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW)
Soyez prudent quand vous autorisez la conversion de vos chaînes de type CHARACTER en types de données DATE. La raison en est que ces conversions sont souvent non déterministes.
Vous contrôlez ces conversions non déterministes en prenant en considération les paramètres SET LANGUAGE et SET DATEFORMAT.
Exemple pour SET LANGUAGE : nom du mois en polonais
SET LANGUAGE Polish;
Une chaîne de caractères peut être le nom d’un mois. Mais quel est le nom en anglais , en polonais, en croate ou dans une autre langue ? Et la session de l’utilisateur sera-t-elle définie pour la langue (LANGUAGE) correspondante appropriée ?
Par exemple, considérez le mot listopad, qui est le nom d’un mois. Le mois qu’il désigne dépend de la langue que le système SQL estime être utilisée :
- Si c’est du polonais, listopad est traduit en mois 11 (November en anglais).
- Si c’est du croate, listopad est traduit en mois 10 (October en anglais).
Exemple de code de 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
***/
Exemple SET DATEFORMAT
SET DATEFORMAT dmy;
Le format dmy (jma) précédent indique qu’un exemple de chaîne de date « 01-03-2018 » serait interprétée comme signifiant le premier jour du mois de mars de l’année 2018.
Si au lieu de cela, le format mdy a été spécifié, la même chaîne « 01-03-2018 » signifierait le troisième jour du mois de janvier 2018.
Si le format ymd est spécifié, aucun résultat n’est garanti. La valeur numérique « 2018 » est trop grande pour être un jour.
Pays/régions spécifiques
Au Japon et en Chine, le format DATEFORMAT ymd (amj) est utilisé. Les parties du format sont dans un ordre significatif, qui va de la plus grande unité à la plus petite. Ce format effectue donc un tri correct. Ce format est considéré comme étant le format international. Il est international, car les quatre chiffres de l’année sont univoques et aucun pays ni région n’utilise le format archaïque ydm (ajm).
Dans d’autres pays/régions, comme l’Allemagne et la France, le format DATEFORMAT est dmy (jma), c’est-à-dire « jj-mm-aaaa ». Le format dmy (jma) ne permet pas d’effectuer un tri correct, mais c’est une séquence significative allant de la plus petite unité à la plus grande.
Les États-Unis et les États fédérés de Micronésie sont les seuls pays/régions utilisant le format mdy (mja), qui n’effectue aucun tri. La séquence mixte du format correspond à un modèle de discours parlé dans les dates énoncées verbalement.
Exemple de code de SET DATEFORMAT : mdy (mja) et dmy (jma)
L’exemple de code Transact-SQL suivant utilise la même chaîne de caractères de date avec trois valeurs différentes pour DATEFORMAT. Une exécution du code produit la sortie présentée dans le commentaire :
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
***/
Dans l’exemple de code précédent, le dernier exemple montre une non-correspondance entre le format ymd (amj) et la chaîne d’entrée. Le troisième nœud de la chaîne d’entrée représente une valeur numérique qui est trop grande pour être un jour. Microsoft ne garantit pas la valeur de la sortie dans le cas de ces incompatibilités.
CONVERT offre des codes explicites pour le contrôle déterministe des formats de date
Notre article documentant CAST et CONVERT liste les codes explicites que vous pouvez utiliser avec la fonction CONVERT pour contrôler de façon déterministe les conversions de date. L’article concerné a chaque mois un nombre de visualisations de page parmi les plus élevés.
- CAST et CONVERT (Transact-SQL) : styles de date et d’heure
- CAST et CONVERT (Transact-SQL) : certaines conversions de date/heure sont non déterministes
Niveau de compatibilité 90 et supérieur
Dans SQL Server 2000, le niveau de compatibilité était de 80. Pour les paramètres de niveau 80 ou inférieurs, les conversions de date implicites étaient déterministes.
À compter de SQL Server 2005 et de son niveau de compatibilité de 90, les conversions de date implicites sont devenues non déterministes. Les conversions de dates sont devenues dépendantes de SET LANGUAGE et SET DATEFORMAT, à partir du niveau 90.
Unicode
La conversion de données caractères non-Unicode entre les classements est également considérée comme non déterministe.