C# 和 MS Access 之间的数据类型不匹配?

Posted

技术标签:

【中文标题】C# 和 MS Access 之间的数据类型不匹配?【英文标题】:DataType mismatch between C# and MS Access? 【发布时间】:2015-01-10 21:56:39 【问题描述】:

我有一条 SQL 语句导致 MS Access 数据库上的 C# 中出现错误,该数据库似乎间歇性地工作。我想我找到了问题,但不明白答案或没有解决方案。

我的C#中的SQL语句是这样写的:

// note that Start and StartLog are both nullable variables and ProfileID variable is a string

cmd = new OleDbCommand("INSERT INTO shifts(profile_id, start, start_log) " +
                "VALUES (@profile_id, @start, @start_log);");
cmd.Parameters.AddWithValue("@profile_id", ProfileID);
cmd.Parameters.AddWithValue("@start", Start.Value);
cmd.Parameters.AddWithValue("@start_log", StartLog.Value);

shifts 表具有以下列:

profile_id is a string
start is a date/time
start_log is a date_time

我尝试使用从调试器中提取的以下数据执行语句:

profile_id -> "16078965744"
start -> 1/10/2015 1:30:00 PM
start_log -> 1/10/2015 1:23:13 PM

并得到以下异常:

System.DataOleDb.OleDbException: "Data type mismatch in criteria expression."

我注意到,如果我按如下方式在 Start.Value 和 StartLog.Value 上调用 ToString(),它会起作用:

cmd = new OleDbCommand("INSERT INTO shifts(profile_id, start, start_log) " +
                "VALUES (@profile_id, @start, @start_log);");
cmd.Parameters.AddWithValue("@profile_id", ProfileID);
cmd.Parameters.AddWithValue("@start", Start.Value.ToString());
cmd.Parameters.AddWithValue("@start_log", StartLog.Value.ToString());

我怀疑这个问题与 Steve 的 SO answer 相关,毫秒部分是由较早的 DateTime.Now 调用引起的。

任何人对此有解决方案或知道问题所在?

我怀疑this 会解决我的问题,但坦率地说,我是一个初学者,我对整个考验感到困惑。

这个问题来自这个问题here,我正在调查这个问题。

【问题讨论】:

是 ProfileID(来自 DB)和 @profile_id 字符串? @Mark ProfileID是一个字符串实例变量,而@profile_id是OleDB的参数,也是一个字符串。 听起来数据库的 Start 和 StartLog 定义为字符串而不是 Date 否则你仍然应该得到一个不匹配的字符串传递给 Date col @Plutonix 并非如此。我还仔细检查了数据库表,两列都列为日期/时间。 在这种情况下,删除.ToString,以传递日期;然后在两个 AddWithValue 语句执行后检查调试中的参数,并查看这两个参数数据类型是什么(尤其是如果它们不同 Date vs TimeSpatmp 8I think*)。 AddWithValue 允许 OleDB 根据传递的数据解释数据类型。这些是否来自 DTP? 【参考方案1】:

是的,如果您在 .NET 中从先前对 DateTime.Now 的调用中派生参数值,那么几乎可以肯定是毫秒导致了问题。

您可以使用您引用here 的上一个问题的答案中的方法来消除毫秒,或者您可以将参数格式化为yyyy-MM-dd HH:mm:ss 字符串并让Access OLEDB 将它们转换回Access Date/Time值,即,

cmd.Parameters.AddWithValue("@profile_id", ProfileID);
cmd.Parameters.AddWithValue("@start", Start.Value.ToString("yyyy-MM-dd HH:mm:ss"));
cmd.Parameters.AddWithValue("@start_log", StartLog.Value.ToString("yyyy-MM-dd HH:mm:ss"));

【讨论】:

这对于不同地区的不同时间格式是不是一个潜在的陷阱? @YouAreSalty - 恰恰相反。将日期显式格式化为 yyyy-MM-dd 使其明确,因此无论 Windows 中指定的短日期格式如何,它都可以工作。由于 Access 数据库引擎解释日期文字的方式,其他格式,尤其是 dd-MM-yyyy 可能会导致问题。 我将你的答案标记为答案,但我最终使用了我原始帖子中提到的扩展方法,并将类更新为始终截断到最接近的秒。使我不必编辑每个实例并添加 ToString(),因为在我调用这些属性的任何地方,它都会被预先截断。

以上是关于C# 和 MS Access 之间的数据类型不匹配?的主要内容,如果未能解决你的问题,请参考以下文章

ms access 数据库中条件表达式异常中的数据类型不匹配

MS Access - 条件表达式中的数据类型不匹配

PHP ODBC 数据类型不匹配 (MS Access)

尝试从 C# 插入 Access 数据库时数据类型不匹配

MS Access 报告给出“数据类型不匹配”错误,但基础查询没有

使用 Decimal 参数的数据类型不匹配 - OleDb、C#、Access