我想提出的參數化查詢的SQLQuery可以是這樣的:如何使用ADO.NET/C#進行涉及多個表的參數化查詢?
SELECT * FROM Table1 WHERE Col1 IN (SELECT Col2 FROM Table2 WHERE Col3 IN (1, 2, 3));
的數據來自WS接口,雖然我可以信任的消費者我想發揮它的安全和使用參數化查詢涉及DbParameters防止SQL注入。怎麼做?
謝謝!
我想提出的參數化查詢的SQLQuery可以是這樣的:如何使用ADO.NET/C#進行涉及多個表的參數化查詢?
SELECT * FROM Table1 WHERE Col1 IN (SELECT Col2 FROM Table2 WHERE Col3 IN (1, 2, 3));
的數據來自WS接口,雖然我可以信任的消費者我想發揮它的安全和使用參數化查詢涉及DbParameters防止SQL注入。怎麼做?
謝謝!
正如您所注意的,關鍵點是使用參數。令人討厭的是,IN
子句出了名的問題。現在,如果你知道值均爲整數(例如你正在服用的int[]
參數到C#方法),那麼你可以只是與之類的東西脫身:
cmd.CommandText = "SELECT * FROM Table1 WHERE Col1 IN (SELECT Col2 FROM Table2 WHERE Col3 IN ("
+ string.Join(",", values) + "))"; // please don't!!!
這是可怕的,表明一個非常糟糕的做法(如果有人將其複製爲字符串,則處於痛苦的世界),並且不能使用查詢計劃緩存。您可以做這樣的事情:
var sb = new StringBuilder("SELECT * FROM Table1 WHERE Col1 IN (SELECT Col2 FROM Table2 WHERE Col3 IN (");
int idx = 0;
foreach(var val in values) {
if(idx != 0) sb.Append(',');
sb.Append("@p").Append(idx);
cmd.Parameters.AddWithValue("@p" + idx, val);
idx++
}
sb.Append("))");
cmd.CommandText = sb.ToString();
這是首選的,但尷尬。
或者簡單:與像dapper的工具,讓庫擔心:
var data = conn.Query<YourType>(
"SELECT * FROM Table1 WHERE Col1 IN (SELECT Col2 FROM Table2 WHERE Col3 IN @values)",
new { values });
這裏短小精悍點的使用和「做正確的事」。它也爲您處理「0值」的情況。
謝謝Marc!我很熟悉如何進行參數化查詢。正如我告訴過你的,我只是在想不同的(錯誤的)方式。因此,底線是參數化「第二個查詢」,就像單個表一樣。所以這和我多次做的事情沒有什麼不同。 – 2013-03-08 14:16:18
@matti絕對沒有什麼不同; ADO.NET不關心*命令文本是什麼。您所顯示的具體查詢中唯一有趣的技術點是'IN'子句 - 這是一個真正的PITA來正確參數化。 – 2013-03-08 14:17:24
要檢查出這個小巧玲瓏。看起來不錯! – 2013-03-08 14:24:14
下面是一個例子:
SqlCommand cmd = new SqlCommand("SELECT * FROM Table1 WHERE Col1 IN (SELECT Col2 FROM Table2 WHERE Col3 = @myparam", conn);
//define parameters used in command object
SqlParameter param = new SqlParameter();
param.ParameterName = "@myparam";
param.Value = "myvalue";
//add new parameter to command object
cmd.Parameters.Add(param);
// get data stream
reader = cmd.ExecuteReader();
看看這個鏈接查看更多細節: http://csharp-station.com/Tutorial/AdoDotNet/Lesson06
謝謝!我在想,我必須爲每個值創建一個DbParameter,例如:SELECT * FROM TABLE1 WHERE Col1 IN(@Params),它反過來將具有Status-es的參數。 – 2013-03-08 14:05:29
的困難在這裏被參數化每個單獨IN子句,這樣就可以通過ID的變量數。
看一看這個有用的物品作爲一種方法來解決這個問題:http://www.mikesdotnetting.com/Article/116/Parameterized-IN-clauses-with-ADO.NET-and-LINQ
基本上,它涉及字符串操作的一點點建立IN子句的參數列表,這樣就結束了一個對於具有3個ID的特定示例,SQL語句如下所示:
select * from TABLE1 where COL1 in (select COL2 from TABLE2 where COL3 IN (@p1, @p2, @p3));
謝謝。我製作了自動處理IN的代碼。然而,我在想,是否有可能參數化SELECT * FROM TABLE1 WHERE Col1 IN(@Params),這反過來會以某種方式爲Status-es提供參數。也許這只是愚蠢的。 – 2013-03-08 14:11:56
你可以使用存儲過程嗎? – Ankit 2013-03-08 13:40:08
@Ankit:不,我不能。我必須使現有的代碼來處理依賴於另一個表的條件,並且使用存儲過程將會發生太大的變化。 – 2013-03-08 13:43:03
你有這樣的代碼嗎? – 2013-03-08 13:45:46