【问题标题】:SqlDateTime overflow when using .ExecuteReader使用 .ExecuteReader 时 SqlDateTime 溢出
【发布时间】:2016-02-23 17:01:45
【问题描述】:

我在执行一个在 asp 页面上使用的阅读器时遇到这个错误:

SqlDateTime 溢出。必须在 1753 年 1 月 1 日凌晨 12:00:00 到 9999 年 12 月 31 日晚上 11:59:59 之间。

从日历中选择一个日期,并将其设置为DateTime 变量,然后将其用作 SQL 命令中的参数。它似乎随机工作,我选择了一个日期,它工作,我重新加载页面并选择同一天,它可能不工作。

我的相关代码如下,我在.ExecuteReader() 行收到错误消息。 我在阅读器执行之前检查了confirmedDate 变量,它确实有一个有效的DateTime

    DateTime confirmedDate = DateTime.Parse(dateSelected);
    SqlCommand command4 = new SqlCommand();
    command4.Connection = gconn;
    String sql4 = "SELECT MAX([Day]) as TheDay FROM Days WHERE User_ID = @User_ID AND [Day] < @dateSelected AND NOT EXISTS (SELECT 1 FROM Days WHERE User_ID = @User_ID AND [DAY] >= @dateSelected)";
    command4.CommandText = sql4;
    command4.Parameters.Add(new SqlParameter("@User_ID", ""));
    command4.Parameters.Add(new SqlParameter("@dateSelected", confirmedDate));


for (int i = 0; i < firstName.Count; i++ )
{
    command4.Parameters["@User_ID"].Value = userID[i];

    using (SqlDataReader reader = command4.ExecuteReader()) //error here
    {
        while (reader.Read())
        {
            if (reader.HasRows)
            {
                if (reader["TheDay"].ToString() == "") 
                {
                    dates.Add("NULL"); 
                }
                else
                {
                    dates.Add(reader["TheDay"].ToString());
                }
            }
        }
    }
}   

我查找了有关此问题的其他问题,但找不到有效的解决方案。始终传入有效的DateTime 值。

【问题讨论】:

  • 作为解决问题的第一步,我会尝试使用明确的 DataType 设置参数,并且从不使用方法来为我决定哪个是参数的正确 DataType。

标签: c# asp.net sql-server datetime sqldatetime


【解决方案1】:

.net DateTime 对象的可能范围与 Sql Server DateTime 对象不同。在将其插入 sql 查询之前,您应该进行一些参数验证。

这是一个例子。

DateTime confirmedDate = DateTime.Parse(dateSelected);
if(confirmedDate > DateTime.Now) throw new ArgumentOutOfRangeException("Date time cannot be in the future");
if(confirmedDate.Year < 1990)  throw new ArgumentOutOfRangeException("Sorry, we only have data starting from the year 1990");

还要在参数中指定数据类型。

command4.Parameters.Add(new SqlParameter("@dateSelected", SqlDbType.DateTime){Value = confirmedDate}));

.Net DateTime 的范围

  • Min DateTime - 00:00:00.0000000 UTC,0001 年 1 月 1 日
  • Max DateTime - 23:59:59.9999999 UTC,9999 年 12 月 31 日

可能的range of a Sql DateTime

  • 最小值 - 1753 年 1 月 1 日凌晨 12:00:00
  • 最大值 - 12/31/9999 晚上 11:59:59

【讨论】:

  • 或者从datetime改成datetime2,范围更好
  • 事实证明,由于某些情况,日期来自的日历有时为 Null,导致日期为 1 月 1 日的 0001。修复了该问题并按照您所说的进行了参数验证,因为这是正确的方法。
  • @PanagiotisKanavos - 绝对同意是否需要关注精度或 (如您所述) 您需要扩展可能的范围。
【解决方案2】:

将第二个@dateSelected 替换为另一个名称@dateselected2,并将其添加为第三个参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    相关资源
    最近更新 更多