6

私は通常、SQLを.NETでそのように記述します

sql.Append("SELECT id, code, email FROM mytable WHERE variable = @variable ");

次に、次のようなことを行います。

using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["defaultConnection"]].ConnectionString))
{
    using (SqlCommand myCommand = new SqlCommand(sql.ToString(), conn))
    {
        myCommand.Parameters.AddWithValue("@variable", myVariableName");
        ...

しかし、取得したデータがデータベースから直接取得された場合にも、このaddParameterを実行する必要がありますか?

likesql.Append(string.Format("SELECT group_id, like_text FROM likeTerms ORDER BY group_id ASC "));

DataTable dtLike = SqlHelper.GetDataTable(likesql.ToString());

foreach (DataRow dr in dtLike)
{
    buildsql.Append(".... varId = " + dr["group_id"].ToString() + "...");

    ...

これは受け入れられますか?ベストプラクティスは何ですか?

4

4 に答える 4

17

常にパラメータを使用する必要があります。

  • データベースの値はどこから来ていますか?
  • あなたの例では、「group_id」が予期しないものに変更されていないことを信頼できますか?

誰も信じない

データベースへのアクセスが制限されている人は、他の場所で使用されているフィールドに直接注入できますか?

パフォーマンス

また、パフォーマンスにも役立ちます。キャッシュされた実行プランはパラメーターの値を無視します。つまり、パラメーターが変更されるたびにサーバーがクエリを再コンパイルするのを防ぐことができます。

于 2012-11-20T23:46:07.193 に答える
5

パラメータを指定してDbCommandsを使用する場合、パラメータがクエリに「インライン化」されることはありません。代わりに、クエリとパラメータデータが特別なシステムストアドプロシージャsp_executesqlに渡されます。このように行われると、所有しているパラメータデータはすべてそれとまったく同じように扱われ、クエリ文字列から解析されません。したがって、検証を通過した可能性のある挿入されたコマンドは実行されません。

パラメータの使用は、データの取得元に関係なく、ADO.NETベースのデータアクセスレイヤーのベストプラクティスであり、このレベルで実行する必要がある唯一の方法です(ORMを使用しない場合)。WebフォームまたはWindowsフォームから取得した値をSQLステートメントに連結しないでください。そのルールに従っている場合、情報が直接ではないことに自信がある、または確信しているという理由だけで、なぜ別の方法で実装するのでしょうか。ユーザーから?同じパターンに従い、そのメソッドを公開してユーザー指定のデータを永続化する場合は、書き込みが発生しません。

于 2012-11-20T23:45:20.483 に答える
4

それは許容範囲です(制限を知っている場合は、正しく機能する場合があります)。

データベースの値を使用し、文字列を連結してSQLクエリを作成することをお勧めしますか?いいえ。

つまり、サンプルで「group_id」がの場合はどうなり"'--"ますか?

于 2012-11-20T23:44:55.910 に答える
0

ストアドプロシージャを使用することをお勧めしますが、これは許容されます。クエリに割り当てる前に、パラメータをサニタイズすることもお勧めします。

于 2012-11-20T23:51:34.533 に答える