【问题标题】:SQL statement with datetimepicker带有日期时间选择器的 SQL 语句
【发布时间】:2010-11-26 23:51:30
【问题描述】:

这应该是一个简单的。在 windows 窗体中使用日期时间选择器时,我希望执行一条 SQL 语句,如下所示:

string sql = "SELECT * FROM Jobs WHERE JobDate = '" + dtpJobDate.Text + "'";

不幸的是,这实际上并没有提供任何结果,因为 JobDate 字段存储为 DateTime 值。我希望能够搜索该日期的所有记录,无论存储的时间是多少,有什么帮助吗?

新查询:

        SqlDataAdapter da2 = new SqlDataAdapter();
        SqlCommand cmd = new SqlCommand();
        cmd.CommandText = "SELECT * FROM Jobs WHERE JobDate >= @p_StartDate AND JobDate < @p_EndDate";
        cmd.Parameters.Add ("@p_StartDate", SqlDbType.DateTime).Value = dtpJobDate.Value.Date;
        cmd.Parameters.Add ("@p_EndDate", SqlDbType.DateTime).Value = dtpJobDate.Value.Date.AddDays(1);
        cmd.Connection = conn;
        da2.SelectCommand = cmd;
        da2.Fill(dt);
        dgvJobDiary.DataSource = dt;

非常感谢您的帮助!

【问题讨论】:

  • 我猜是DateTimePicker的Text属性和控件的当前日期没有关联

标签: c# sql winforms datetime datetimepicker


【解决方案1】:

只有一个答案:使用parametrized queries

这是出于不同的原因:

  • 安全性(SQL Injection 无风险
  • 不再是您打开主题的那些问题
  • 性能。

因此,这样写你的陈述:

SqlCommand cmd = new SqlCommand();
cmd.CommandText = "SELECT * FROM Jobs WHERE JobDate = @p_Date"
cmd.Parameters.Add ("@p_Date", SqlDbType.DateTime).Value = dtpJobDate.Value;

如果你想忽略时间,那么我认为最好的办法是进行范围搜索,如果时间存储在DB中,那就是。 像这样的东西(只是 SQL 查询):

SELECT * FROM Jobs WHERE JobDate >= @p_StartDate AND JobDate < @p_EndDate

StartDate 将是 dtpJobDate.Value.Date,而 EndDate 将是 dtpJobDate.Value.Date.AddDays(1)

如果时间没有存储在数据库中,那么你可以这样做:

SELECT * FROM Jobs WHERE JobDate = @p_Date

搜索参数应该是dtpJobDate.Value.Date

【讨论】:

  • +1:参数化查询的存在是有原因的。而且它们不是可以被忽略的:)
  • 这看起来非常好,我想使用它,但我不知道从哪里开始。通常我会用 sql 查询填充一个新的数据适配器,我该怎么做呢?
  • DataAdapter 有一个“SelectCommand”属性,您可以为其分配一个 IDbCommand。 (如果你使用 Sql Server:一个 SqlCommand)。 SqlDataAdapter 适配器 = new SqlDataAdapter(); SqlCommand cmd = new SqlCommand(); cmd.CommandText = "选择..."; cmd.参数。 .... 适配器.SelectCommand = cmd;
  • 嗯……好像少了点什么。请检查我上面的编辑,我错过了什么吗?
  • 是的:你的参数名称不好。您查询的参数称为 p_StartDate 和 p_EndDate。但是,您正在将参数添加到称为 'p_Date' 的参数集合中。参数名称必须匹配,因此您必须添加一个 p_StartDate 参数和一个 p_EndDate 参数。
【解决方案2】:

试试 dtpJobDate.Value。

【讨论】:

    【解决方案3】:

    除了其他答案中的 SQL 注入之外,您可以使用以下内容:

    dtpJobDate.Value.ToString("yyyyMMdd HH:mm:ss");
    

    但您可能找不到任何与精确时间匹配的内容,因此您可以将查询更改为类似

    string sql = "SELECT * FROM Jobs WHERE JobDate BETWEEN '" + dtpJobDateStart.Value.ToString("yyyyMMdd HH:mm:ss") + "' AND '" + + dtpJobDateEnd.Value.ToString("yyyyMMdd HH:mm:ss") + " + "'";
    

    【讨论】:

    • 似乎它应该可以工作,但这个并没有真正发生任何事情。试图让参数在上面工作。
    • 这是你最好的选择......无论如何,考虑到 DateTimePickers 的时间值被包含在这个 sql 查询中,所以你想把 DateTimePickers 的格式设置为 Long 或自定义
    【解决方案4】:

    首先 - 在您的示例中,您为 SQL 注入打开了大门。

    除此之外 - 要回答您的问题,您必须从 JobDate 列中删除时间以完成匹配。尝试这样的事情(示例中留下的 SQL 注入代码用于比较)...

    string sql = "SELECT * FROM Jobs WHERE CAST(CONVERT(CHAR(8), JobDate, 112) AS DATETIME) = '" + dtpJobDate.Text + "'";
    

    如果你要参数化你的查询 - 你可以这样做......

    using (var conn = new SqlConnection(myConnectionString))
    using (var cmd = new SqlCommand("SELECT * FROM Jobs WHERE JobDate = @JobDate", conn))
    {
        cmd.Parameters.Add(new SqlParameter("@JobDate", dtpJobDate.Value));
    
        conn.Open();
        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                // your code here to deal with the records...
            }
        }
    }
    

    【讨论】:

    • 我猜是DateTimePicker的Text属性和控件的当前日期没有关联
    • 这也不起作用 - 它还产生了一个错误:“将 char 数据类型转换为 datetime 数据类型导致 datetime 值超出范围。”抱歉,我之前没有提到这一点,但我使用的是英国日期系统
    • 大卫,你能告诉我我的解决方案是否对你有帮助吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    相关资源
    最近更新 更多