2012-04-18 28 views
1

ASP.NET 4.0,Web表單,C#,SQL多選項搜索的語法

我幾乎有一些類似於您在約會網站上看到的搜索表單。多個下拉框,每個ddbox都有特定的值以及「任何」值。我想不出一個簡單的方法來創建下面的例子之外這句法有很多否則,如果在後面的按鈕單擊事件的C#代碼語句:

if 
= && = && = 
else if<br/> 
= && = && != 
else if<br/> 
= && != && != 
else if<br/> 
!= && = && != 

...這裏是相同的序列與選定的值

if 
Any && Any && Any 
else if 
Any && Any && Not Any 
else if 
Any && Not Any && Not Any 
else if 
Not Any && Any && Not Any 

這一直持續下去,直到我遍歷所有場景。在按鈕上單擊後面的代碼將採用選定的值並決定執行哪個查詢。導致頭痛的原因是ddbox中的「any」值。有沒有一種首選的方式來構建C#或SQL語法來減少其他if的數量?

讓我知道這是否合理,或者您是否需要更多信息。

+0

如果你想讓數據庫以及時的方式返回結果,在索引使用中有很多注意事項。你的旅程應該開始閱讀:[由Erland Sommarskog在T-SQL中的動態搜索條件](http://www.sommarskog.se/dyn-search.html)。這是一篇SQL Server文章(您似乎在「Microsoft」環境中)。如果您正在追求「通用」SQL來處理任何數據庫,那麼使用「通用」SQL以及像這些搜索一樣可以在您的表增長時獲得良好性能的好運氣。在不知道數據庫的情況下很難調整/優化查詢。 – 2012-04-19 17:30:49

回答

0

首先,我建議在下一個項目中考慮使用ORM,因爲動態SQL在涉及到應用程序設計時有很多這樣的注意事項。

這麼說,我處理這個問題的方法是將任何可選的搜索項在括號內,所以我可以這樣做:

(SomeField =「胡說」 OR 1 = 1)

請記住,我並不是說這是一個好的解決方案,但它確實可以減少嵌套語句的數量,因爲您可以按順序構造SQL語句。

考慮下面的代碼:

SQL = "SELECT CompanyName, CompanyState FROM Companies WHERE "; 
SQL += "(CompanyName = '" & CompanyName & "' " + (CompanyName == "AnyKey" ? " OR 1=1" : "") + ") "; 
SQL += "(CompanyState = '" & CompanyState & "' " + (CompanyState == "AnyKey" ? " OR 1=1" : "") + ") "; 

我再次強調這是不應該被認爲是良好的。我已經轉向ORM,所以我不再有這個問題了。和往常一樣,一定要清理您的用戶輸入。

希望這會有所幫助。

+0

啊好趕上謝謝。 – 2012-04-18 23:27:03

+0

謝謝,我明天還會試試這個,看看它是怎麼回事 - 肯定會看到int ORM! – user1001411 2012-04-18 23:51:05

+0

在工作中,我使用LLBLGen,它做的很好,但我們必須在其周圍實現一個海量的數據層。如果項目很大,研究許多ORM,以及如何在做出決定之前與他們合作 – MilkyWayJoe 2012-04-18 23:56:24

2

我會寫這樣的事:

create procedure usp_search (
    @param1 varchar(50) = null 
    ,@param2 carchar(50) = null 
) as 
begin 
    select field1 
      ,field2 
      ,field3 
      ,fieldN 
     from table t with(nolock) 
    where ((@param1 is null) or (t.fieldX == @param1)) 
     and ((@param2 is null) or (t.fieldY == @param2)) 
end 

那麼你的客戶你不喜歡沿着這些線路......這樣你的搜索查詢可以檢索過濾或未經過濾的結果

//code 
var connection = new SqlConnection("connection_string"); 
var command = new SqlCommand(); 
command.Connection = connection; 
command.CommandText = "usp_Search"; 
command.CommandType = CommandType.StoredProcedure; 
if((string.IsNullOrEmpty(stringVariable1)) || (stringVariable2.ToLower().Equals("any"))) { 
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = DBNull.Value; 
} else { 
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = stringVariable1; 
} 
if((string.IsNullOrEmpty(stringVariable2)) || (stringVariable2.ToLower().Equals("any"))) { 
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = DBNull.Value; 
} else { 
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = stringVariable2; 
} 
// code 

東西..當然,你將不得不注意這種類型的查詢的一些陷阱

編輯:同樣的事情onl y在C#代碼將是這樣的:

var sb = new StringBuilder(); 
sb.Append("select field1 ,field2, field3, fieldN "); 
sb.Append("from table t with(nolock) "); 
sb.Append("where ((@param1 is null) or (t.fieldX == @param1))"); 
sb.Append("and ((@param2 is null) or (t.fieldY == @param2))"); 

var connection = new SqlConnection("connection_string"); 
var command = new SqlCommand(); 
command.Connection = connection; 
command.CommandText = sb.ToString(); 
command.CommandType = CommandType.Text; 
if((string.IsNullOrEmpty(stringVariable1)) || (stringVariable2.ToLower().Equals("any"))) { 
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = DBNull.Value; 
} else { 
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = stringVariable1; 
} 
if((string.IsNullOrEmpty(stringVariable2)) || (stringVariable2.ToLower().Equals("any"))) { 
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = DBNull.Value; 
} else { 
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = stringVariable2; 
} 
+0

謝謝,我會給這個鏡頭。我正在考慮沿着參數線,但不知道如何處理查詢的「任何」功能。明天最有可能去測試這個... – user1001411 2012-04-18 23:49:44

+0

不幸的是,當涉及到過濾時,沒有太多選項,醜陋的'if'語句無處不在,但沿着這些方向的東西應該可以工作。讓我知道。 – MilkyWayJoe 2012-04-18 23:52:59