Pourquoi le format de string de date ISO 8601 'yyyy-mm-dd' fonctionne même lorsque le paramètre dateformat pour la connection de l'user est défini sur 'mdy'

J'ai couru ci-dessous la requête:

dbcc useroptions 

Cela indique que mon paramètre de mdy est mdy .

Ensuite, je cours en dessous de requête dans SQL Server Management Studio (SSMS) qui s'exécute avec succès:

 declare @mydate as datetime set @mydate = '07-29-2017' -- 'mdy' formatted date ssortingng corresponding to 29 August, 2017 select @mydate 

Maintenant, j'ai couru ci-dessous la requête:

 declare @mydate as datetime set @mydate = '29-07-2017' --here the format is dmy so SQL Server fails to parse it select @mydate 

La requête ci-dessus entraîne l'erreur ci-dessous:

Msg 242, niveau 16, état 3, ligne 5 La conversion d'un type de données varchar en un type de données datetime a entraîné une valeur hors de scope.

L'erreur est assez acceptable pour moi car il y a une discordance dans le format de la date. Mais, lorsque je cours en dessous de la requête, il réussit:

 declare @mydate as datetime set @mydate = '2017-07-29' -- this ymd format is also conflicting with mdy setting but it succeeds select @mydate 

Donc, je veux comprendre que la capacité de SQL Server à parsingr n'importe quelle date de string dépend de ce paramètre de useroptions de useroptions dans useroptions du tout ou pas? Si oui, pourquoi le format de date ISO 8601 yyyy-MM-dd date est-il analysé avec succès? Si non, alors quel est le paramètre moteur / raison de cette parsing réussie?

Cela fonctionnera toujours dans SQL Server:

 set @mydate = '20170729' 

indépendamment des parameters d'internationalisation (comme expliqué ici ). Cela ne répond pas exactement à votre question, mais cela indique que le dateformat n'est pas exhaustif.

Je suspecte que la version avec des traits d'union est acceptée avec dehors de l'altruisme (SQL Server identifie l'année étant le premier) ou parce qu'il est très semblable au format d'ODBC.

J'ai finalement obtenu la citation ici qui clarifie l'air sur mon problème.

En général, le format de date et d'heure pour les strings littérales est en effet contrôlé par le format de la date et les parameters de langue de la connection de l'user pour la session SQL:

Les formats littéraux de string affectent la présentation des données dans les applications aux users, mais pas le format de stockage sous-jacent des entiers dans SQL Server. Toutefois, SQL Server peut interpréter une valeur de date dans un format littéral de string, input par une application ou un user pour le stockage ou à une fonction de date, comme des dates différentes. L'interprétation dépend de la combinaison du format littéral de string, du type de données et des parameters d'option de langue par défaut SET DATEFORMAT, SET LANGUAGE et langue par défaut.

Mais ISO 8601 est indépendant du paramètre de langue par défaut de l'user:

Certains formats littéraux de string ne sont pas affectés par ces parameters. Envisagez d'utiliser un format qui ne dépend pas de ces parameters, sauf si vous savez que les parameters sont corrects pour le format. Le format ISO 8601 ne dépend pas de ces parameters et est une norme internationale. Transact-SQL qui utilise des formats littéraux de string, en fonction des parameters du système, est less portable.

Il existe un autre cas particulier de littéraux de string de date qui est indépendant du paramètre dateformat de la session SQL pour la connection user – ssortingng literals without delimiters . Ces dates n'appartiennent à aucun format local ou international mais sont toujours supposées être au format ymd . Citant de ce lien:

Vous pouvez spécifier datatables de date en tant que string non séparée. Les données de date peuvent être spécifiées en utilisant quatre, six ou huit numbers, une string vide ou une valeur d'heure sans valeur de date. Le paramètre de session SET DATEFORMAT ne s'applique pas aux inputs de date entièrement numériques, telles que les inputs numériques sans séparateurs. Les strings à six numbers ou à huit numbers sont toujours interprétées comme ymd. Le mois et le jour doivent toujours comporter deux numbers.