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 字符串? @MarkProfileID
是一个字符串实例变量,而@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 数据库中条件表达式异常中的数据类型不匹配