投稿フォームを使用して一部のユーザー データを保存する asp.net アプリケーションがあります。そのために、以下にリストされている簡単なクエリがあります。
"UPDATE myTable SET LastUpdatedOn='"
+ DateTime.UtcNow + "', Completed='1'
WHERE ID='" + requestid + "'"
これは時々失敗します。でもそれで問題ないと思います。では、なぜそうなるのか教えてください。
パラメータ化されたクエリに慣れ、それらを使用してシステムをSQL インジェクション攻撃から保護する必要があります。
using (var cmd = conn.CreateCommand()) {
cmd.CommandText =
"UPDATE myTable SET LastUpdatedOn=@Time, Completed='1' WHERE ID=@Id";
cmd.Parameters.AddWithValue("@Time", DateTime.UtcNow);
cmd.Parameters.AddWithValue("@Id", requestid);
var count = cmd.ExecuteNonQuery();
if (count != 1) {
Console.Error.WriteLine(
"Warning: Cannot update myTable for ID {0}", requestid
);
}
}
追加の利点として、このアプローチにより、考えられるすべてのデータ形式の問題が排除され、SQL Server がクエリ プランをキャッシュできるようになるため、クエリが高速化されます。しかし、主な利点は、世界中の「Bobby Tables」によるシステムへの不正アクセスの試みを阻止することです。
なぜこれが壊れるかは正確にはわかりません。何がうまくいかないのかをよりよく理解するには、テーブルのスキーマを確認する必要があります。別の注意点として、クエリを単に連結するのではなく、パラメータ化されたクエリを使用することをお勧めします。現在のクエリは、入力の送信元によってはSQLインジェクションに対して脆弱である可能性があります。コードを次のようなものに変更して、エラーが軽減されるかどうかを確認してください(これにより、SQLインジェクションのリスクも軽減されます)。
SqlCommand cmd = new SqlCommand("UPDATE myTable SET LastUpdatedOn = @LastUpdatedOn, Completed = @Completed WHERE ID = @RequestId", sqlConnectionObject);
cmd.Parameters.AddWithValue("@LastUpdatedOn", DateTime.UtcNow);
cmd.Parameters.AddWithValue("@Completed", 1);
cmd.Parameters.AddWithValue("@RequestId", requestid);
cmd.ExecuteNonQuery();
DateTime.UtcNow
クエリの日時に解析できない可能性があります。試す:
DateTime.UtcNow.ToString('yyyy-MM-dd hh:mm:ss')
(また、「m」を台無しにしている可能性があるので、再確認してください)
使用する代わりに、使用しているデータベースでSql Sevrerまたは類似の関数DateTime.UtcNow
を使用することを検討してくださいgetdate()
"UPDATE myTable SET LastUpdatedOn= getdate(), Completed='1' WHERE ID='" + requestid + "'"