none
向数据库插入时间类型数据的奇怪问题 RRS feed

  • 问题

  •         DateTime Time_T = DateTime.Now;
            DateTime Time_D = Time_T;
            string Time_S = Time_T.ToString("yyyy-MM-dd HH:mm:ss.fff");
            SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["SqlConnection"].ToString());
            SqlCommand cmd = new SqlCommand("Insert Into Test (Time) Values (@Time) ", conn);
            //取值方法1,实际环境中并不是三条语句同时使用。
            cmd.Parameters.Add("@Time", SqlDbType.DateTime).Value = Time_D;//数据结果不正确,时间大于Time_T(不是四舍五入问题),取的不是Time_T,而是当前时间,等效cmd.Parameters.Add("@Time", SqlDbType.DateTime).Value = DateTime.Now;
            //取值方法2,实际环境中并不是三条语句同时使用。
            cmd.Parameters.Add("@Time", SqlDbType.DateTime).Value = Time_D.ToString("yyyy-MM-dd HH:mm:ss.fff");//数据结果不正确,时间大于Time_T(不是四舍五入问题),取的不是Time_T,而是当前时间,等效 cmd.Parameters.Add("@Time", SqlDbType.DateTime).Value = DateTime.Now;
            //取值方法3,实际环境中并不是三条语句同时使用。
            cmd.Parameters.Add("@Time", SqlDbType.DateTime).Value = Time_S;//正确
    我想问的是,DateTime类型的Time_D为什么会引用一个新的DateTime.Now值给cmd.Parameters.Add("@Time", SqlDbType.DateTime).Value?
    • 已移动 Sheng Jiang 蒋晟Moderator 2009年11月17日 23:24 System.Data问题 (发件人:.NET Framework 一般性问题讨论区)
    2009年11月16日 21:50

答案

  • 经过我无数次测试,终于解决问题。
    DateTime.Now时间为yyyy-MM-dd HH:mm:ss.fffffff,(前三个)fff是准确值,(后四个)ffff不知道是哪里来的几个莫名其妙的值,暂时称为幽灵值
    DateTime字段类型时间为yyyy-MM-dd HH:mm:ss.fff,(前两个)ff是准确值,(最后一个)f是误差约小于3的误差值
    DateTime2(3)yyyy-MM-dd HH:mm:ss.fff,(前两个)ff是准确值,(最后一个)f是根据自己的值和后一位(第四位)取四舍五入值
    DateTime.Now赋值到DateTime字段类型=准确值+幽灵值+误差值,取得准才出了鬼了
    DateTime.Now赋值到DateTime2(3)字段类型=准确值+幽灵值+四舍五入值,总是大
    string Time_S = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");舍弃幽灵值,取准确值,不四舍五入=精准值
    string Time_S赋值到DateTime2(3)字段类型=准确值(没有第四位,不存在四舍五入)+精准值,正确值
    • 已标记为答案 AM-X 2009年11月17日 3:29
    2009年11月17日 3:27

