2011-12-12 51 views
3

什麼是處理動態sql參數的好方法?如何處理動態sql參數

我有一個搜索表單,需要大量不同的搜索參數。如果參數爲空,並且我在sql字符串中有參數,它是否會使查詢變慢或減慢查詢速度?

+0

您不能動態構建SQL字符串嗎? –

+0

我認爲在應用程序中構建查詢比使用'where'子句執行這些檢查花費更多。在應用程序上執行此操作時,必須評估和檢查所有可能參數的值並執行邏輯以創建適當的查詢,並且根據數據庫,您更願意擁有對性能的靜態查詢(執行計劃等) – MilkyWayJoe

回答

13

根據具體實施,我們有這個問題兩種常用的方法:

1)在代碼中動態構建SQL查詢的過濾語句,跳過任何空的參數。如果允許用戶爲單個列選擇多個值(即選擇50個狀態中的0個或更多個來過濾數據),這是最好的方法。

例如:

假設txtCondition1和txtCondition2是文本框:

 // Assuming conn is an open SqlConnection 

     System.Text.StringBuilder sbSQL = new StringBuilder(500); 

     List<SqlParameter> cParameters = new List<SqlParameter>(); 

     // Add a default condition of 1=1 so that all subsequent conditions can be added 
     // with AND instead of having to check to see whether or not any other conditions 
     // were added before adding AND. 
     sbSQL.Append("SELECT * FROM MyTestTable WHERE 1 = 1 "); 

     if (!String.IsNullOrEmpty(txtCondition1.Text)) { 
      sbSQL.Append(" AND Column1 = @Column1"); 
      cParameters.Add(new SqlParameter("@Column1", txtCondition1.Text)); 
     } 
     if (!String.IsNullOrEmpty(txtCondition1.Text)) 
     { 
      sbSQL.Append(" AND Column2 = @Column2"); 
      cParameters.Add(new SqlParameter("@Column2", txtCondition2.Text)); 
     } 

     SqlCommand oCommand = new SqlCommand(sbSQL.ToString, conn); 
     if (cParameters.Count != 0) 
     { 
      oCommand.Parameters.AddRange(cParameters.ToArray()); 
     } 

     // Do something with oCommand 

2)如果數值更多的限制,我們通常將它們傳遞到一個存儲過程,它負責確定是否不是通過測試「空白」參數來評估值,無論是空字符串還是空字符串,數字爲0等。

+0

我將如何防止動態創建的搜索filer語句上的sql注入? – chobo

+1

兩種方式:1)沒有什麼能阻止你在動態SQL語句中使用參數,這肯定有幫助; 2)您必須檢查的唯一值是用戶可以輸入自由格式文本的值。我們處理這個問題的方法是將所有單引號加倍,並用空格替換所有嵌入的分號。 –

+0

你能提供一個簡單的例子,用sql參數指向1嗎?這就是我想嘗試工作 – chobo

2

可以做的事情之一是檢查參數是否傳遞給您的存儲過程。你可以這樣說:

create procedure my_procedure (
    @param1 as int = null 
    @param2 as int = null 
) as 
begin 

    select field1, field2, fieldn 
    from table 
    where ((@param1 is null) or (field2 = @param1)) 
     and ((@param2 is null) or (field2 = @param2)) 
end 

我寧願做這個SQL過程比應用壽

+0

有一件事可能會回來咬你,T-SQL不會使'OR'子句短路。如果你用一個不喜歡NULL值的函數(如幾個全文搜索操作符)「或」它,你會得到一個錯誤。 –

+0

的確如此。我沒有包含任何邏輯來處理這個示例,但是我通常會做的是在調用任何查詢之前處理所有參數。因此,上面的選擇缺少邏輯來檢查所有可能的問題,並將params重新分配給安全值。 – MilkyWayJoe