840 votes

<DateTime2> vs <DateTime> dans SQL Server

Lequel :

est la méthode recommandée pour stocker la date et l'heure dans SQL Server 2008+?

Je suis conscient des différences de précision (et probablement d'espace de stockage), mais en les ignorant pour le moment, existe-t-il un document de bonnes pratiques sur quand utiliser quoi, ou devrions-nous simplement utiliser datetime2 uniquement?

716voto

Adam Porad Points 4569

La documentation de MSDN pour datetime recommande d'utiliser datetime2. Voici leur recommandation:

Utilisez les types de données time, date, datetime2 et datetimeoffset pour les nouveaux travaux. Ces types sont conformes à la norme SQL. Ils sont plus portables. time, datetime2 et datetimeoffset offrent une plus grande précision des secondes. datetimeoffset fournit un support du fuseau horaire pour les applications déployées à l'échelle mondiale.

datetime2 a une plus grande plage de dates, une précision fractionnaire par défaut plus grande et une précision spécifiée par l'utilisateur en option. Selon la précision spécifiée par l'utilisateur, il peut également utiliser moins de stockage.

61 votes

While there is increased precision with datetime2, some clients doesn't support date, time, or datetime2 and force you to convert to a string literal. If you're concerned more about compatability than precision, use datetime

7 votes

Une autre option consiste à utiliser une vue indexée avec la colonne convertie en datetime pour la compatibilité. Vous devriez être en mesure de pointer l'application vers la vue, cependant.

12 votes

Le support du fuseau horaire avec DATETIMEOFFSET est un abus de langage. Il ne fait que stocker un décalage UTC pour un instant précis, pas un fuseau horaire.

551voto

marc_s Points 321990

DATETIME2 a une plage de dates de "0001 / 01 / 01" à "9999 / 12 / 31" tandis que le type DATETIME ne prend en charge que les années 1753-9999.

De plus, si nécessaire, DATETIME2 peut être plus précis en termes de temps; DATETIME est limité à 3 1/3 millisecondes, tandis que DATETIME2 peut être précis jusqu'à 100ns.

Les deux types sont mappés à System.DateTime en .NET - pas de différence de ce côté-là.

Si vous avez le choix, je recommanderais d'utiliser DATETIME2 autant que possible. Je ne vois aucun avantage à utiliser DATETIME (à part pour la compatibilité ascendante) - vous aurez moins de problèmes (avec des dates hors de portée et des tracas comme ça).

De plus : si vous avez seulement besoin de la date (sans heure), utilisez DATE - c'est aussi bien que DATETIME2 et vous permet d'économiser de l'espace, aussi! :-) Il en va de même pour l'heure seulement - utilisez TIME. C'est à cela que servent ces types!

0 votes

Je suis d'accord avec Marc. À moins que vous n'ayez besoin de rétrocompatibilité pour une raison quelconque, allez toujours avec DATETIME2. L'espace de stockage est bon marché et selon ce que j'ai vu dans ma propre expérience et lu ailleurs, il n'y a aucune différence en termes de surcharge de traitement entre les deux.

170 votes

Faites attention lorsque vous ajoutez une valeur .NET DateTime en tant que paramètre à un SqlCommand, car il a tendance à supposer qu'il s'agit de l'ancien type de données datetime, et vous obtiendrez une erreur si vous essayez d'écrire une valeur DateTime en dehors de la plage d'années 1753-9999 à moins que vous ne spécifiez explicitement le type en tant que System.Data.SqlDbType.DateTime2 pour le SqlParameter. Quoi qu'il en soit, datetime2 est génial, car il peut stocker n'importe quelle valeur pouvant être stockée dans le type .NET DateTime.

2 votes

@marc_s - Je ne comprends pas votre point concernant la préférence pour DATETIME2 lorsque tout est égal. Est-ce que la flexibilité de supporter l'année 1-1752 est vraiment un avantage pour la plupart des applications? Je n'ai jamais eu une application qui représentait une année antérieure à la fin des années 1800 et cela semble encourager des accidents comme la mauvaise codification de 2011 en tant que 11.

234voto

imanabidi Points 3203

datetime2 l'emporte dans la plupart des aspects, sauf la compatibilité avec les anciennes applications

  1. une plus grande gamme de valeurs
  2. une meilleure précision
  3. un espace de stockage plus petit (si une précision facultative spécifiée par l'utilisateur est précisée)

Comparaison des types de données date et heure SQL - datetime,datetime2,date,TIME

veuillez noter les points suivants

  • Syntaxe
    • datetime2[(précision des secondes fractionnaires => Voir la taille de stockage ci-dessous)]
  • Précision, échelle
    • 0 à 7 chiffres, avec une précision de 100 ns.
    • La précision par défaut est de 7 chiffres.
  • Taille de stockage
    • 6 bytes pour une précision inférieure à 3;
    • 7 bytes pour une précision de 3 et 4.
    • Toute autre précision nécessite 8 bytes.
  • DateTime2(3) ont le même nombre de chiffres que DateTime mais utilisent 7 bytes de stockage au lieu de 8 bytes (SQLHINTS- DateTime Vs DateTime2)
  • En savoir plus sur datetime2 (Article MSDN Transact-SQL)

source de l'image : Kit de formation autonome MCTS (Examen 70-432) : Microsoft® SQL Server® 2008 - Implémentation et maintenance Chapitre 3 : Tables -> Leçon 1 : Création de tables -> page 66

7 votes

Merci d'avoir montré que les statistiques +1 pour cela, datetime2 est génial (Gagnant)

2 votes

@Iman Abidi : Selon le commentaire d'Oskar Berggren daté du 10 septembre 2014 à 15h51 sur l'article "SQLHINTS- DateTime Vs DateTime2" que vous avez mentionné : "datetime2(3) n'est PAS la même chose que datetime. Ils auront le même nombre de chiffres, mais la précision de datetime est de 3,33ms, tandis que la précision de datetime2(3) est d'1ms".

1 votes

@PankajParkar: Woah, pas si vite. Vous voudrez peut-être regarder la section Cons de ma réponse datée du 10/07/17 ci-dessous.

113voto

EBarr Points 5824

Je suis d'accord avec @marc_s et @Adam_Poward -- DateTime2 est la méthode préférée pour aller de l'avant. Il a une plage de dates plus large, une plus grande précision, et utilise un stockage égal ou inférieur (selon la précision).

Une chose que la discussion a manquée, cependant...
@Marc_s affirme: Les deux types se mappent sur System.DateTime en .NET - pas de différence là. C'est correct, cependant l'inverse n'est pas vrai...et cela importe lors de recherches dans une plage de dates (par exemple, "trouvez-moi tous les enregistrements modifiés le 5/5/2010").

La version de .NET de Datetime a une plage et une précision similaires à DateTime2. Lors du mapping d'un Datetime .net vers l'ancien SQL DateTime, un arrondi implicite se produit. L'ancien SQL DateTime est précis à 3 millisecondes. Cela signifie que 11:59:59.997 est aussi proche que possible de la fin de la journée. Tout ce qui est plus élevé est arrondi au jour suivant.

Essayez ceci :

declare @d1 datetime   = '5/5/2010 23:59:59.999'
declare @d2 datetime2  = '5/5/2010 23:59:59.999'
declare @d3 datetime   = '5/5/2010 23:59:59.997'
select @d1 as 'JeSuisLe6MaiEnRaisonDeLArrondi', @d2 'Mai5', @d3 'ToujoursMai5Car2msPlusTôt'

Éviter cet arrondi implicite est une raison importante de passer à DateTime2. L'arrondi implicite des dates cause clairement de la confusion :

16 votes

Vous pouvez également éviter cet arrondi en ne cherchant pas à trouver la "fin" d'une journée de toute façon. >= 5 mai ET < 6 mai est bien plus sûr et fonctionnera sur n'importe quel type de date/heure (sauf TIME bien sûr). Je suggère également d'éviter les formats régionaux et ambigus comme jj/mm/aaaa.

2 votes

@AaronBertrand - entièrement d'accord, mais en regardant le nombre de questions que nous avons sur le sujet, il semblait utile de le décrire.

2 votes

Pourquoi avez-vous changé de 20100505 à 5/5/2010? Le format précédent fonctionnera avec n'importe quelle région dans SQL Server. Le second va poser problème: SET LANGUAGE French; SELECT Convert(datetime, '1/7/2015') oops: 2015-07-01 00:00:00.000

15voto

Rhett A Brown Points 61

DateTime2 fait des ravages si vous êtes un développeur Access essayant d'écrire Now() dans le champ en question. Je viens de faire une migration d'Access -> SQL 2008 R2 et tous les champs datetime ont été mis en DateTime2. Ajouter un enregistrement avec Now() comme valeur a échoué. C'était bon le 01/01/2012 14:53:04, mais pas le 10/01/2012 14:53:04.

Un caractère a fait la différence. J'espère que cela aidera quelqu'un.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X