Laquelle:
est le moyen recommandé de stocker la date et l'heure dans SQL Server 2008+?
Je suis conscient des différences de précision (et de l'espace de stockage probablement), mais en les ignorant pour le moment, existe-t-il un document de bonnes pratiques sur le moment d'utiliser quoi, ou peut-être que nous devrions simplement utiliser datetime2
uniquement?
DateTime2
type (ou de tout autre serveur SQL Server Tapez d'ailleurs) Voir les inconvénients dans ma réponse du 7/10/17 ci-dessous pour savoir pourquoi je demandeDATETIME2
a une plage de dates de "0001/01/01" à "DATETIME
9999/12/31 " alors que le type ne prend en charge que l'année 1753-9999.En outre, si vous en avez besoin, vous
DATETIME2
pouvez être plus précis en termes de temps; DATETIME est limité à 3 1/3 millisecondes, tout enDATETIME2
pouvant être précis jusqu'à 100 ns.Les deux types sont mappés
System.DateTime
en .NET - aucune différence là-bas.Si vous avez le choix, je vous recommande d'utiliser
DATETIME2
autant que possible. Je ne vois aucun avantage à utiliserDATETIME
(sauf pour la compatibilité descendante) - vous aurez moins de problèmes (avec des dates hors limites et des tracas comme ça).De plus: si vous n'avez besoin que de la date (sans partie horaire), utilisez DATE - c'est aussi bon
DATETIME2
et économisez de l'espace aussi! :-) Il en va de même pour le temps seulement - utilisezTIME
. C'est pour ça que ces types sont là!la source
Nullable<DateTime>
sert?datetime2 gagne dans la plupart des aspects sauf (compatibilité des anciennes applications)
veuillez noter les points suivants
source d'image: Kit de formation auto-rythmé des SCTM (examen 70-432): Microsoft® SQL Server® 2008 - Implémentation et maintenance Chapitre 3: Tableaux -> Leçon 1: Création de tableaux -> page 66
la source
datetime2
c'est génial (Gagnant)datetime2
utilise-t-il moins d'espace de stockagedatetime
et offre-t-il une gamme plus large et une précision supérieure?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 précision plus élevée et utilise un stockage égal ou inférieur (selon la précision).
Une chose la discussion a manqué, mais ...
@Marc_s déclare:
Both types map to System.DateTime in .NET - no difference there
. C'est correct, cependant, l'inverse n'est pas vrai ... et il est important lors de la recherche de plages de dates (par exemple, "trouvez-moi tous les enregistrements modifiés le 5/5/2010").La version de .NET
Datetime
a une portée et une précision similaires àDateTime2
. Lors du mappage d'un .netDatetime
vers l'ancien SQL,DateTime
un arrondi implicite se produit . L'ancien SQLDateTime
est précis à 3 millisecondes. Cela signifie que11:59:59.997
c'est aussi proche que possible de la fin de la journée. Tout ce qui est supérieur est arrondi au lendemain.Essaye ça :
Éviter cet arrondi implicite est une raison importante pour passer à DateTime2. L'arrondi implicite des dates crée clairement de la confusion:
la source
20100505
à5/5/2010
? L'ancien format fonctionnera avec n'importe quelle région dans SQL Server. Ce dernier se cassera:SET LANGUAGE French; SELECT Convert(datetime, '1/7/2015')
oups:2015-07-01 00:00:00.000
Presque toutes les réponses et commentaires ont pesé sur les avantages et la lumière sur les inconvénients. Voici un récapitulatif de tous les avantages et inconvénients jusqu'à présent, ainsi que certains inconvénients cruciaux (au n ° 2 ci-dessous) que je n'ai vu mentionnés qu'une seule fois ou pas du tout.
1.1. Plus conforme ISO (ISO 8601) (même si je ne sais pas comment cela entre en jeu dans la pratique).
1.2. Plus de gamme (1/1/0001 au 31/12/9999 vs 1/1 / 1753-12 / 31/9999) (bien que la gamme supplémentaire, toutes antérieures à l'année 1753, ne sera probablement pas utilisée sauf pour ex., dans les applications historiques, astronomiques, géologiques, etc.).
1.3. Correspond exactement à la plage de la plage de type .NET
DateTime
(bien que les deux convertissent dans les deux sens sans codage spécial si les valeurs sont dans la plage et la précision du type cible, sauf pour Con # 2.1 ci-dessous, sinon une erreur / arrondi se produira).1.4. Plus de précision (100 nanosecondes aka 0,000,000,1 sec. Contre 3,33 millisecondes aka 0,003,33 sec.) (Bien que la précision supplémentaire ne sera probablement pas utilisée sauf par ex. Dans les applications d'ingénierie / scientifiques).
1.5. Lorsqu'il est configuré pour une précision similaire (comme en 1 millisec pas "identique" (comme en 3,33 millisec) comme Iman Abidi)
DateTime
, utilise moins d'espace (7 contre 8 octets), mais bien sûr, vous perdriez le avantage de précision qui est probablement l'un des deux (l'autre étant la gamme) les plus vantés bien que probablement des avantages inutiles).2.1. Lors de la transmission d'un paramètre à un .NET
SqlCommand
, vous devez spécifierSystem.Data.SqlDbType.DateTime2
si vous pouvez transmettre une valeur en dehors de laDateTime
plage et / ou de la précision de SQL Server , car elle est par défautSystem.Data.SqlDbType.DateTime
.2.2. Ne peut pas être implicitement / facilement converti en une valeur numérique à virgule flottante (nombre de jours depuis la date-heure min) pour effectuer les opérations suivantes avec / dans les expressions SQL Server à l'aide de valeurs et d'opérateurs numériques:
2.2.1. ajouter ou soustraire # de jours ou jours partiels. Remarque: L'utilisation de
DateAdd
Function comme solution de contournement n'est pas anodine lorsque vous devez prendre en compte plusieurs, sinon toutes les parties de la date-heure.2.2.2. prendre la différence entre deux dates-heures aux fins du calcul de «l'âge». Remarque: Vous ne pouvez pas simplement utiliser la
DateDiff
fonction de SQL Server à la place, car elle ne calcule pasage
comme la plupart des gens s'attendent à ce que si les deux dates-heures arrivent à traverser une limite calendrier / horloge date-heure des unités spécifiées, même pour une petite fraction de cette unité, il retournera la différence que 1 de cette unité par rapport à 0. Par exemple, leDateDiff
dansDay
« s de deux fois ce jour seulement 1 milliseconde en dehors retournera 1 vs 0 (jours) si ces dates-heures sont sur différents jours civils (c.-à-d. «1999-12-31 23: 59: 59.9999999» et «2000-01-01 00: 00: 00.0000000»). Les mêmes dates-heures de différence de 1 milliseconde si elles sont déplacées afin qu'elles ne traversent pas un jour calendaire, renverront un «DateDiff» enDay
's de 0 (jours).2.2.3. prendre la
Avg
date-heure (dans une requête agrégée) en convertissant simplement en «Float» d'abord, puis de nouveau enDateTime
.REMARQUE: pour convertir
DateTime2
en numérique, vous devez faire quelque chose comme la formule suivante qui suppose toujours que vos valeurs ne sont pas inférieures à l'année 1970 (ce qui signifie que vous perdez toute la plage supplémentaire plus 217 années supplémentaires. Remarque: vous pouvez ne pas être en mesure d'ajuster simplement la formule pour permettre une plage supplémentaire car vous pouvez rencontrer des problèmes de débordement numérique.25567 + (DATEDIFF(SECOND, {d '1970-01-01'}, @Time) + DATEPART(nanosecond, @Time) / 1.0E + 9) / 86400.0
- Source: " https://siderite.dev/blog/how-to-translate-t-sql-datetime2-to.html "Bien sûr, vous pourriez aussi
Cast
à laDateTime
première (et si nécessaire de retour à nouveauDateTime2
), mais vous perdriez la précision et la portée (tous avant 1753) les prestations deDateTime2
rapportDateTime
qui sont prolly les 2 plus grands et aussi en même temps prolly les 2 moins probablement nécessaires, ce qui soulève la question de savoir pourquoi l'utiliser lorsque vous perdez les conversions implicites / faciles en virgule flottante numérique (# de jours) pour l'addition / la soustraction / l '"âge" (vs.DateDiff
) / leAvg
bénéfice de calcul qui est un grand dans mon expérience.En fait, la
Avg
date-heure est (ou du moins devrait être) un cas d'utilisation important. a) Outre l'utilisation pour obtenir la durée moyenne lorsque des dates-heures (car une date-heure de base commune) sont utilisées pour représenter la durée (une pratique courante), b) il est également utile d'obtenir une statistique de type tableau de bord sur ce que la date moyenne- l'heure est dans la colonne date-heure d'une plage / d'un groupe de lignes. c) Une requête ad-hoc standard (ou du moins devrait être standard) pour surveiller / dépanner les valeurs dans une colonne qui peuvent ne plus être valides jamais / plus et / ou qui doivent être dépréciées consiste à répertorier pour chaque valeur le nombre d'occurrences et ( le cas échéant) lesMin
,Avg
etMax
horodatés associés à cette valeur.la source
DateTime
) les plus probables , sont tous liés aux effets sur les requêtes et les instructions SQL Server.DateTime2
j'ai déjà mentionné (en raison du risque élevé de débordement)). Ré. "ne fonctionne pas pour la plupart des types de date": vous n'en avez besoin que pour travailler avec un seul, et la plupart des dates dans la plupart des applications n'auront probablement jamais besoin d'être converties en un autre type de date pour toute leur durée de vie (sauf peut-être, comme je l'ai également mentionné ,DateTime2
àDateTime
(par exemple, pour faire de l '"arithmétique sur les dates"; P). Étant donné que cela ne vaut pas tout le codage supplémentaire dans les requêtes de recherche non seulement programmées mais aussi ad hoc pour utiliser un type de date non arithmétique.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 Access -> SQL 2008 R2 et il a mis tous les champs datetime en DateTime2. Ajout d'un enregistrement avec Now () comme valeur bombardée. C'était correct le 1/1/2012 14:53:04, mais pas le 1/10/2012 14:53:04.
Une fois que le personnage a fait la différence. J'espère que ça aide quelqu'un.
la source
Voici un exemple qui vous montrera les différences de taille de stockage (octets) et de précision entre smalldatetime, datetime, datetime2 (0) et datetime2 (7):
qui revient
Donc, si je veux stocker des informations à la seconde - mais pas à la milliseconde - je peux enregistrer 2 octets chacun si j'utilise datetime2 (0) au lieu de datetime ou datetime2 (7).
la source
bien qu'il y ait une précision accrue avec datetime2 , certains clients ne prennent pas en charge la date , l' heure ou datetime2 et vous obligent à convertir en un littéral de chaîne. Plus précisément, Microsoft mentionne les problèmes ODBC, OLE DB, JDBC et SqlClient de «bas niveau» avec ces types de données et dispose d'un graphique montrant comment chacun peut mapper le type.
Si la valeur de compatibilité sur la précision, utilisez datetime
la source
Vieille question ... Mais je veux ajouter quelque chose que personne n'a déjà déclaré ici ... (Remarque: c'est ma propre observation, alors ne demandez aucune référence)
Datetime2 est plus rapide lorsqu'il est utilisé dans les critères de filtre.
TLDR:
Dans SQL 2016, j'avais une table avec cent mille lignes et une colonne datetime ENTRY_TIME car elle était nécessaire pour stocker l'heure exacte jusqu'à quelques secondes. Lors de l'exécution d'une requête complexe avec de nombreuses jointures et une sous-requête, lorsque j'utilisais la clause where comme:
La requête était correcte au départ lorsqu'il y avait des centaines de lignes, mais lorsque le nombre de lignes augmentait, la requête commençait à donner cette erreur:
J'ai supprimé la clause where et, de manière inattendue, la requête a été exécutée en 1 seconde, bien que TOUTES les lignes de toutes les dates aient été récupérées. J'exécute la requête interne avec la clause where, et cela a pris 85 secondes, et sans la clause where, cela a pris 0,01 seconde.
Je suis tombé sur de nombreux threads ici pour ce problème en tant que performances de filtrage datetime
J'ai optimisé un peu la requête. Mais la vitesse réelle que j'ai obtenue a été de changer la colonne datetime en datetime2.
Maintenant, la même requête qui a expiré auparavant prend moins d'une seconde.
à votre santé
la source
L'interprétation des chaînes de date dans
datetime
etdatetime2
peut également être différente lors de l'utilisation deDATEFORMAT
paramètres non américains . Par exempleCela renvoie
2013-05-06
(c'est-à-dire le 6 mai) pourdatetime
et2013-06-05
(c'est-à-dire le 5 juin) pourdatetime2
. Cependant, avecdateformat
set tomdy
, both@d
et@d2
return2013-06-05
.Le
datetime
comportement semble en contradiction avec la documentation MSDN deSET DATEFORMAT
qui stipule: Certaines chaînes de caractères formats, par exemple ISO 8601, sont interprétées indépendamment du réglage DATEFORMAT . Evidemment pas vrai!Jusqu'à ce que je sois mordu par cela, j'avais toujours pensé que les
yyyy-mm-dd
dates seraient juste gérées correctement, quels que soient les paramètres de langue / paramètres régionaux.la source
SET LANGUAGE FRENCH; DECLARE @d DATETIME = '20130605'; SELECT @d;
Réessayez avec les tirets.Selon cet article , si vous souhaitez avoir la même précision que DateTime en utilisant DateTime2, vous devez simplement utiliser DateTime2 (3). Cela devrait vous donner la même précision, prendre un octet de moins et fournir une plage étendue.
la source
Je suis juste tombé sur un autre avantage pour
DATETIME2
: cela évite un bogue dans leadodbapi
module Python , qui explose si unedatetime
valeur de bibliothèque standard est passée qui a des microsecondes non nulles pour uneDATETIME
colonne mais fonctionne bien si la colonne est définie commeDATETIME2
.la source
Le SQL ci-dessus ne fonctionnera pas avec un champ DateTime2. Il renvoie et l'erreur "Type d'opérande en conflit: datetime2 est incompatible avec int"
Ajouter 1 pour obtenir le lendemain est quelque chose que les développeurs font avec les dates depuis des années. Maintenant, Microsoft a un nouveau champ datetime2 super qui ne peut pas gérer cette fonctionnalité simple.
"Utilisons ce nouveau type qui est pire que l'ancien", je ne pense pas!
la source
datetime
etdatetime2
ont été introduits dans SQL Server 2008. Vous obtenez égalementOperand type clash: date is incompatible with int
dudate
type qui existe depuis le jour.dateadd(dd, 1, ...)
Cependant, les trois types de données fonctionnent très bien.Je pense que
DATETIME2
c'est la meilleure façon de stocker ledate
, car il a plus d'efficacité que leDATETIME
. DansSQL Server 2008
vous pouvez utiliserDATETIME2
, il stocke une date et une heure, prend 6-8bytes
pour stocker et a une précision de100 nanoseconds
. Donc, toute personne qui a besoin d'une plus grande précision temporelle le voudraDATETIME2
.la source