按日期搜索数据库的SQL查询

时间:2013-02-16 14:17:34

标签: c# sql datetime

有人可以建议我使用sql查询来搜索具有特定日期的ms数据库。

例如,我想在第13/02/2013天搜索所有交易。 在我的数据库中,我有一个名为“购买日期”的列,用于存储购买日期。

在数据库中,日期以16/02/2013 02:47:36 AM格式存储。

我希望tom在文本框中输入我想要的日期,然后将该值传递给查询。

 public DataSet OrderByDate(DateTime date)
        {
            //  string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\Amrit\\Desktop\\Database.accdb ;Persist Security Info=False;";
            DataSet dataSet = new DataSet();
            OleDbConnection oleConn = new OleDbConnection(connString);

            try
            {
                oleConn.Open();
                string sql = "SELECT  Customer.[Title] + SPACE(2)  + Customer.[Customer's Name] as CustomerName, Customer.[Customer's Ebayname], Customer.[Email Address], Customer.[Phone Number], Customer.[Address 1] + SPACE(2)  +Customer.[Address 2] + SPACE(2)  + Customer.[City] + SPACE(2)  + Customer.[Post Code]+  SPACE(2)  + Customer.[Country] as Address, Customer.[Item Purchased], Customer.[Purchased Date], Customer.[Total Price] FROM Customer WHERE [Purchased Date]='" + date;
                OleDbDataAdapter dataAdapter = new OleDbDataAdapter(sql, oleConn);
                dataAdapter.Fill(dataSet, "Customer");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            finally
            {
                oleConn.Close();
            }
            if (dataSet.Tables.Count <= 0)
                return null;
            else
                return dataSet;
        }

6 个答案:

答案 0 :(得分:4)

  1. 始终尝试使用原始/正确的数据类型进行查询。在这种情况下 - datetime。
  2. 永远不要将参数连接到SQL中 - 特别是字符串,特别是如果字符串是用户输入。
  3. 以下应该有效:

        public DataSet OrderByDate(DateTime date)
        {
            string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\Amrit\\Desktop\\Database.accdb ;Persist Security Info=False;";
            var dataSet = new DataSet();
    
            using(var oleConn = new OleDbConnection(connString))
            {
                try
                {
                    oleConn.Open();
                    var cmd = oleConn.CreateCommand();
                    cmd.CommandText = "SELECT * FROM Customer WHERE [Purchased Date] BETWEEN :dateStart AND :dateEnd";
                    cmd.Parameters.AddRange(new[]
                        {
                            new OleDbParameter("dateStart", date.Date),
                            new OleDbParameter("dateEnd", date.Date.AddDays(1).AddTicks(-1))
                        }
                        );
    
                    var dataAdapter = new OleDbDataAdapter(cmd);
                    dataAdapter.Fill(dataSet, "Customer");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
            return dataSet.Tables.Count <= 0 ? null : dataSet;
        }
    

    为清晰起见,我删除了那么长的列列表。 据我所知,Oracle期望参数名前面带冒号(:)的参数,而不是SQL Server的'@'。如果以上不起作用尝试使用@或者只是使用?而不是没有名称的参数名称和供应参数。

    “using”部分应该处理关闭连接就好了,即使抛出异常,并且看起来比代码中的finally部分更整洁。

    关于这部分:

                        new OleDbParameter("dateStart", date.Date),
                        new OleDbParameter("dateEnd", date.Date.AddDays(1).AddTicks(-1))
    

    date.Date仅返回日期部分(时间为00:00:00),date.Date.AddDays(1)是下一个日期(时间也是00:00:00),例如2012-02-16 00:00:00和2012-02-17 00:00:00 - 所以恰好24小时 - 一天。如果你愿意,你可以减去一个刻度,但这个想法仍然是一样的。这样我们就可以选择日期在该范围内的所有记录(因此使用BETWEEN)。您可以尝试使用Oracle datetime函数实现相同的功能,但我认为这更短/更清晰。

答案 1 :(得分:1)

您可以使用LIKE运算符进行查询;

string sql = "SELECT  Customer.[Title] + SPACE(2)  + Customer.[Customer's Name] as CustomerName, Customer.[Customer's Ebayname], Customer.[Email Address], Customer.[Phone Number], Customer.[Address 1] + SPACE(2)  +Customer.[Address 2] + SPACE(2)  + Customer.[City] + SPACE(2)  + Customer.[Post Code]+  SPACE(2)  + Customer.[Country] as Address, Customer.[Item Purchased], Customer.[Purchased Date], Customer.[Total Price] FROM Customer WHERE [Purchased Date] LIKE '" + "'" + date "%'";

结果是所有字符串都包含13/02/2013日期,如;

  • 13/02/2013 02:47:36 AM。
  • 13/02/2013 14:24:02 AM

等。

始终在查询中使用 parameterized sql 。这种代码始终对SQL Injection开放。等;

答案 2 :(得分:1)

如果要从where子句中删除time组件,请执行以下操作:

where YourDateField >= @StartDate
and YourDateField < @TheDayAfterTheEndDate

使用问题中的数据,@ StartDate将是2013-02-13,@ TheDayAfterTheEndDate将是2013-02-14。

答案 3 :(得分:0)

理想情况下,为了避免任何类型的“时间”问题,我总是使用日期时的Date属性,无论是在插入/更新数据库还是在读出数据库时。事实上,我写了一些包装代码,以便在时间不重要的列上自动执行此操作。

这确保了在数据库中,插入和更新时的时间总是00:00:00

所以查询(避免任何其他SQL注入/参数化查询问题)

"SELECT * FROM _table WHERE _date = '" + date.Date + "'";

在所有条件相同且知道所有插入也使用.Date的情况下,我们可以不再担心时间。

答案 4 :(得分:0)

不要使用like,你可以使用普通的WHERE子句:

        DateTime start = DateTime.Now.Date; //this will get you 2/16/2013 12:00:00am
        DateTime end = start.AddDays(1); //this will get you 2/17/2013 12:00:00am

        //make sure to parameterize your query like this
        string sql = "SELECT * FROM Product WHERE PurchasedDate >= @start AND PurchasedDAte < @end";
        System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection();
        using (conn)
        {
            System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand(sql, conn);
            System.Data.SqlClient.SqlParameter pmStart = new System.Data.SqlClient.SqlParameter("start", start);
            System.Data.SqlClient.SqlParameter pmEnd = new System.Data.SqlClient.SqlParameter("end", end);
            command.Parameters.Add(pmStart);
            command.Parameters.Add(pmEnd);
        }

答案 5 :(得分:0)

根据MSDN库,您可以使用 DateTime.ToString Method (String) 将datetime对象转换为以明确方式格式化的字符串:

string datestring = date.ToString("yyyyMMdd"); 
string sql = 
  " SELECT ... "
+ " FROM Customer "
+ " WHERE [Purchased Date] >= '" + datestring + "'" 
  + " AND [Purchased Date] < DATEADD(day, 1, '" + datestring + "')" ;

而且我很确定有更好的方法将参数传递给查询字符串,而不是像这样使用引号。例如,请参阅此问题: How to properly sanitize (or parametrize) SQL Compressed Insert Statement