ユーザー提供のデータを使用してSQLステートメントを作成しようとしています。私はこれに似たコードをC#で使用します。
var sql = "INSERT INTO myTable (myField1, myField2) " +
"VALUES ('" + someVariable + "', '" + someTextBox.Text + "');";
var cmd = new SqlCommand(sql, myDbConnection);
cmd.ExecuteNonQuery();
そしてこれはVB.NETで:
Dim sql = "INSERT INTO myTable (myField1, myField2) " &
"VALUES ('" & someVariable & "', '" & someTextBox.Text & "');"
Dim cmd As New SqlCommand(sql, myDbConnection)
cmd.ExecuteNonQuery()
しかしながら、
O'Brien
)、「正しい方法」でそれを行うにはどうすればよいですか?
パラメータ化されたSQLを使用します。
例
(これらの例は、C#にあります 以下を参照 VB.NETバージョンの場合)。
文字列の連結を@...
プレースホルダーに置き換え、その後、値をSqlCommandに追加します。プレースホルダーの名前は自由に選択できますが、@
記号で始まることを確認してください。あなたの例は次のようになります:
var sql = "INSERT INTO myTable (myField1, myField2) " +
"VALUES (@someValue, @someOtherValue);";
using (var cmd = new SqlCommand(sql, myDbConnection))
{
cmd.Parameters.AddWithValue("@someValue", someVariable);
cmd.Parameters.AddWithValue("@someOtherValue", someTextBox.Text);
cmd.ExecuteNonQuery();
}
同じパターンが他の種類のSQLステートメントにも使用されます。
var sql = "UPDATE myTable SET myField1 = @newValue WHERE myField2 = @someValue;";
// see above, same as INSERT
または
var sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = @someValue;";
using (var cmd = new SqlCommand(sql, myDbConnection))
{
cmd.Parameters.AddWithValue("@someValue", someVariable);
using (var reader = cmd.ExecuteReader())
{
...
}
// Alternatively: object result = cmd.ExecuteScalar();
// if you are only interested in one value of one row.
}
注意事項:AddWithValue
は出発点として最適で、ほとんどの場合問題なく機能します。ただし、渡す値は、対応するデータベースフィールドのデータ型と正確に一致する必要があります。そうしないと、変換によってクエリが インデックスを使用 できなくなる可能性があります。 char/varchar(「n」を前に付けない)や日付などの一部のSQL Serverデータ型には、対応する.NETデータ型がないことに注意してください。そのような場合は、正しいデータ型の Add
を代わりに使用する必要があります 。
なぜそれをする必要があるのですか?
より安全です :停止します SQLインジェクション 。 ( Bobby Tablesは学生の記録を削除しません。 )
簡単です。一重引用符や二重引用符をいじったり、日付リテラルの正しい文字列表現を調べたりする必要はありません。
より安定しています:O'Brien
は、奇妙な名前を維持することを強く求めているからといって、アプリケーションをクラッシュさせません。
その他のデータベースアクセスライブラリ
SqlCommandの代わりにOleDbCommandを使用する場合(たとえば、MS Accessデータベースを使用している場合)、SQLのプレースホルダーとして?
ではなく@...
を使用します。その場合、AddWithValue
の最初のパラメーターは無関係です。代わりに、正しい順序でパラメーターを追加する必要があります。 同じことがOdbcCommandにも当てはまります 。
これは、Option Strict On
とOption Infer On
を想定した vb.net の wiki answer のサンプルコードです。
[〜#〜]挿入[〜#〜]
Dim sql = "INSERT INTO myTable (myField1, myField2) " &
"VALUES (@someValue, @someOtherValue);"
Using cmd As New SqlCommand(sql, myDbConnection)
cmd.Parameters.AddWithValue("@someValue", someVariable)
cmd.Parameters.AddWithValue("@someOtherValue", someTextBox.Text)
cmd.ExecuteNonQuery()
End Using
[〜#〜]更新[〜#〜]
Dim sql = "UPDATE myTable SET myField1 = @newValue WHERE myField2 = @someValue;"
' see above, same as INSERT
[〜#〜]選択[〜#〜]
Dim sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = @someValue;"
Using cmd As New SqlCommand(sql, myDbConnection)
cmd.Parameters.AddWithValue("@someValue", someVariable)
Using reader = cmd.ExecuteReader()
' ...
End Using
' Alternatively: Dim result = cmd.ExecuteScalar()
' if you are only interested in one value of one row.
End Using