【问题标题】:C# Generate Query to Compare DateTime with SQL Nvarchar date ColumnC# 生成查询以将 DateTime 与 SQL Nvarchar 日期列进行比较
【发布时间】:2016-11-12 03:11:14
【问题描述】:

我试图根据用户检查的两个日期来获得结果。 我有两个 datetimepicker 控件。 我希望用户选择“从”日期和“到”日期, 然后查询得到具体的结果。

leaving_time 列类型为 nvarchar

这是我的查询:

SELECT name, mil_no, rotba, arrival_time, leaving_time, day, year
FROM dbo.Hodor_data 
WHERE leaving_time BETWEEN '"+dateTimePicker1.Checked.ToString()+ "' AND  '" + dateTimePicker2.Checked.ToString() + '"

错在哪里?

【问题讨论】:

  • 使用参数化查询。
  • 您遇到了什么错误?如果没有错误显示示例数据
  • 那么您将很难找到日期。如果您希望有机会对这些值执行查询,则应将日期存储在 DateTime 列中。
  • 我不知道您如何将这些日期存储在 varchar 列中,但是为了解释问题,假设您使用 dd-MM-yyyy 格式。现在你的离开时间是“01-07-2016”,转换为字符串的两个选择器值是“15-04-2016”和“15-07-2016”。 leave_time 不包括在此期间,因为按字母顺序,字母 '0' 位于 '1' 之前。日期应该被使用和存储为日期(在内部它们有一个数字表示,可以排除任何可能的误解)

标签: c# sql


【解决方案1】:

您应该编写参数化查询,而不是使用字符串连接来传递参数,以便创建 sql 命令。使用字符串连接会使您的代码容易受到 sql 注入的攻击。

var cmdText = @"SELECT ...
                FROM dbo.Hodor_data
                WHERE leaving_time BETWEEN @StartDate AND @EndDate";

var sqlCommand = new SqlCommand(cmdText, connection);
sqlCommand.Parameters.AddWithValue("@StartDate", dateTimePicker1.Value);
sqlCommand.Parameters.AddWithValue("@EndDate", dateTimePicker2.Value);

connection 是你的 sql 连接对象。

【讨论】:

  • Checked 不是 DateTime 属性。
  • 该代码不使用 Checked 属性,您也不应该使用 @user3185569。只需使用该值 - 它是 DateTime 类型
  • @user3185569 为此我将其更改为Value。谢谢
  • @Plutonix 我认为用户在我发表评论后编辑了答案。很抱歉。
  • @Plutonix 我忘记了 :) 我想说把它改成AddWithValue。非常感谢您指出这一点!
【解决方案2】:

Checked 是一个布尔属性,它不是日期。您需要使用 Value 属性。最好加上参数,明确指定类型,这样才能解决日期格式冲突。

编辑:如果 SQL server 中的列类型为NVARCHAR,格式为MM/dd/yyyy,则需要使用ONVERT(DATETIME, leaving_time, 101)

conn.Open();
SqlDataAdapter dataAdapter = 
    new SqlDataAdapter("SELECT name, mil_no, rotba, arrival_time, leaving_time, day, year "
                     + "FROM dbo.Hodor_data where CONVERT(DATETIME, leaving_time, 101) "
                     + "BETWEEN @p1 AND @p2", conn);

SqlParameter fromDate = new SqlParameter("@p1", SqlDbType.DateTime2);
fromDate.Value = dateTimePicker1.Value;
SqlParameter toDate = new SqlParameter("@p2", SqlDbType.DateTime2);
toDate.Value = dateTimePicker2.Value;

dataAdapter.SelectCommand.Parameters.Add(fromDate);
dataAdapter.SelectCommand.Parameters.Add(toDate);

DataTable dt = new DataTable();
dataAdapter.Fill(dt);
dataGridView1.DataSource = dt; 
conn.Close()

您确实应该考虑将列 leaving_time 的类型更改为 DateTime 列。这将使您的查询生活更轻松。我真的看不出将这些值存储为文本有什么好处。

【讨论】:

  • @amrkamal 你能展示整个代码吗?这就是您执行查询和构建命令对象的方式。
  • conn.Open(); SqlDataAdapter dataAdapter = new SqlDataAdapter("SELECT name, mil_no, rotba,arrival_time, leave_time, day, year FROM dbo.Hodor_data where leave_time BETWEEN '" + dateTimePicker1.Value + "' AND '" + dateTimePicker2.Value.ToString("") + "'", 连接);数据表 dt = 新数据表(); dataAdapter.Fill(dt); dataGridView1.DataSource = dt; conn.Close();
  • 当前上下文中不存在名称“dateParamFrom”!!
  • @amrkamal 如果您的列类型是 nvarchar,它将不起作用。您可以显示该列的示例值吗?是 2016-07-09 还是 09-07-2016
  • @amrkamal 错字已在答案中修复。
【解决方案3】:

尝试在dateTimePicker1_ValueChanged 事件中使用dateTimePicker1.Text,而您使用dateTimePicker2.Checked 返回truefalse 而不是日期的值

【讨论】:

    猜你喜欢
    • 2021-04-18
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 2015-03-12
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多