Может фильтровать дату, но не может фильтровать дату и время? - PullRequest
2 голосов
/ 28 марта 2012

У меня есть приложение, которое может фильтровать представление данных на основе даты, используя datetimepicker.Столбец «date» в моей базе данных является типом данных datetime, следовательно, он будет содержать дату и время, сохраненные в нем, но есть некоторые данные, которые имеют только даты.Моя проблема в том, что мой фильтр datetimepicker может фильтровать только те данные с датой = 12:00:00 AM.Те данные, которые содержат другое время, не могут быть отфильтрованы, когда я выбрал дату, используя datatimepicker.Я не знаю в чем проблема.Вот мой код:

public trackInput()
    {
        InitializeComponent();
        dataGridView1.Visible = false;
        webBrowser1.Location = new Point(12, 141);
    }

    /*private void trackInput_Load(object sender, EventArgs e)
    {
        // TODO: This line of code loads data into the 'trackingBMSDATADataSet.BRDATA' table. You can move, or remove it, as needed.
        this.bRDATATableAdapter.Fill(this.trackingBMSDATADataSet.BRDATA);

    }*/
    private void trackBtn_Click(object sender, EventArgs e)
    {

        dataGridView1.Visible = true;
        if (dataGridView1.Visible == true)
        {
            webBrowser1.Location = new Point(12, 397);
        }
        //DataTable dt = null;
        string connoInput = textBox1.Text;
        string conString = Properties.Settings.Default.BMSDATAConnectionString;
        using (SqlCeConnection con = new SqlCeConnection(@"Data Source=C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\TrackCon\TrackCon\BMSDATA.sdf;Persist Security Info = True;Password=Gdex123$"))
        {

                string Ids = "conno= '" + System.Text.RegularExpressions.Regex.Replace(textBox1.Text.Trim(), @"\s*\n\s*", "' OR conno= '") + "'";
                SqlCeCommand com = new SqlCeCommand("SELECT conno,cmpsno,ctrx,dsysdate,cstnno,corigin FROM BRDATA WHERE " +Ids, con);
                SqlCeDataAdapter adap = new SqlCeDataAdapter(com);
                DataSet set = new DataSet();
                adap.Fill(set);
                if (set.Tables.Count > 0)
                {
                    bRDATABindingSource1.DataSource = set.Tables[0];
                }
                bRDATABindingSource1.Filter = null;
                dataGridView1.DataSource = bRDATABindingSource1;
                con.Close();
        }
    }

    private void trackMPSbtn_Click(object sender, EventArgs e)
    {
        dataGridView1.Visible = true;
        if (dataGridView1.Visible == true)
        {
            webBrowser1.Location = new Point(12, 397);
        }
        //DataTable dt = null;
        //string connoInput = textBox1.Text;
        string conString = Properties.Settings.Default.BMSDATAConnectionString;
        using (SqlCeConnection con = new SqlCeConnection(@"Data Source=C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\TrackCon\TrackCon\BMSDATA.sdf;Persist Security Info = True;Password=Gdex123$"))
        {
            dataGridView1.DataSource = bRDATABindingSource1;
            string Ids = "cmpsno= '" + System.Text.RegularExpressions.Regex.Replace(textBox2.Text.Trim(), @"\s*\n\s*", "' OR cmpsno= '") + "'";
            con.Open();
            SqlCeCommand com = new SqlCeCommand("SELECT conno,cmpsno,ctrx,dsysdate,cstnno,corigin FROM BRDATA WHERE " + Ids, con);
            SqlCeDataAdapter adap = new SqlCeDataAdapter(com);
            DataSet set = new DataSet();
            adap.Fill(set);
            if (set.Tables.Count > 0)
            {
                bRDATABindingSource1.DataSource = set.Tables[0];
            }
            bRDATABindingSource1.Filter = null;
            dataGridView1.DataSource = bRDATABindingSource1;
            con.Close();
        }
    }

    private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
    {
        bRDATABindingSource1.Filter = string.Format("dsysdate = #{0:d/M/yyyy HH:mm tt}#", dateTimePicker1.Value.ToLongDateString());
    }

Ответы [ 2 ]

3 голосов
/ 28 марта 2012

