26

使用するのが最適かどうか、または新しく挿入された行のID列を返したいかどうかをExecuteScalar判断しようとしています。私はこの質問ExecuteNonQueryを読み、そこでの違いを理解していますが、数週間前に書いたコードを見ると(このサイトから多額の借用をしているときに)、挿入物で次のように使用していることがわかりました。ExecuteScalar

public static int SaveTest(Test newTest)
{
    var conn = DbConnect.Connection();
    const string sqlString = "INSERT INTO dbo.Tests ( Tester , Premise ) " +
                             "               VALUES ( @tester , @premise ) " +
                             "SET @newId = SCOPE_IDENTITY(); ";
    using (conn)
    {
        using (var cmd = new SqlCommand(sqlString, conn))
        {
            cmd.Parameters.AddWithValue("@tester", newTest.tester);
            cmd.Parameters.AddWithValue("@premise", newTest.premise);
            cmd.Parameters.Add("@newId", SqlDbType.Int).Direction = ParameterDirection.Output;

            cmd.CommandType = CommandType.Text;
            conn.Open();
            cmd.ExecuteScalar();

            return (int) cmd.Parameters["@newId"].Value;
        }
    }
}

これは私が必要とするものにはうまく機能するので、私は疑問に思っています

  1. ExecuteNonQuery挿入を行うのに「より適切」であるため、ここ で使用する必要があるかどうか。
  2. 出力パラメーターを使用しているので、ID値の取得はどちらの方法でも同じでしょうか?
  3. いずれかの方法に関連するパフォーマンスの影響はありますか?
  4. 一般的に、これを全体的に行うためのより良い方法はありますか?

違いが生じる場合に備えて、Visual Studio 2010、.NET 4.0、およびSQLServer2008r2を使用しています。

4

1 に答える 1

32

Aaronが提案しているように、ストアドプロシージャを使用すると、SQL ServerのSQLバッチのコンパイル作業が節約されるため、処理が高速になります。ただし、次のいずれかのアプローチを使用することもできます:ExecuteScalarまたはExecuteNonQuery。IMHO、それらの間のパフォーマンスの違いは非常に小さいので、どちらの方法も同じように「適切」です。

ExecuteScalarそうは言っても、出力パラメーターからID値を取得する場合に使用する意味はわかりません。その場合、によって返される値はExecuteScalar役に立たなくなります。

ExecuteScalar必要なコードが少なく、出力パラメーターなしで使用するため、私が気に入っているアプローチは次のとおりです。

public static int SaveTest(Test newTest)
{
    var conn = DbConnect.Connection();
    const string sqlString = "INSERT INTO dbo.Tests ( Tester , Premise ) " +
                             "               VALUES ( @tester , @premise ) " +
                             "SELECT SCOPE_IDENTITY()";
    using (conn)
    {
        using (var cmd = new SqlCommand(sqlString, conn))
        {
            cmd.Parameters.AddWithValue("@tester", newTest.tester);
            cmd.Parameters.AddWithValue("@premise", newTest.premise);

            cmd.CommandType = CommandType.Text;
            conn.Open();
            return (int) (decimal) cmd.ExecuteScalar();

        }
    }
}

ハッピープログラミング!

編集:オブジェクトから、、decimalそしてへの2回キャストする必要があることに注意してくださいint(これに注意してくれたtechturtleに感謝します)。

于 2013-01-11T22:51:42.013 に答える