2013-10-10 24 views
1

我試圖實現對SQLite數據庫數據訪問層。我的一個表格包含一個日期時間字段。DATETIMEOFFSET和SQLite

我在將數據插入到這個日期字段出現問題。

cmd.CommandText = string.Format(
         "INSERT INTO Orders(" + 
          "OrderId, " + 
          "Status, " + 
          "CreationTime, " + 
          "LastModification, " + 
          "CreatorName) " + 
         "VALUES(@orderId,@status,@creation,@modification,@creator)"; 
        cmd.Parameters.AddWithValue("@orderId", orderId); 
        cmd.Parameters.AddWithValue("@status", status); 
        cmd.Parameters.AddWithValue("@creation", creationTime); 
        cmd.Parameters.AddWithValue("@modification", lastModificationTime); 
        cmd.Parameters.AddWithValue("@creator", creatorName); 

我創建表:

cmd.CommandText = "CREATE TABLE IF NOT EXISTS Orders(" + 
            "OrderId TEXT PRIMARY KEY NOT NULL, " + 
            "Status TEXT, " + 
            "CreationTime DATETIME, " + 
            "LastModification DATETIME, " + 
            "CreatorName TEXT)"; 
+0

這是一個有點不清楚你問這裏。請編輯你的問題,並發表你的期望是什麼。 –

+0

@neoistheone完成 –

+0

更好地避免轉化完全,並傳遞值作爲參數。更安全,更快 –

回答

3

代替手工創建一個字符串,使用參數化查詢,並添加參數值。正如您發現的那樣,使用String.Format將肯定會導致轉換錯誤,並使您受到SQL注入攻擊。

當您使用值沒有任何轉換傳遞的參數,所以你永遠不必擔心任何轉換錯誤或注入攻擊。大多數數據庫在知道哪些部分可以更改以及從一次執行到下一次執行哪些部分保持不變時,也能夠更好地優化查詢。

在你的情況,你可以使用這樣的事情:

cmd.CommandText= "INSERT INTO Orders(" + 
         "OrderId, " + 
         "Status, " + 
         "CreationTime, " + 
         "LastModification, " + 
         "CreatorName) " + 
        "VALUES (@orderId,@status,@creation,@modification,@creator)"; 
cmd.Parameters.AddWithValue("@orderId",orderId); 
cmd.Parameters.AddWithValue("@status",status); 
cmd.Parameters.AddWithValue("@creation",creation); 
cmd.Parameters.AddWithValue("@modification",modification); 
cmd.Parameters.AddWithValue("@creator",creator); 

題外話 - 爲什麼參數化查詢速度較快

所有服務器都必須分析查詢,瞭解其結構和創建執行計劃運行查詢。該計劃包含要使用的索引,過濾或加入策略,可能需要的臨時結構等。創建此計劃代價昂貴,因此大多數服務器都會緩存它們爲以後使用而創建的計劃。

除非服務器知道在您的查詢其值實際上參數和手工編碼,它不能決定它是否可以使用現有的計劃或創建一個新的,實際上並沒有解析查詢。通過自己指定參數,您可以讓服務器創建更好更可重用的計劃。如果你每秒執行很多查詢,這可能會是一個重大的提升。

更不用說,以原生形式傳遞值比傳遞文本更輕,因此速度更快。

+0

如果我重新使用cmd,我必須調用** cmd.Parameters.Clear(); **。 –

+1

請勿重複使用該命令。創建一個命令很便宜,你爲什麼要「重用」它呢? –

+0

你的代碼在哪裏?假設數據庫確實存在,你是如何創建命令的?執行前是否打開連接? –