2013-04-25 16 views
12

Se provo a scrivere un datetime a un record in un database MS-Access la via più facile, come questocercando di inserire DateTime.Now nel campo Data/ora dà "Tipo di dati non corrispondente" Errore di

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

Ricevo un'eccezione dicendo "Mancata corrispondenza del tipo di dati nell'espressione dei criteri".

Qualcuno può dirmi perché? Cosa va storto qui?

Dopo un po 'di sperimentazione, ho trovato che posso farlo funzionare se scrivo

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

ma farlo in questo modo sembra meno ordinata, meno semplice. Perché è necessario? Sto trascurando qualcosa di semplice?

+0

'date' potrebbe essere una parola chiave qui. Prova 'INSERT INTO table ([date]) VALUES (?)' – LarsTech

+0

@LarsTech Hai ragione sul fatto che sia una parola chiave, ovviamente. Ho aggiornato il codice nella domanda. Ma questa non è la causa del problema. –

risposta

22

Il problema della mancata corrispondenza nell'espressione criterio è dovuta alla OleDbType assegnato al parametro utilizzato per rappresentare il valore DateTime.Now quando si chiama AddWithValue.

Il OleDbType scelto da AddWithValue è DBTimeStamp, ma Access vuole un OleDbType.Date.

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

Cercando in rete ho trovato un altro suggerimento intersting. Il problema principale si trova nell'oggetto OleDbParameter che non può gestire la parte dei millisecondi di DateTime.Now. Probabilmente forzando l'OleDbType ad essere Data, la parte dei millisecondi viene omessa. Ho anche scoperto che l'inserto funziona anche con il tipo DBTimeStamp se rimuoviamo i millisecondi dalla data.

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, beh, in attesa di qualcuno che lo spieghi meglio.

+0

+1, che significa 'cmd.Parameters.AddWithValue ("? ", DateTime.Today);' funzionerebbe. – LarsTech

+2

@LarsTech sì, ma la parte temporale è scomparsa – Steve

+1

I sacrifici devono essere eseguiti con un database di Access. :-) – LarsTech

5

La dichiarazione più semplice richiede al motore db di utilizzare la sua funzione Now() per ottenere il valore di data/ora corrente. Oppure potresti usare la sua funzione Date() se non sei interessato all'ora del giorno; Date() ti darà effettivamente la mezzanotte come ora del giorno.

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

IOW, non è necessario preoccuparsi massaggiando un valore Data/ora nel .Net al fine di inserirla nel db Access.

Se si desidera una dichiarazione INSERT che include un valore di data letterale, utilizzare i delimitatori di data #. Quindi, per inserire la data odierna:

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

Penso che stia usando C# non VBA – Mike

+2

@Mike Il linguaggio di programmazione non ha importanza perché 'Now()' è una funzione incorporata nei motori di database ACE/Jet. –

+1

@Mike Access SQL supporta le proprie funzioni incorporate 'Now()' e 'Date()'. Questo non è un problema di tipo C# vs VBA. Quella istruzione SQL funzionerà quando viene eseguita da una connessione valida al db indipendentemente dal linguaggio di programmazione. – HansUp

Problemi correlati