2

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

例如,我想搜索 2013 年 2 月 13 日的所有交易。在我的数据库中,我有一列称为“购买日期”,它存储了购买日期。

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

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

 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;
        }
4

6 回答 6

4
  1. 始终尝试为您的查询使用原始/正确的数据类型。在这种情况下 - 日期时间。
  2. 永远不要将参数连接到 SQL 中——尤其是字符串,尤其是当字符串是用户输入时。

以下应该工作:

    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 的“@”。如果上述方法不起作用,请尝试使用 @ 或者只是使用 ? 而不是参数名称并提供没有名称的参数。

即使抛出异常,“使用”部分也应该很好地处理关闭连接,并且看起来比代码中的 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 日期时间函数来实现相同的目标,但我相信这更短/更清晰。

于 2013-02-16T15:11:55.890 回答
1

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

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日期;

  • 2013 年 13 月 2 日凌晨 2 点 47 分 36 秒。
  • 13/02/2013 上午 14:24:02

ETC..

并始终parameterized sql在您的查询中使用。这种代码始终对SQL Injection. 喜欢;

于 2013-02-16T14:23:22.963 回答
1

当您想从 where 子句中消除时间组件时,请执行以下操作:

where YourDateField >= @StartDate
and YourDateField < @TheDayAfterTheEndDate

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

于 2013-02-16T14:41:35.127 回答
0

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

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

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

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

一切都是平等的,并且知道所有插入也都使用了.Date,我们就可以不用担心时间了。

于 2013-02-16T14:45:42.817 回答
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);
        }
于 2013-02-16T14:46:00.390 回答
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 proper sanitize (or parametrize) SQL Compressed Insert Statement

于 2013-02-16T15:52:24.500 回答