2017-03-28 57 views
0

我想用複選框搜索我的SQL數據庫。讓我解釋一下:我有幾個複選框,每個複選框都有一個值(列名);用戶應該能夠用複選框選擇要在數據庫中搜索的內容。SQL,使用SELECT選擇複選框C#

通常,它應該是這樣的:

cmd.CommandText = "select regnr, benamning, dimension, profil from verkstad.dackforvaring where regnr like ('%"+ TextBox1.Text +"%')"; 

我要爲regnr一個複選框,一個複選框benamning等。

如果只是regnr的複選框處於活動狀態,那麼搜索應該只用於regnr。 (SELECT checkbox1, checkbox2, checkbox3 FROM etc

可以這樣做,以及如何? :)

+3

https://en.wikipedia.org/wiki/SQL_injection – Jamiec

+0

WHST是'regnr','benamning'執行參數的SqlCommand,傳遞參數值?正如目前所寫,很難確切地說出你在問什麼。請參閱[如何提問](http://stackoverflow.com/help/how-to-ask)頁面以獲得澄清此問題的幫助。 – Marusyk

+0

您希望列成爲搜索條件的一部分嗎?像'在哪裏regnr像'添加%'和像'dfds%'一樣的變形?或者他們應該只是選擇列列表的一部分? –

回答

0

你需要的是動態地建立你的SQL字符串。例如,如果你只是想搜索regnr,因爲這是唯一積極的複選框就可以做到以下幾點:

string sql = "select {0} from verkstad.dackforvaring where regnr like('%@PARAM_1%')"; 

if (checkboxRegnr.Checked) 
    sql = string.Format(sql, "regnr"); 

這僅僅是一個簡單的例子,你需要擴展這個您的需求。

進一步注意,你應該使用DbParameter而不是直接將Textbox1.Text注入到你的sql中。 Jamiec在他的評論中指出,這是一個security lack

2

最簡單的方式來做到這一點是動態建立你的SQL,增加附加條款WHERE和列到你的SELECT。但是,由於您允許將用戶輸入的文本注入到SQL中,因此會暴露SQL注入漏洞,並且您必須擔心可能導致SQL無效的撇號和其他標點符號。

一個更穩定的方式是你的WHERE子句中考慮到任何可能的列:

SELECT regnr, benamning, dimension, profil 
FROM verkstad.dackforvaring where 
    (@regnr  IS NOT NULL AND regnr  LIKE '%' + @regnr  + '%') OR 
    (@benamning IS NOT NULL AND benamning LIKE '%' + @benamning + '%') OR 
    (@dimension IS NOT NULL AND dimension LIKE '%' + @dimension + '%') OR 
    (@profil IS NOT NULL AND profil LIKE '%' + @profil + '%') 

而且通過每個值作爲參數(使用DBNull.Value列的未檢查)。

可以動態的行添加到WHERE條款取決於哪些列進行了檢查,並動態地將列添加到SELECT條款,但這是一般的想法與連接字符串(尤其是輸入值 - 確保這些通過參數添加)。

+0

+1,但您可以動態構建參數化查詢,因此它不一定會將您暴露給SQL注入。畢竟,ORM可能以這種方式動態地構建查詢。關鍵在於,在構建查詢時,使用參數而不是連接來自用戶輸入的字符串。 – Joe

+0

@Joe True - 我還補充說。謝謝。 –

1

編輯:因爲WHERE條款也依賴於檢查checkBoxes,我已經編輯我的答案和擴大Dictionary以包括where子句值。請記住,這是通用解決方案,更適合作爲提示使用,而不是真正的解決方案。


首先,不要使用命令文本字符串連接並瞭解參數化查詢。 關於你的問題,我會建議Dictionary的做法。 使用您的CheckBox名稱作爲鍵和Tuple包含列名稱和文本框作爲值作爲字典。

因此,定義字典是這樣的:

Dictionary<string, Tuple<string, string>> dict = new Dictionary<string, Tuple<string, string>(); 

使用值填充它:

dict.Add(checkBox1.Name, new Tuple<string, string>("regnr", TextBox1.Text)); 
dict.Add(checkBox2.Name, new Tuple<string, string>("benamning", TextBox2.Text)); 
dict.Add(checkBox3.Name, new Tuple<string, string>("dimension", TextBox3.Text)); 
//etc.. 

在你的形式,像這樣得到選中的複選框的名字:

var checkedCheckBoxes = this.Controls.OfType<CheckBox>().Where(cb => cb.Checked).Select(cb => cb.Name); 

現在,從您的字典中找到匹配的列。從該列表中爲selectwhere子句創建列名稱。

List<Tuple<string, string>> columnNames = dict.Where(pair => checkedCheckBoxes.Contains(pair.Key)).Select(pair => pair.Value).ToList(); 
string selectColumnNames = string.Join(", ", columnNames.Select(t => t.Item1).ToArray()); 

string whereClause = ""; 
for (int i = 0; i < columnNames.Count(); i++) 
{ 
    if (i > 0) whereClause +=" and "; 
    whereClause += string.Format("{0} = @{0}", columnNames[i]); 
} 

最後,用這個命令生成文本。

string commandText = string.Format("SELECT {0} FROM erkstad.dackforvaring WHERE {1}", selectColumnNames, whereClause); 

和從Tuple.Item2

SqlCommand cmd = new SqlCommand(); 
cmd.Connection = conn; 
cmd.CommandText = commandText; 

foreach (var columnName in columnNames) 
{ 
    cmd.Parameters.AddWithValue(("@" + columnName.Item1), columnName.Item2); 
} 


var reader = cmd.ExecuteReader(); 
+0

複選框也會影響WHERE子句。 –

+0

@DStanley,好的,我編輯了我的答案,包括哪裏部分... – Nino