![](/img/trans.png)
[英]SqlCommand.Parameters.Add NOT substituting into Command Text
[英]Why does String.Format work but SqlCommand.Parameters.Add not?
我有一個Project
表,有兩列 - ProjectId
和ProjectName
- 我正在編寫一個函數來構造和執行一個SqlCommand
來查詢數據庫中具有給定名稱的Project的id。 此命令有效,但容易受到SQL注入 :
string sqlCommand = String.Format("SELECT {0} FROM {1} WHERE {2} = {3}",
attributeParam, tableParam, idParam, surroundWithSingleQuotes(idValue));
SqlCommand command = new SqlCommand(sqlCommand, sqlDbConnection);
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
DataTable attributes = new DataTable();
adapter.Fill(attributes);
...
}
attributeParam
, tableParam
, idParam
和idValue
都是字符串。 例如,它們可能分別是"ProjectId"
, "Project"
, "ProjectName"
和"MyFirstProject"
。 surroundWithSingleQuotes
用''
包圍一個字符串,所以surroundWithSingleQuotes(idValue) == "'MyFirstProject'"
。 我試圖盡可能地編寫這個函數,因為我可能希望將來從表中獲取所有給定的屬性。
雖然上面的String.Format工作,但這不是:
string sqlCommand = String.Format("SELECT @attributeparam FROM {0} WHERE " +
"@idparam = @idvalue", tableParam);
command.Parameters.Add(new SqlParameter("@attributeparam", attributeParam));
command.Parameters.Add(new SqlParameter("@idparam", idParam));
command.Parameters.Add(new SqlParameter("@idvalue",
surroundWithSingleQuotes(idValue)));
SqlCommand command = new SqlCommand(sqlCommand, sqlDbConnection);
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
DataTable attributes = new DataTable();
adapter.Fill(attributes);
...
}
我不知道為什么。 我沒有收到錯誤消息,但是當我使用SqlDataAdapter
填充我的DataTable
,DataTable什么都不包含。 以下是我采取的各種方法,但無濟於事:
AddWithValue
或使用Parameters.Add
和SqlParameter.Value
。 String.Format
{0}
, {1}
, {2}
和{3}
。 在我的代碼的其他地方,我使用參數化查詢(雖然只有一個參數)沒問題。
基本上,SQL中的參數僅適用於值 - 而不是列或表的標識符。 在您的示例中,只有final參數表示值。
如果您需要在列名和表名方面保持動態,則需要自己構建SQL的那一部分。 對於與SQL注入攻擊相關的所有正常原因, 要非常小心 。 理想情況下,只允許表和列值的已知白名單。 如果您需要更一般,我建議執行非常嚴格的驗證,並引用標識符以避免與關鍵字沖突(或完全禁止那些關鍵字)。
當然,繼續使用SQL參數作為值。
這是一個有效的語句: SELECT * FROM SomeTable WHERE SomeColumn=@param
而這不是: SELECT * FROM @param
這意味着您可以使用值的參數,而不是表名,視圖名,列名等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.