簡體   English   中英

SQLite 數據庫與 C# 無法比較日期時間數據類型

[英]SQLite database with C# Unable to compare datetime datatype

我正在使用 C# (.NET) 和 SQLite 數據庫。 我在 SQLite 數據庫中有一個表,其中有一列名為“InvoiceDate”。 我選擇了與 TEXT 相同的數據類型(在 db 表中),因為我需要它作為日期時間變量。

我正在使用System.Data.SQLite reference

以下是我遇到問題的命令文本:

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

我需要找到 InvoiceDate 列落在給定日期 date1 和 date2 之間的所有結果。 但問題是,即使我選擇了其他日期,我也得到了結果,例如,即使我選擇了不同的年份,我也得到了相同月份和日期的相同結果。 命令文本有問題,我還需要知道應該在 db 表中選擇什么類型的數據類型。 請讓我知道我應該如何編寫選擇命令。

1.2 日期和時間數據類型

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)

但更重要的是,您應該始終使用參數化查詢 這種字符串連接對SQL 注入攻擊是開放的。

我不是 %100 關於格式,但您可能想使用代表"o"標准格式說明符

.. 使用保留時區信息並發出符合 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));

您可以創建一種方法來轉換您的日期時間

 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());

由於您已選擇將日期作為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")格式說明符來確保將日期正確傳遞到數據庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM