如何将datetime以毫秒插入Access数据库?

时间:2015-03-23 06:07:01

标签: c# datetime ms-access

我正在尝试使用C#将日期+时间插入Access数据库。时间字符串中有毫秒,例如:

"2015-03-23 11:22:33.123"`

这是我的代码:

string strName = "somestring";
string strDate = "2015-03-23 11:22:33.123"

sql = @"insert into table_name  ([name], [date]) values (@Name, @Date)";

using (OleDbCommand command = new OleDbCommand(sql))
{
    command.Connection = openCon;
    command.Parameters.AddWithValue("@Name", strName);
    command.Parameters.AddWithValue("@Date", strDate ); // <-- error here          
    openCon.Open();
    recordsAffected = command.ExecuteNonQuery();
    openCon.Close();
}

我在ExcuteNonQuery()收到错误;如果我删除日期时间字符串,那么代码可以正常工作。

那么如何将datetime和毫秒插入Access数据库?

4 个答案:

答案 0 :(得分:3)

您正在混合DateTime和String。始终使用DateTime作为日期/时间值或尽早转换为DateTime。 因此:

string strDate = "2015-03-23 11:22:33.123";
DateTime datDate = DateTime.Parse(strDate);
// ...
//    command.Parameters.AddWithValue("@Date", datDate ); // <-- error here 

command.Parameters.Add("@Date",OleDbType.Date);
command.Parameters[0].Value = datDate;                    // <-- no error

请注意,尽管Access会正确存储值,但它或VBA不会显示毫秒数,而是会对第二个进行4/5舍入。当然,如果您只从C#应用程序中读取这些值,那么这一点并不重要。

当插入我的Millisecond应用程序时,可以正确插入该值:

DateTimeMs          SortValue       DateFull                CDouble             RoundSecSQL         MsecSQL MsecVBA SecondDec SecondStd
23-03-2015 11:22:33 60438568953123  23-03-2015 11:22:33.123 42086,4739944792    42086,4739930556    123     123     33,123    33
23-03-2015 11:45:31 60438570330707  23-03-2015 11:45:30.707 42086,4899387384    42086,4899305556    707     707     30,707    31

答案 1 :(得分:2)

访问&#34;日期/时间&#34;字段类型的标称分辨率为一秒。也就是说,当在Access中显示日期/时间值时,formatted使用预定义或自定义格式,或使用DateAddDatePart等函数进行操作,我们可以使用最小的时间单位指定是第二个

将OLED与.NET结合使用

通过.AddWithValue对Access数据库使用System.Data.OleDb时,日期/时间字段的DateTime参数不得具有毫秒值,否则插入/更新将失败。也就是说,

DateTime dt = Convert.ToDateTime("2015-03-23 11:22:33.123");
cmd.Parameters.AddWithValue("?", dt);
cmd.ExecuteNonQuery();

将失败

  

标准表达式中的数据类型不匹配。

但是,正如Gustav在his answer中指出的那样,我们可以.Add使用OleDbType.Date添加DateTime参数,其中包含毫秒,

DateTime dt = Convert.ToDateTime("2015-03-23 11:22:33.123");
cmd.Parameters.Add("?", OleDbType.Date).Value = dt;
cmd.ExecuteNonQuery();

,该值将完整地存储在“访问日期/时间”字段中。我们可以通过检索存储的值并检查它来验证这一点

cmd.CommandText = "SELECT [date] FROM table_name WHERE ID = 13";
DateTime rtn = Convert.ToDateTime(cmd.ExecuteScalar());
Console.WriteLine(rtn.Millisecond);

...打印&#34; 123&#34;,表明毫秒组件是返回值的一部分。

诀窍在于Access本身并没有为我们提供有效使用这些日期/时间值的毫秒部分的工具。要在Access / VBA中执行此操作,需要一些额外的编码,如另一个网站here上的文章所述。

(当然,如果您只想将值拉回到.NET应用程序中,那么您可以使用上面的代码片段。)

将ODBC与.NET一起使用

System.Data.Odbc使用相同的方法会产生稍微不同的结果。 Access ODBC驱动程序将为DateTime.Add接受带有毫秒值的.AddWithValue参数,但 NOT 将存储毫秒数。

此外,如果我们尝试检索使用OLEDB存储的毫秒数的日期/时间值,则Access ODBC驱动程序将删除毫秒。也就是说,如果我们尝试使用以下ODBC代码来检索&#34;毫秒值&#34;我们通过上面的OLEDB示例存储......

// cmd is now an OdbcCommand object
cmd.CommandText = "SELECT [date] FROM table_name WHERE ID = 13";
DateTime rtn = Convert.ToDateTime(cmd.ExecuteScalar());
Console.WriteLine(rtn.Millisecond);

...它打印&#34; 0&#34;,即使我们可以通过

验证Double值的毫秒部分已存储在数据库中
cmd.CommandText = "SELECT CDbl([date]) AS foo FROM table_name WHERE ID = 13";
Double rtn = Convert.ToDouble(cmd.ExecuteScalar());
Console.WriteLine(rtn);

并检查Double值的小数部分。

<强>替代

如果您希望保持在日期/时间字段类型的标称1秒分辨率范围内,您可以...

将值四舍五入到最接近的秒:

DateTime dt = Convert.ToDateTime("2015-03-23 11:22:33.123");
if (dt.Millisecond >= 500)
{
    dt = dt.AddSeconds(1);
}
dt = dt.AddMilliseconds(-dt.Millisecond);
cmd.Parameters.AddWithValue("?", dt);
cmd.ExecuteNonQuery();

或者,如果你想保持毫秒,那么你必须将截断的(不是舍入的)日期/时间和毫秒存储在单独的字段中,或者只是将原始字符串值存储在文本字段中。

答案 2 :(得分:1)

你必须尝试这样:

command.Parameters.AddWithValue("@Date", GetDateWithMilliseconds(strDate));

private DateTime GetDateWithoutMilliseconds(DateTime d)
{
    command new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second,d.Milliseconds);
}

您收到错误的原因是,当您使用AddWithValue使用OleDbType时,它是DBTimeStamp,但Access需要OleDbType.Date。查看MSDN了解详情

或者您可以尝试这样:

command.Parameters.Add("@Date", OleDbType.Date).Value = strDate;

答案 3 :(得分:-1)

尝试使用此

string strDate = "2015-03-23 11:22:33"