DateTimePicker имеет свойство Value, которое содержит выбранную дату.Эту дату следует использовать для формирования запроса, который выглядит следующим образом:

where somedate >= datetimepicker.Value.Date 
  and somedate < datetimepicker.Value.Date.AddDays(1)

, где .Date возвращает только часть даты DateTime.Чтобы подготовить предложение where, замените where часть SqlCeCommand на

" where conno >= @startDate and conno < @endDate"

Добавьте два параметра в SqlCeCommand

com.Parameters.Add (new SqlCeParameter("@startDate", SqlDbType.DateTime, 
                    textbox1.Value.Date));
com.Parameters.Add (new SqlCeParameter("@endDate", SqlDbType.DateTime, 
                    textbox1.Value.Date.AddDays(1)));

и выполните аналогичное упражнение с cmpsno.

ОБНОВЛЕНИЕ: Я полностью пропустил последний метод.

private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
    {
        bRDATABindingSource1.Filter = string.Format("dsysdate >= '{0:yyyy-MM-dd}' AND dsysdate < '{1:yyyy-MM-dd}'", dateTimePicker1.Value, dateTimePicker1.Value.AddDays(1));
    }

Попытка объяснения:

Поскольку dsysdate имеет компонент времени, вам нужно отфильтровать интервал, начиная св полночь и до полуночи следующего дня - это Value.AddDays (1).К сожалению, я не знаю много о фильтрации BindingSource, потому что я в основном фильтрую на уровне базы данных, отсюда первый код.Возможно, вы захотите переписать dateTimePicker1_ValueChanged для получения данных из базы данных вместо фильтрации в памяти;это будет окупаться при работе с большими таблицами из-за индексов.

Говоря об этом, вы могли бы рассмотреть структурирование вашего кода по-другому.Такая задача обычно выполняется методом, который проверяет элементы управления фильтрацией, создает запрос и выполняет его, тем самым устраняя дублирующийся код и позволяя выполнять фильтрацию по нескольким критериям одновременно.Метод, который вызывается при изменении содержимого элемента управления фильтрацией.

0 голосов
/ 28 марта 2012

Я должен сделать несколько комментариев:

1-й: никогда не составлять запросы, объединяющие тексты.Это подвержено внедрению SQL, даже если вы пытаетесь очистить ввод.Вместо этого используйте хранимые процедуры или параметризованные запросы: они полностью защищены от внедрения SQL.

2-й: используйте параметры, потому что вы можете просто передавать значения в исходном виде, не преобразовывая их в текст.Это удалит часть проблемы.Вы можете использовать хранимые процедуры или параметризованные запросы.

2nd & 1/2: есть другие причины для использования параметров, которые связаны с производительностью.

3rd: возможно, фильтрация по дате и времени будетфункционировать, но вы не можете в этом убедиться.Хотите ли вы, чтобы пользователь мог выполнять фильтрацию по точной дате и времени, включая секунды и доли секунд?Я думаю, что это не очень хорошая идея.Пожалуйста, измените дизайн или объясните, что вы хотите сделать.Похоже, это не имеет особого смысла.Возможно, вам следует «округлить» дату до секунд или минут, прежде чем сохранять ее в БД.Вы должны учитывать, что дата и время не являются точными.Он работает как поплавок, поэтому вы можете без проблем сравнивать эти значения.Тем не менее, я жду ваших комментариев, чтобы помочь вам улучшить ваш дизайн.

ДОБАВЛЕНО: Поскольку вы говорите, что часть времени не важна, вы можете удалить ее при вставке или при сравнении (сравнивая столбец datetime спараметр), используя этот «трюк»:

SELECT (CAST(FLOOR(CAST(YourDateTimeColumn as FLOAT)) AS DateTime))

Даты хранятся внутри, как числа дней от базовой даты.Десятичная часть представляет часть дня (чч: мм: сс ...).Таким образом, если вы избавляетесь от десятичной дроби, вы сохраняете только часть даты и можете спокойно сравнивать ее с заданной датой.

Если вам не нужна часть времени: если вы используете SQLВ Server 2008 или более поздней версии вы можете использовать тип DATE для своего столбца (если вам не нужно хранить время).Или вы можете использовать тот же прием при вставке данных в предыдущую версию SQL Server.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...