私は、ProjectId
とProjectName
の2つのカラムを持つProject
テーブルを持っていて、SqlCommand
を構築して実行する関数を書いて、指定された名前のプロジェクトのIDをデータベースに問い合わせます。このコマンドは動作しますが、SQL Injectionに対して脆弱です:なぜString.Formatは機能しますが、SqlCommand.Parameters.Addは機能しませんか?
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には何も含まれません。
- this answerとMicrosoft's documentation後、
AddWithValue
を使用したりParameters.Add
とSqlParameter.Value
を使用して:ここで私は無駄に、撮影した様々なアプローチがあります。 - 選択的に実際の値又はパラメータ文字列のいずれかで
{0}
、{1}
、{2}
、及びString.Format
で{3}
を置き換えます。
私のコードの他の場所では、パラメータ化されたクエリを使用しましたが(パラメータは1つのみ)、問題はありません。
唯一のパラメータは '{3}'です。 –
列の名前にパラメータを使用することはできません。テーブル名の場合と同じように 'string.Format'を使用する必要があります。 – juharr