2010-12-06 5 views
3

Je le code suivant:Datetime a trop de décimales

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); 
// set properties on builder (omitted for brevity) 

using (SqlConnection connection = new SqlConnection(builder.ToString())) 
{ 
    connection.Open(); 
    using (SqlCommand command = connection.CreateCommand()) 
    { 
     command.CommandType = System.Data.CommandType.Text; 
     command.CommandText = "SELECT * FROM Employee WHERE WhenHire < @HireDate"; 
     SqlParameter hireDateParameter = new SqlParameter("@HireDate", DateTime.Now); 
     command.Parameters.Add(hireDateParameter); 
     using (SqlDataReader reader = command.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       // do stuff 
      } 
     } 
    } 
} 

qui apparaît dans Profiler SQL comme:

exec sp_executesql N'SELECT * FROM Employee WHERE WhenHire < @HireDate', 
        N'@HireDate datetime', 
        @HireDate='2010-12-06 11:43:23.573' 

Quelle est la précision du paramètre datetime déterminé? J'ai vu cela avoir 7 chiffres après la virgule.

exec sp_executesql N'SELECT * FROM Employee WHERE WhenHire < @HireDate', 
       N'@HireDate datetime', 
       @HireDate='2010-12-06 11:43:23.5733125' 

Dans ce cas, la déclaration ne parvient pas à exécuter avec cette erreur:

Msg 8114, Level 16, State 1, Line 1 Error converting data type varchar to datetime.

+1

Pouvez-vous poster la définition de table? Est-ce que 'WhenHire' est vraiment de type datetime? – VVS

+0

Je préférerais ne pas afficher toute la définition de la table. Je peux dire avec certitude que WhenHire est un type datetime. Mon problème principal que je veux comprendre est pourquoi est-ce que 7 chiffres seraient générés après la décimale dans certaines situations? Je n'ai pas été en mesure de préciser exactement ce qui le cause et je cherchais des suggestions. – Bryan

+0

Enregistrez-vous vraiment une date d'embauche à la milliseconde? Coupez-le et continuez. La précision est déterminée par le producteur du logiciel serveur que vous utilisez. Il diffère entre toutes les technologies de base de données. –

Répondre

3

par Microsoft (http://msdn.microsoft.com/en-us/library/ms187819.aspx) , le type DateTime T-SQL a une précision de .000, .003 ou .007 millisecondes. Tout ce qui a plus de précision que cela pourrait causer cette erreur.

Sauf si vous avez vraiment besoin de précision à la milliseconde, je donnerais DateTime.Now une chaîne de format - quelque chose comme « aaaa-MM-JJ HH: mm: ss » - qui vous donnerait:

exec sp_executesql N'SELECT * FROM Employee WHERE WhenHire < @HireDate', 
        N'@HireDate datetime', 
        @HireDate='2010-12-06 11:43:23' 

Le .NET Framework est en mesure de faire rapport sur des intervalles de millisecondes jusqu'à sept chiffres après la virgule, donc si vos données source provient de DateTime.Now, vous pourriez potentiellement obtenir jusqu'à sept chiffres après la virgule transmis.

+0

'select CAST ('2010-12-06 11: 43: 23.573' comme datetime)' fonctionne bien pour moi. –

+0

Oui, bien sûr - .573 est arrondie à la plus proche .003 secondes déjà.Dans la question, l'OP a noté qu'il voit parfois aller jusqu'à 7 chiffres de précision milliseconde, ce qui causerait l'erreur qu'il a vue. – rswafford

+0

Oui. Désolé, je n'ai pas bien lu la question. Je pensais que le message d'erreur provenait du SQL fourni qui ne pourrait être expliqué que par 'WhenHire' étant' varchar' et contenant une valeur datetime invalide. –

1

http://msdn.microsoft.com/en-us/library/ms186724.aspx

Aussi de microsoft Il existe plusieurs types de données de date et d'heure. L'un est datetime2 qui a une précision accrue et une seconde précision fractionnaire définie par l'utilisateur.

Ils donnent un exemple datetime2 avec 7 chiffres de précision sous-seconde.

3

Je recommande en vous assurant d'utiliser un SqlParameter avec un DateTime type db - essayez ce code:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); 
// set properties on builder (omitted for brevity) 

using (SqlConnection connection = new SqlConnection(builder.ToString())) 
using (SqlCommand command = new SqlCommand(connection)) 
{ 
    command.CommandType = System.Data.CommandType.Text; 
    command.CommandText = "SELECT * FROM Employee WHERE WhenHire < @HireDate"; 

    // make sure to have a SqlDbType.DateTime parameter! 
    SqlParameter hireDateParameter = new SqlParameter("@HireDate", SqlDbType.DateTime); 
    hireDateParameter.Value = DateTime.Now; 

    command.Parameters.Add(hireDateParameter); 

    // don't open the connection too early - this is early enough here! 
    connection.Open(); 

    using (SqlDataReader reader = command.ExecuteReader()) 
    { 
     while (reader.Read()) 
     { 
      // do stuff 
     } 
    } 
} 
+0

connection.CreateCommand() échouera si la connexion n'est pas ouverte. – Bryan

+0

@Bryan: ok fixed - utilise 'new SqlCommand (connection)' à la place –

0

On dirait qu'il était quelque chose d'étrange avec la machine cliente. Je ne sais pas exactement ce que c'était, mais quand nous avons déménagé sur une autre machine, il n'y avait plus de précision supplémentaire. Merci pour toutes les idees.

Questions connexes