全部回复

  • 你好!

    出现这样的问题可能是因为在数据库表 Test 中字段 Time 不是日期类型而 DateTime.ToString() 默认的格式化字符串不是 yyyy-MM-dd HH:mm:ss.fff ,你可以将此字段改为 DateTime,参数使用下面的方式添加。

    comm.Parameters.AddWithValue("@Time", DateTime.Now);

    知识改变命运,奋斗成就人生!
    2009年11月17日 1:05
    版主
  • string Time_S = Time_T.ToString("yyyy-MM-dd HH:mm:ss.fff");

    当你转换成字符串后 无法被重新转换为符合sql server数据库的格式 所以就会出错

    传参的时候直接用DateTime类型的就可以了
    如果是要取出数据按照既定的格式展示,可以在展示的时候 进行ToString(IFormatProvider)
    Wenn ich dich hab’,gibt es nichts, was unerträglich ist.坚持不懈!My blog~~~
    2009年11月17日 1:32
    版主
  • 你好!

    出现这样的问题可能是因为在数据库表 Test 中字段 Time 不是日期类型而 DateTime.ToString() 默认的格式化字符串不是 yyyy-MM-dd HH:mm:ss.fff ,你可以将此字段改为 DateTime,参数使用下面的方式添加。

    comm.Parameters.AddWithValue("@Time", DateTime.Now);

    知识改变命运,奋斗成就人生!
    Time字段是datetime和datetime2(7)两种都试过了.
    DateTime.ToString() 默认的格式化字符串不是 yyyy-MM-dd HH:mm:ss.fff ,但是我已经指定了ToString("yyyy-MM-dd HH:mm:ss.fff")格式。
    数据库中的时间要与文件名对应的,也就是HH:mm:ss.fff必须相同,值一定要一样。
    Time_T.ToString("yyyy-MM-dd HH:mm:ss.fff")不存在四舍五入现象
    cmd.Parameters.AddWithValue("@Time", DateTime.Now);//DateTime.Now存储为datetime、datetime2(3)有四舍五入现象
    cmd.Parameters.Add("@Time", SqlDbType.DateTime).Value = Time_S;我发现一样有时间漂移现象,飘移幅度HH:mm:ss.fff<=正负00:00:00:00.002,Time_D是总是大。
    Parameters.AddWithValue("@Time", Time_D)和cmd.Parameters.AddWithValue("@Time", DateTime.Now)出现四舍五入
    目前Parameters.AddWithValue("@Time", Time_S)没发现问题,时间好像能完全匹配。
    你能告诉我数据库Time字段等效datetime和datetime2(7)两种数据类型的Parameters.Add()方法的完整写法吗?指完整参数。
    2009年11月17日 2:06
  • string Time_S = Time_T.ToString("yyyy-MM-dd HH:mm:ss.fff");

    当你转换成字符串后 无法被重新转换为符合sql server数据库的格式 所以就会出错

    传参的时候直接用DateTime类型的就可以了
    如果是要取出数据按照既定的格式展示,可以在展示的时候 进行ToString(IFormatProvider)
    Wenn ich dich hab’,gibt es nichts, was unerträglich ist.坚持不懈! My blog~~~
    datetime类型字段的默认值给你复制出来一个2009-11-04 02:16:11.640
    datetime2(7)类型字段的默认值给你复制出来一个2009-11-17 09:19:43.9970000
    如果你说yyyy-MM-dd HH:mm:ss.fff存入datetime类型字段出现无法转换请你拿出依据
    主题里已经说了传参直接用DateTime类型字段值会永远比DateTime.Now大
    不取数据,只求完全匹配
    2009年11月17日 2:18
  • DateTime fileDateTime = DateTime.Now;

    // 构梏你的文件名。
    // ....
    comm.Parameters.Add("@Time", System.Data.SqlDbType.DateTime2, 7).Value = fileDateTime;
    comm.Parameters.Add("@Time", System.Data.SqlDbType.DateTime, 0).Value = fileDateTime;

    知识改变命运,奋斗成就人生!
    2009年11月17日 2:40
    版主
  • 经过我无数次测试,终于解决问题。
    DateTime.Now时间为yyyy-MM-dd HH:mm:ss.fffffff,(前三个)fff是准确值,(后四个)ffff不知道是哪里来的几个莫名其妙的值,暂时称为幽灵值
    DateTime字段类型时间为yyyy-MM-dd HH:mm:ss.fff,(前两个)ff是准确值,(最后一个)f是误差约小于3的误差值
    DateTime2(3)yyyy-MM-dd HH:mm:ss.fff,(前两个)ff是准确值,(最后一个)f是根据自己的值和后一位(第四位)取四舍五入值
    DateTime.Now赋值到DateTime字段类型=准确值+幽灵值+误差值,取得准才出了鬼了
    DateTime.Now赋值到DateTime2(3)字段类型=准确值+幽灵值+四舍五入值,总是大
    string Time_S = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");舍弃幽灵值,取准确值,不四舍五入=精准值
    string Time_S赋值到DateTime2(3)字段类型=准确值(没有第四位,不存在四舍五入)+精准值,正确值
    • 已标记为答案 AM-X 2009年11月17日 3:29
    2009年11月17日 3:27
  • DateTime fileDateTime = DateTime.Now;

    // 构梏你的文件名。
    // ....
    comm.Parameters.Add("@Time", System.Data.SqlDbType.DateTime2, 7).Value = fileDateTime;
    comm.Parameters.Add("@Time", System.Data.SqlDbType.DateTime, 0).Value = fileDateTime;

    知识改变命运,奋斗成就人生!
    DateTime Time_T = DateTime.Now;
    string Time_S = Time_T.ToString("yyyy-MM-dd HH:mm:ss.fff");
    cmd.Parameters.Add("@Time", SqlDbType.DateTime2,3).Value = Time_S;
    我测试结果只有这样写是正确的
    2009年11月17日 3:41