System.Data.OleDb.OleDbException:'条件表达式中的数据类型不匹配。' C#错误

时间:2019-11-20 09:06:56

标签: c# ms-access

这是一个普遍的问题。我什至理解错误。但到目前为止,没有任何帮助。 为什么我得到System.Data.OleDb.OleDbException:'条件表达式中的数据类型不匹配。'错误。

private void DataWrite()
{
   connectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + MyDataBase;
   connection = new OleDbConnection(connectionString);
   connection.Open();
   OleDbCommand cmd = new OleDbCommand();
   int testValue = 1;
   string values = "INSERT INTO DataTable (ID,Date,Measurement)\r\nVALUES ('" + testValue.ToString() + "','" + DateTime.Now + "','" + testValue.ToString() + "')";
   cmd = new OleDbCommand(values, connection);
   cmd.ExecuteNonQuery();
   connection.Close();
}


访问数据类型为 ID是短文本,日期是日期/时间,测量是短文本

3 个答案:

答案 0 :(得分:1)

让我们使用sql中的参数正确执行此操作:

private void DatenInDatenbankSchreibenKalibrierung()
{
   connectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + MyDataBase;
   connection = new OleDbConnection(connectionString);
   connection.Open();
   OleDbCommand cmd = new OleDbCommand();
   int testValue = 1;
   string values = "INSERT INTO DataTable (ID,[Date],Measurement) VALUES (?,?,?)";
   cmd = new OleDbCommand(values, connection);
   cmd.Parameters.AddWithValue("p1", testValue);
   cmd.Parameters.AddWithValue("p2", DateTime.Now);
   cmd.Parameters.AddWithValue("p3", 1234);
   cmd.ExecuteNonQuery();
   connection.Close();
}

Why we always use parameters

现在,关于辅助信息,也请阅读Can we stop using AddWithValue already-对于插入来说没什么大不了的,AddWithValue便于在SO帖子中演示参数化,但是生产系统有所改进SELECT(不使用访问权限也会有所改善),因为如果AddWithValue猜测类型错误,则可能会对性能或数据精度产生影响

在编写SQL时始终使用参数。如果您认为自己做不到,则因为您可能在数组中包含值,并且必须使用循环将这些值连接到sql中(例如);不要在其中合并值。完全有可能在其中合并参数占位符,并为数组中的每个值添加一个参数。永远不要concat值,永远concat参数占位符


如果您想使数据库工作更轻松,但仍要编写SQL,请查看Dapper

使用dapper,您的代码将更像:

using(var x = new OleDbConnection(...)){
  x.Execute("INSERT INTO DataTable (ID,[Date],Measurement) VALUES (?id?,?dt?,?ms?)",
    new { id = 1, dt = DateTime.Now, ms = 1234 }
  );
}

是的,就是这样! Dapper将负责所有的连接打开,参数添加,类型猜测等工作,您所需要做的就是在连接上执行查询,并为其提供sql和一个匿名对象,其名称与您在sql中输入的参数名相匹配

免责声明:我从未在Access / ole上使用dapper来做到这一点,我只是parroting the words of Dapper's author

答案 1 :(得分:0)

即使首选参数,也可以回答您的直接问题:

并非所有值都是文本

在这里,您似乎只有数字和日期值。因此,对不同的数据类型使用正确的SQL语法,并且 Date 是保留字:

string values = "INSERT INTO DataTable (ID, [Date], Measurement)\r\nVALUES (" + testNumericId.ToString() + ", #" + DateTime.Now.ToString("yyyy'/'MM'/'dd") + "#, " + testNumericValue.ToString(System.Globalization.CultureInfo.InvariantCulture) + ")";

数字十进制值必须使用点作为十进制分隔符转换为文本。

答案 2 :(得分:-5)

我认为问题出在日期转换上。通常,我会这样在SQL语句中固定格式:

string values = "INSERT INTO DataTable (ID,Date,Measurement)\r\nVALUES ('" + testValue.ToString() + "','" + DateTime.Now.ToString("yyyyMMddhhmmssfff") + "','" + testValue.ToString() + "')";

或者我更喜欢字符串插值:

string values = $"INSERT INTO DataTable (ID,Date,Measurement)\r\nVALUES ('{testValue}','{DateTime.Now:yyyyMMddhhmmssfff}','{testValue}')";