【问题标题】:Cast Null DateTime Value From Database?从数据库中投射空日期时间值?
【发布时间】:2019-03-25 13:36:39
【问题描述】:

我正在执行一个简单的 SELECT 语句,并尝试从 SQL Server 2012 表的 DateTime 列中返回值。问题是,当我返回 NULL DateTime 值时,我不知道如何使用下面的代码来管理它。

dtTrainingEnd = (DateTime)reader["TrainingEnd"];

过去几天我一直在寻找答案,但找不到对我有帮助的东西。我发现了类似的帖子,但我仍然无法弄清楚它们如何帮助我。您能解释一下我如何检查从数据库返回的日期时间值是否为 NULL 吗?

SqlConnection connRead = new SqlConnection(connReadString);
SqlCommand comm = new SqlCommand();
SqlDataReader reader;
string sql;

DateTime dtTrainingEnd = DateTime.Now;
int iTrainingSwipeID = 123;

sql = "SELECT TrainingEnd FROM TrainingSwipe WHERE TrainingSwipeID = " + iTrainingSwipeID;

comm.CommandText = sql;
comm.CommandType = CommandType.Text;
comm.Connection = connRead;

connRead.Open();
reader = comm.ExecuteReader();

while (reader.Read())
{
    dtTrainingEnd = (DateTime)reader["TrainingEnd"];
}
connRead.Close();

【问题讨论】:

  • 关于 DateTime 类型的说明,DateTime 是一种(结构)值类型,当检索空值时,它会将自身设置为默认值。此类型的默认值为 '01/01/0001'。
  • 如果数据库允许空值,你的代码也应该这样做。考虑在涉及这些列的情况下使用可为空的类型。

标签: c# sql-server datetime casting


【解决方案1】:

如果可能是null,您可以使用可为空的类型...在这种情况下,是DateTime? 类型:

while (reader.Read())
{
    dtTrainingEnd = ((DateTime?)reader["TrainingEnd"]) ?? some_default_date;
}
connRead.Close();

如果您愿意,也可以只测试null

while (reader.Read())
{
    var endDate = reader["TrainingEnd"];
    dtTrainingEnd = (endDate == null) ? some_default_date : (DateTime)endDate;
}
connRead.Close();

在上述两种情况下,如果数据库中的日期为 NULL,我假设您希望 dtTrainingEnd 包含 something,因此 some_default_date 是一些默认的 DateTime。

或者,如果您想在值为 NULL 的情况下单独保留 dtTrainingEnd,那么在这种情况下不要设置它:

while (reader.Read())
{
    if ((reader["TrainingEnd"]) != null)
        dtTrainingEnd = (DateTime)reader["TrainingEnd"];
}
connRead.Close();

*** 根据您连接到数据库的方式,您可能需要替换 null DBNull.Value

【讨论】:

  • 更广泛的模式可能是reader["field"] as DateTime? ?? some_default_date;这对于使用 DataTables 处理相同的场景很有用,因为 null 变为 DBNull.Value
  • @Grant,在您的第二个示例中,如果数据库值为 NULL,将保存到 dtTrainingEnd 中的内容是什么?换句话说,判断 datetime 是否为 NULL 的 if 语句是什么?抱歉,我对这个话题一无所知。
  • @Grant,好的,我想我明白了。非常感谢您的耐心和帮助。 :D
  • @Grant,当我将代码放入时,if 语句“if ((reader["TrainingEnd"]) != null)”上出现错误“System.IndexOutOfRangeException: TrainingEnd”。有任何想法吗?我不敢相信这在 c# 中很难查看日期时间是否为空...... :(
  • @Grant,出于某种原因,对我来说,检查“== null”对于数据库中所有非空记录返回非空。因此,稍作搜索发现对我来说“== DBNull.Value”可以解决问题。不知道有什么区别,但我想我会提到它以防其他人遇到同样的问题。
【解决方案2】:

使用 SQL,您可以执行 SELECT Coalesce(TrainingEnd,0),如果它为空,您将有一个 1900-01-01 日期...

【讨论】:

    猜你喜欢
    • 2014-06-16
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    相关资源
    最近更新 更多