web-dev-qa-db-fra.com

Erreur - débordement SqlDateTime. Doit être entre 1/1/1753 00:00:00 et 12/31/9999 11:59:59 PM

J'ai utilisé ce morceau de code que j'ai écrit et cela fonctionne de la manière la moins claire possible. Je souhaite insérer une ligne dans la base de données qui comprend deux colonnes de DateTime:

myrow.ApprovalDate = DateTime.Now
myrow.ProposedDate = DateTime.Now

Et pourtant, quand je mets à jour la base de données, je reçois cette erreur:

SqlDateTime débordement. Doit être entre 1/1/1753 00:00:00 et 12/31/9999 23:59:59 PM. 

J'ai même essayé de copier une valeur insérée dans la base de données et de la coder en dur dans l'objet en cours de mise à jour:

// I copied this value from the DB
myrow.ApprovalDate =  Convert.ToDateTime("2008-12-24 00:00:00.000");

Toujours la même erreur, la partie étrange est que l'astuce ci-dessus a fonctionné pour la première insertion dans la base de données mais a échoué à partir de là. Avez-vous une idée de ce qui passe?

63
vondiplo

DateTime en C # est un type valeur, pas un type référence, et ne peut donc pas être null. Il peut toutefois s'agir de la constante DateTime.MinValue qui est en dehors de la plage du type de données Sql Servers DATETIME

Il est garanti que les types de valeur ont toujours une valeur (par défaut) (égale à zéro) sans avoir toujours besoin d'être explicitement définie (dans ce cas, DateTime.MinValue).

La conclusion est que vous avez probablement une valeur DateTime non définie que vous essayez de transmettre à la base de données.

DateTime.MinValue = 1/1/0001 12:00:00 AM
DateTime.MaxValue = 23:59:59.9999999, December 31, 9999, 
                    exactly one 100-nanosecond tick 
                    before 00:00:00, January 1, 10000

MSDN: DateTime.MinValue


Concernant Sql Server

date/heure
Données de date et heure du 1er janvier 1753 au 31 décembre 9999, avec une précision d'un trois centième de seconde (équivalent à 3,33 millisecondes ou 0,00333 seconde). Les valeurs sont arrondies à des incréments de .000, .003 ou .007 secondes.

petit temps
Données de date et heure du 1er janvier 1900 au 6 juin 2079, avec la précision à la minute près. Les valeurs smalldatetime de 29,998 secondes ou moins sont arrondies à la minute la plus proche; les valeurs avec 29,999 secondes ou plus sont arrondies à la minute la plus proche.

MSDN: Sql Server DateTime et SmallDateTime


Enfin, si vous passez une chaîne C # DateTime sous forme de chaîne à SQL, vous devez le formater comme suit pour conserver une précision maximale et empêcher le serveur SQL de générer une erreur similaire.

string sqlTimeAsString = myDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff");

Mise à jour (8 ans plus tard)

Envisagez d'utiliser le type de données sql DateTime2 qui s'aligne mieux sur la variable .net DateTime avec la plage de dates 0001-01-01 through 9999-12-31 et la plage temporelle 00:00:00 through 23:59:59.9999999

string dateTime2String = myDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffffff");

MSDN datetime2 (Transact-SQL)

72
Robert Paulson

Je trouve que l'utilisation de ce qui suit fonctionne assez bien pour les dates SQL min/max après de nombreuses erreurs liées à la base de données:

DateTime rngMin = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue;

DateTime rngMax = (DateTime)System.Data.SqlTypes.SqlDateTime.MaxValue;
62
Chrismean

Le code que vous avez pour les deux colonnes est correct. Recherchez toutes les autres colonnes datetime sur cette classe de mappage. Activez également la journalisation sur le datacontext pour afficher la requête et les paramètres.

dc.Log = Console.Out;

DateTime est initialisé sur le numéro 0 de c #, qui est 0001-01-01. Ceci est transmis par linqtosql à la base de données via la chaîne littérale sql: '0001-01-01'. SQL ne peut pas analyser une date/heure T-Sql à partir de cette date.

Il y a plusieurs façons de gérer cela:

  • Assurez-vous d’initialiser toutes les heures de la date avec une valeur que SQL peut gérer (telle que 0: 1900-01-01)
  • Assurez-vous que les dates qui peuvent parfois être omises sont nullable dat heures
9
Amy B

Faites attention lorsque vous comparez un .Net DateTime à SqlDateTime.MinValue ou MaxValue. Par exemple, ce qui suit lève une exception:

DateTime dte = new DateTime(1000, 1, 1);
if (dte >= SqlDateTime.MinValue)
    //do something

La raison en est que MinValue renvoie un SqlDateTime, pas un DateTime. Donc .Net essaie de convertir dte en SqlDateTime à des fins de comparaison et, comme il se situe en dehors de la plage acceptable SqlDateTime, il lève l’exception.

Une solution consiste à comparer votre DateTime à SqlDateTime.MinValue. Value .

9
Phil Haselden

Cette erreur se produit si vous essayez de définir une variable de type DateTime sur null. Déclarez la variable comme nullable, c'est-à-direDateTime?. Cela résoudra le problème.

5
Altaf Patel

Parfois, afin d'écrire moins de code, il est utilisé pour que SQL Server définisse des champs tels que la date, l'heure et l'ID lors de l'insertion en définissant la valeur par défaut pour les champs sur GETDATE() ou NEWID().

Dans ce cas, Valeur générée automatiquement la propriété de ces champs dans les classes d'entité doit être définie sur true.

De cette façon, vous n'avez pas besoin de définir des valeurs dans le code (éviter la consommation d'énergie !!!) et de ne jamais voir cette exception.

3
Haghpanah

Cela signifie généralement qu'un null est publié dans la requête au lieu de la valeur souhaitée. Vous pouvez essayer d'exécuter le Générateur de profils SQL pour voir exactement ce qui est transmis à linq par SQL Server.

1
Turnkey

Si vous utilisez NHibernate, vérifiez que les propriétés DateTime appropriées qui sont nullable sont définies sur nullable dans les mappages.

0
arash

Ce type d'erreur survient généralement lorsque vous effectuez une conversion ou une analyse de DateTime. Vérifiez les paramètres de calendrier du serveur sur lequel l'application est hébergée, principalement le fuseau horaire et le format de date abrégé, et assurez-vous qu'il est défini sur le bon fuseau horaire pour l'emplacement. J'espère que cela résoudra le problème.

0
Sushil Kumar Naik

Utiliser la méthode d'extension 

 public static object ToSafeDbDateDBnull(this object objectstring)
    {
        try
        {
            if ((DateTime)objectstring >= SqlDateTime.MinValue)
            {
                return objectstring;
            }
            else
            {
                return DBNull.Value;
            }
        }
        catch (Exception)
        {

            return DBNull.Value;
        }

    }

DateTime objdte = new DateTime(1000, 1, 1);
dte.ToSafeDbDateDBnull();
0
MSTdev

Je vois la même chose. L'erreur ne se produit pas lors de l'insertion d'une ligne, mais lors d'une mise à jour. la table que je référence a deux colonnes DateTime dont aucune n'est nullable. 

J'ai obtenu le scénario pour obtenir la ligne et l'enregistrer immédiatement (aucune modification de données). L'obtention fonctionne bien mais la mise à jour échoue.

Nous utilisons NHibernate 3.3.1.4000

0
Tevya