48

これに関連する質問があります:

パラメータをSQLCommandに渡す最良の方法は何ですか?

しかし、違いが何であるか、そしてさまざまな方法に問題があるかどうかを知りたいです。

私は通常、次のような構造を使用します。

using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(SQL, conn))
{
     cmd.CommandType = CommandType.Text;
     cmd.CommandTimeout = Settings.Default.reportTimeout;
     cmd.Parameters.Add("type", SqlDbType.VarChar, 4).Value = type;

     cmd.Connection.Open();

     using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
     {
         adapter.Fill(ds);
     }
      //use data                    
}

現在、cmd パラメーターを追加する方法はいくつかありますが、どれが最適か疑問に思っています。

cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob";
cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob";
cmd.Parameters.Add("@Name").Value = "Bob";
cmd.Parameters.AddWithValue("@Name", "Bob");

varchars を渡す際にフィールドの長さを持つことは、後でデータベースで変更される可能性がある魔法の値であるため、好ましくありません。これは正しいです?この方法で varchar を渡すと問題が発生しますか (パフォーマンスまたはその他)。デフォルトは varchar(max) またはデータベースと同等であると想定しています。これが機能することをかなり嬉しく思います。

もっと気になる部分は、上記の 3 番目または 4 番目のオプションを使用している場合に SqlDbType 列挙型が失われることです。型をまったく指定していません。これがうまくいかない場合はありますか? varchar が char に誤ってキャストされたり、その逆であるという問題や、10 進数からお金への問題などを想像できます....

データベースに関して言えば、フィールド タイプは長さよりも変更される可能性がはるかに低いので、保持する価値はありますか?

4

2 に答える 2

62

私の経験では、次のことを確実に実行します。

  • パラメータのデータ型を定義するのは自分であることを確認してください。ADO.NET は推測でまともな仕事をしますが、場合によっては、それがひどくオフになる可能性があるため、この方法は避けます。

    cmd.Parameters.Add("@Name").Value = "Bob";
    cmd.Parameters.AddWithValue("@Name", "Bob");
    

    渡された値によって ADO.NET にパラメーターの型を推測させるのは難しい作業です。何らかの理由でそれがオフになっている場合、追跡して見つけるのは非常に難しいバグです。を渡すとどうなるか想像してみてくださいDBNull.Value- ADO.NET はそのためにどのデータ型を選択する必要がありますか?

    明確にしてください - あなたが望むタイプを言ってください!

  • 文字列パラメーターを使用している場合は、長さを明示的に定義してください。そのため、この方法も避けます。

    cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob";
    

    長さを指定しない場合、ADO.NET はデフォルトで任意の値、値として渡された文字列の長さ、またはその他の値になる可能性があります。また、長さがストアド プロシージャが実際に期待するものと一致しない場合は、変換やその他の不愉快な驚きが発生する可能性があります。したがって、文字列を定義する場合は、その長さも定義してください!

したがって、あなたの場合、私にとって本当にうまくいく唯一のアプローチは、これです:

cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob";

a) 使用するデータ型を明示的に定義し、b) 文字列の長さを明示的に定義するためです。

于 2011-01-07T11:10:54.503 に答える
7

タイプを追加すると、キャッシュされたクエリ プランを使用してリクエストのパフォーマンスが向上する可能性が高くなります。

以下は MSDN からの引用です。

パラメーター化されたコマンドは、データベース サーバーが着信コマンドを適切なキャッシュされたクエリ プランと正確に一致させるのに役立つため、クエリ実行のパフォーマンスも向上させることができます。

詳細については、実行計画のキャッシュと再利用を参照してください。

于 2011-01-07T11:15:23.660 に答える