2013-04-08 31 views
0

我有一個OleDbCommand用於我嘗試實現的插入,以避免SQL注入。在此之前,我用簡單的字符串進行查詢,而我不喜歡那樣。現在,我對插入記錄的代碼看起來是這樣的:找出哪個查詢導致了一個異常

try 
{ 
    OleDbConnection rConn = new OleDbConnection(args[3]); 
    rConn.Open(); 
    using (OleDbCommand insert = new OleDbCommand(String.Format(Globals.QUERY_INSERT_CLICK, args[4]), rConn)) 
    { 
     insert.Parameters.Add("id", OleDbType.BigInt, 20); 
     insert.Parameters.Add("email", OleDbType.VarChar, 255); 
     insert.Parameters.Add("clickTime", OleDbType.Date, 20); 
     insert.Parameters.Add("subscriberId", OleDbType.BigInt, 20); 
     insert.Parameters.Add("link", OleDbType.VarChar, 255); 
     insert.Parameters.Add("sendQueueId", OleDbType.BigInt, 20); 
     insert.Parameters.Add("mailingListName", OleDbType.VarChar, 255); 
     insert.Parameters.Add("newsletterId", OleDbType.BigInt, 20); 
     insert.Parameters.Add("sendDate", OleDbType.Date, 20); 

     insert.Parameters[0].Value = clickitem.Id; 
     insert.Parameters[1].Value = clickitem.Email; 
     insert.Parameters[2].Value = clickitem.ClickTime; 
     insert.Parameters[3].Value = clickitem.SubscriberId; 
     insert.Parameters[4].Value = clickitem.Link; 
     insert.Parameters[5].Value = clickitem.SendQueueId; 
     insert.Parameters[6].Value = mailingListName; 
     insert.Parameters[7].Value = newsletterID; 
     insert.Parameters[8].Value = sendDate; 

     insert.Prepare(); 
     insert.ExecuteNonQuery(); 
    } 
    rConn.Close(); 
} 
catch (OleDbException oldbex) 
{ 
    logger.WriteToLog("GETCLICKS", "OleDbException: " + Globals.ERROR_INSERT_CLICK + oldbex.Message); 
} 
catch (Exception ex) 
{ 
    logger.WriteToLog("GETCLICKS", Globals.ERROR_INSERT_CLICK + ex.Message); 
} 

我有成千上萬刀片和我從我的日誌,其中一些不正確插入看到。例外告訴我,例如不能從bigint轉換爲datetime和類似的東西。雖然我的大部分記錄都正確插入,但我想知道哪些插入查詢確實導致了錯誤。我怎麼弄出來的?

N.B.在使用此方法之前,我有權訪問我的查詢字符串,並立即發現錯誤。現在我想我對SQL注入的免疫力造成了一些困惑

+0

在你的'catch'只是註銷參數,就像你以前註銷你的SQL字符串一樣。 – 2013-04-08 15:10:40

+0

注意,如果'args [4]'可能受到用戶的影響,則此代碼仍然容易受到SQL注入的影響。 – tomfanning 2013-04-08 15:20:01

+0

您可能會發現使用'OleDbParameterCollection.AddWithValue()'可以更輕鬆地進行操作,而不需要您指定參數類型或長度。 http://msdn.microsoft。com/en-us/library/system.data.oledb.oledbparametercollection.addwithvalue(v = vs.100).aspx – tomfanning 2013-04-08 15:21:43

回答

1

由於您提到接收不同/多個數據轉換錯誤,我的建議是在捕獲OleDbException時改進日誌記錄。

您可以在初始'GETCLICKS'日誌條目之後立即將每個參數值寫入日誌。這會給你一個更好的想法,即來自用戶的價值是不正確的格式。

0

參數Value屬性是Object的泛型類型。所以它接受你分配給它的任何東西。當然這不是處理數據的好方法。我將嘗試將該值轉換爲參數的適當數據類型,並避免將虛假值發送到數據庫。這樣一來,你會立刻捕獲錯誤的參數,而不是assignement執行插入

時。例如:

insert.Parameters[2].Value = Convert.ToDateTime(clickitem.ClickTime); 

如果這不是一個有效的datetime它將在Convert.ToDateTime和你失敗會注意到在您的日誌中

1

標準SQL錯誤不會顯示導致錯誤的列或值。

最簡單的方法是將SQL語句和參數值添加到日誌記錄調用中。

string params = string.Join(Environment.NewLine, 
          insert.Parameters 
            .Select(p => string.Format("{0} : {1}", 
                  p.Name, 
                  p.Value)) 
            .ToArray() 
          ); 

string message = string.Format("{0}: {1}{2}\n{3}\n{4}", 
           "OleDbException: " , 
           Globals.ERROR_INSERT_CLICK, 
           oldbex.Message, 
           insert.CommandText, 
           params); 

logger.WriteToLog("GETCLICKS", message); 
-1

困難的方式,但好的設計。我建議你通過繼承Base Exception類來創建你自己的自定義異常類。

創建一個構造函數,它將oledbcomndand作爲輸入參數,然後您可以嘗試通過循環參數集合來記錄OldedbComamnd.CommandText。如下面的SQLcommand示例所示(與OLedbCommand差不多)

或Easy Way - 當引發異常時,將OLDEBCommand.ComamndText寫入日誌。

下面是我爲SQL命令的StoredProcExecutionException創建的示例。你可以完全複製這個OleDbCommand。希望這可以幫助

public StoredProcExecutionException(string message, Exception innerException ,SqlCommand sqlCommand) 
      : base(Convert.ToString(sqlCommand.CommandType ,CultureInfo.InvariantCulture)+" : " 
       + Convert.ToString(sqlCommand.CommandText, CultureInfo.InvariantCulture) 
       + "Failed. " + Convert.ToString(message, CultureInfo.InvariantCulture), innerException) 
     { 
      StringBuilder sb = new StringBuilder(); 

      foreach (SqlParameter param in sqlCommand.Parameters) 
      { 
       if (sb.Length > 0) sb.Append(","); 
       sb.AppendFormat("{0}='{1}'", param.ParameterName, Convert.ToString(param.Value, CultureInfo.InvariantCulture));    
      } 

      StringBuilder sbHeader = new StringBuilder(); 
      sbHeader.AppendLine(String.Format(CultureInfo.InvariantCulture,"{0} :{1} Failed. {2}", sqlCommand.CommandType, sqlCommand.CommandText, message)); 
      sbHeader.AppendFormat("Exec {0} ", sqlCommand.CommandText); 

      sbHeader.Append(sb.ToString()); 

     } 
+0

CommandText將不包含參數值。 – tomfanning 2013-04-08 15:23:07

+0

@tomfanning:好的,對不起,糾正了文字。引發自定義異常因此,在這種情況下,循環遍歷參數集合並記錄值。我想這應該工作。 – dekdev 2013-04-08 15:26:44

相關問題