2013-04-25 12 views
12

einfügen Wenn ich versuche, ein Datetime zu einem Datensatz in einer MS-Access-Datenbank die einfache Art und Weise, wie dieseVersuch DateTime.Now in Datums-/Uhrzeitfeld gibt „Datentypenkonflikt“ Fehler

cmd.CommandText = "INSERT INTO [table] ([date]) VALUES (?)"; 
cmd.Parameters.AddWithValue("?", DateTime.Now); 

zu schreiben Ich bekomme eine Ausnahme mit dem Hinweis "Datentyp stimmt nicht mit den Kriterien überein".

Kann mir jemand sagen warum? Was läuft hier falsch?

Nach einem wenig Experimentieren fand ich, dass ich es kann, wenn ich

OleDbParameter parm = new OleDbParameter("?", OleDbType.Date); 
parm.Value = DateTime.Now; 
cmd.Parameters.Add(parm); 

schreiben funktioniert aber es so scheint weniger ordentlich, weniger einfach zu tun. Warum ist das notwendig? Betrachte ich etwas Einfaches?

+0

'date' könnte hier ein Schlüsselwort sein. Probiere 'INSERT INTO table ([date]) VALUES (?)' – LarsTech

+0

@LarsTech Du hast Recht, dass es ein Keyword ist, natürlich. Ich habe den Code in der Frage aktualisiert. Aber das ist nicht die Ursache des Problems. –

Antwort

22

Das Problem des Ungleichgewichts in Kriterienausdruck ist aufgrund der OleDbType dem Parameter zugewiesen verwendet, um den DateTime.Now Wert darstellen, wenn Sie AddWithValue nennen.

Der OleDbType, der von AddWithValue ausgewählt wird, ist DBTimeStamp, aber Access möchte ein OleDbType.Date.

http://support.microsoft.com/kb/320435

Suche im NET ich eine andere interessante Spitze gefunden. Das Kernproblem liegt in dem OleDbParameter, das den Millisekunden-Teil von DateTime.Now nicht verarbeiten kann. Wahrscheinlich wird der OleDbType zu Date gezwungen, der Millisekunden-Teil wird weggelassen. Ich habe auch festgestellt, dass die Einfügung auch mit dem DBTimeStamp-Typ funktioniert, wenn wir die Millisekunden aus dem Datum entfernen.

cmd.Parameters.AddWithValue("?", GetDateWithoutMilliseconds(DateTime.Now)); 

private DateTime GetDateWithoutMilliseconds(DateTime d) 
{ 
    return new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second); 
} 

oh, naja, warten auf jemanden, der das besser erklärt.

+0

+1, was bedeutet "cmd.Parameters.AddWithValue ("? ", DateTime.Today);' würde funktionieren. – LarsTech

+2

@LarsTech Ja, aber die Zeit ist vorbei – Steve

+1

Opfer müssen mit einer Access-Datenbank gemacht werden. :-) – LarsTech

5

Die einfachste Anweisung fordert die db-Engine auf, ihre Now()-Funktion zu verwenden, um den aktuellen Datums-/Uhrzeitwert abzurufen. Oder Sie können seine Date() Funktion verwenden, wenn Sie nicht an der Tageszeit interessiert sind; Date() gibt Ihnen tatsächlich Mitternacht als Tageszeit.

INSERT INTO [table] ([date]) VALUES (Now()); 

IOW, brauchen Sie sich nicht die Mühe ein Datum/Zeit-Wert in .Net um das Massieren sie in Ihrer Access-db einzufügen.

Wenn Sie eine INSERT-Anweisung verwenden möchten, die einen literalen Datumswert enthält, verwenden Sie die Datumsgrenzen . So heutigen Datum einfügen:

INSERT INTO [table] ([date]) VALUES (#2013-04-25#); 
+1

Ich denke, er verwendet C# nicht VBA – Mike

+2

@Mike Die Programmiersprache ist nicht wichtig, weil 'Now()' ist eine integrierte Funktion in den ACE/Jet-Datenbank-Engines. –

+1

@Mike Access SQL unterstützt seine eigenen eingebauten 'Now()' und 'Date()' Funktionen. Dies ist kein C# vs VBA-Typ Problem. Diese SQL-Anweisung funktioniert, wenn sie von einer gültigen Verbindung zur Datenbank unabhängig von der Programmiersprache ausgeführt wird. – HansUp