Search code examples
c#databaseado.netoledb

Why my Access DB rejects an insert date time?


I have this table created on an Access DB.

string sql = $"CREATE TABLE Eventi (" +
  $"id AUTOINCREMENT PRIMARY KEY," +
  $"tipologia varchar(255)," +
  $"denominazione varchar(255)," +
  $"descrizione varchar(255)," +
  $"data date," +
  $"costo decimal," +
  $"prezzo decimal" +
$");";

I use this query to insert new records in the table, but when i exec the query it returns me a 'System.Data.OleDb.OleDbException: 'Data type mismatch in criteria expression.'.

cmd.CommandText = "INSERT INTO Eventi (tipologia,denominazione,descrizione,data,costo,prezzo) VALUES " +
"(@tipologia, @denominazione, @descrizione, @data, @costo, @prezzo);";

Here it is the code to add the querie's parameters:

cmd.Parameters.Add("@id", OleDbType.Integer).Value = v.Id;
cmd.Parameters.Add("@tipologia", OleDbType.VarChar, 255).Value = v.Tipologia;
cmd.Parameters.Add("@denominazione", OleDbType.VarChar, 255).Value = v.Denominazione;
cmd.Parameters.Add("@descrizione", OleDbType.VarChar, 255).Value = v.Descrizione;
cmd.Parameters.Add("@data", OleDbType.Date).Value = v.Data.Date;
cmd.Parameters.Add("@costo", OleDbType.Double).Value = v.Costo;
cmd.Parameters.Add("@prezzo", OleDbType.Double).Value = v.Prezzo;

Solution

  • The real problem in your query is not the type difference between decimal and double. While it is really good practice to always express the correct datatype, in this context, the parameters of type double can be easily converted to decimal if the properties Costo and Prezzo are of type decimal.
    The real problem is the presence of a first parameter named @ID while you don't have this field in your fields names and in your parameters placeholders.

    In OleDb parameters are not recognized by their name and assigned to their placeholders using the name property. (Indeed the documentation tells us to name these placeholders all with the ? character). In OleDb parameters are positional, so the first parameter will be used as the value for the first placeholder. In your code this results in a shift of every parameter by one position leading to the parameter @Descrizione assigned to the field data and of course that string is not a date.

    Just remove the first parameter from your collection and everything should be fine.

    Side note. In Access, as well in MySql, you can assign a value to an AUTOINCREMENT/AUTONUMBER field if you really want. SqlServer instead doesn't allow this practice without turning off the IDENTITY property of the column.