System.Data.OleDb.OLEDBEException:&x27;条件表达式中的数据类型不匹配;C#错误

System.Data.OleDb.OLEDBEException:&x27;条件表达式中的数据类型不匹配;C#错误,c#,ms-access,C#,Ms Access,这是一个一般性问题。我甚至理解这个错误。但到目前为止,什么都帮不了我。 为什么获取System.Data.OleDb.OLEDBEException:“条件表达式中的数据类型不匹配。”错误 private void DataWrite() { connectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + MyDataBase; connection = new OleDbConnection(connec

这是一个一般性问题。我甚至理解这个错误。但到目前为止,什么都帮不了我。 为什么获取System.Data.OleDb.OLEDBEException:“条件表达式中的数据类型不匹配。”错误

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是短文本,日期是日期/时间,度量值是短文本

我认为问题来自日期转换。通常,我会在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}')";

让我们通过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();
}

现在,对于侧边信息,还需要阅读-这对插入没有多大关系,AddWithValue可以方便地在so帖子中演示参数化,但是对于生产系统选择有一些改进(不使用access也是一种改进)因为如果AddWithValue猜错了类型,可能会影响性能或数据精度

编写SQL时始终使用参数。如果你认为你不能,因为你可能有一个数组中的值,你必须使用一个循环将这些值连接到sql中(例如);不要在中计算值。很可能在数组中包含参数占位符并为数组中的每个值添加一个参数。从不使用concat值,始终使用concat参数占位符


如果您想简化数据库的使用,但仍然要编写SQL,请查看

使用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中输入的参数名称匹配


免责声明:我从未使用dapper在Access/ole上执行此操作,我只是

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

并非所有值都是文本

在这里,您似乎只有数字和日期值。因此,对不同的数据类型使用适当的SQL语法,日期是一个保留字:

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

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

!你听说过SQL注入吗?这两个建议都很容易被忽略。不要这样做。没错,但我使用的是一个沉重的应用程序,风险比在网络环境中要低。上次我在网上发布了一个带有addwithvalue的答案,我得到了一个讲座和一大堆关于这是魔鬼的工作的反对票……你不是唯一的一个。如果人们停下来认为一个insert命中了一条记录,因此一个错误类型转换的影响可以忽略不计/这与duff类型猜测相去甚远,这意味着数百万条记录上的索引无法使用,那么他们可能没有讲课。我在问题中特别提出了这一点,以便给出一个全面和平衡的观点,希望它能被阅读和考虑!)