带有C#的SQLite数据库无法比较datetime数据类型

时间:2016-03-06 15:18:00

标签: c# database sqlite datetime

我正在使用C#(.NET)和SQLite数据库。 我在SQLite数据库中有一个表,其中包含一个名为" InvoiceDate"的列。我选择了数据类型(在db表中)与TEXT相同,因为我需要它作为日期时间变量。

我正在使用command.CommandText = "SELECT * FROM InvoiceMaster WHERE InvoiceDate BETWEEN '" + date1.ToString() + "' AND '" + date2.ToString() + "' ORDER BY InvoiceNumber";

以下是我遇到问题的命令文本:

/Users/apple/Dropbox/PycharmProjects/work

我需要查找列InvoiceDate落在给定日期date1和date2之间的所有结果。但问题是,即使我选择其他日期,我也会得到结果,例如,即使我选择了不同的年份,我也会在同一个月和日期得到相同的结果。命令文本有问题,我还需要知道我应该在db表中选择什么类型的数据类型。请告诉我如何编写select命令。

3 个答案:

答案 0 :(得分:1)

来自1.2 Date and Time Datatype

  

TEXT为ISO8601字符串(" YYYY-MM-DD HH:MM:SS.SSS")

由于ToString()不会生成此类格式,因此您可以使用自定义格式,例如;

date1.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture)
date2.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture)

但更重要的是,您应该始终使用parameterized queries。这种字符串连接对SQL Injection攻击开放。

我不是关于格式的%100,但您可能想要使用代表的The "o" standard format specifier;

  

..使用保留的模式的自定义日期和时间格式字符串   时区信息并发出符合ISO的结果字符串   8601。

command.CommandText = @"SELECT * FROM InvoiceMaster 
                        WHERE InvoiceDate BETWEEN @date1 AND @date2 
                        ORDER BY InvoiceNumber";

command.Parameters.AddWithValue("@date1", date1.ToString("o"));
command.Parameters.AddWithValue("@date2", date1.ToString("o));

答案 1 :(得分:0)

您可以创建转换日期时间的方法

 private string DateTimeSQLite(DateTime datetime)
  {
    string dateTimeFormat = "{0}-{1}-{2} {3}:{4}:{5}.{6}";
    return string.Format(dateTimeFormat, datetime.Year,   
                         datetime.Month,datetime.Day, 
                         datetime.Hour, datetime.Minute,  
                          datetime.Second,datetime.Millisecond);
  }

或更好地使它成为一种扩展方法。

 private static string DateTimeSQLite(this DateTime datetime)
 {}

还使用参数化查询来避免sql注入

string commandText = "SELECT * FROM InvoiceMaster 
                  WHERE InvoiceDate BETWEEN @date1 and @date2
                  ORDER BY InvoiceNumber"
yourcommand.Parameters.Add("@date1",date1.DateTimeSQLite());
yourcommand.Parameters.Add("@date2",date1.DateTimeSQLite());

答案 2 :(得分:0)

由于您已选择将日期存储为数据库中的TEXT字段,因此必须使用ISO8601对其进行格式化。例如:

2016-02-03T20:34:22Z

因此,一旦您确保以这种方式存储它们,剩下的就是参数化您的查询:

DateTime date1 = ... get from somewhere
DateTime date2 = ... get from somewhere

using (var conn = new SQLiteConnection("Data Source=mydb.db;Version=3;"))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "SELECT * FROM InvoiceMaster WHERE InvoiceDate BETWEEN @startDate AND @endDate";
    cmd.Parameters.AddWithValue("@startDate", date1.ToString("o"));
    cmd.Parameters.AddWithValue("@endDate", date2.ToString("o"));
    using (var reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            // do something with the results here
        }
    }
}

请注意我如何使用.ToString("o")格式说明符来确保将日期正确传递到数据库。