3
for (int i = 0; i < myClass.Length; i++)
{
        string upSql = "UPDATE CumulativeTable SET EngPosFT = @EngPosFT,EngFTAv=@EngFTAv WHERE RegNumber =@RegNumber AND Session=@Session AND Form=@Form AND Class=@Class";
        SqlCommand cmdB = new SqlCommand(upSql, connection);

        cmdB.CommandTimeout = 980000;

        cmdB.Parameters.AddWithValue("@EngPosFT", Convert.ToInt32(Pos.GetValue(i)));
        cmdB.Parameters.AddWithValue("@RegNumber", myClass.GetValue(i));
        cmdB.Parameters.AddWithValue("@EngFTAv", Math.Round((engtot / arrayCount), 2));
        cmdB.Parameters.AddWithValue("@Session", drpSess.SelectedValue);
        cmdB.Parameters.AddWithValue("@Form", drpForm.SelectedValue);
        cmdB.Parameters.AddWithValue("@Class", drpClass.SelectedValue);


        int idd = Convert.ToInt32(cmdB.ExecuteScalar());
}

これmyClass.Lengthは 60 の更新ステートメントを実行します。更新ステートメントを 1 つに制限するにはどうすればよいですか。上記のコードを使用したコード例をいただければ幸いです。ありがとう

これを使ってみた

StringBuilder コマンド = new StringBuilder();

            SqlCommand cmdB = null;
            for (int i = 0; i < myClass.Length; i++)
            {
                command.Append("UPDATE CumulativeTable SET" + " EngPosFT = " + Convert.ToInt32(Pos.GetValue(i)) + "," + " EngFTAv = " + Math.Round((engtot / arrayCount), 2) +
        " WHERE RegNumber = " + myClass.GetValue(i) + " AND Session= " + drpSess.SelectedValue + " AND Form= " + drpForm.SelectedValue + " AND Class= " + drpClass.SelectedValue + ";");

               //or command.AppendFormat("UPDATE CumulativeTable SET EngPosFT = {0},EngFTAv={1} WHERE RegNumber ={2} AND Session={3} AND Form={4} AND Class={5};", Convert.ToInt32(Pos.GetValue(i)), Math.Round((engtot / arrayCount), 2), myClass.GetValue(i), drpSess.SelectedValue, drpForm.SelectedValue, drpClass.SelectedValue);



            }//max length is 128 error is encountered
4

4 に答える 4

1

BULKINSERTT -SQLコマンドを見てください。しかし、私はそのコマンドについて個人的な経験があまりないので、ループの外側でコマンドとパラメーターを作成し、ループの内側で必要な変更を加えるだけで、同じSQLを使用してこのコードを改善する機会がすぐにあります。 :

string upSql = "UPDATE CumulativeTable SET EngPosFT = @EngPosFT,EngFTAv=@EngFTAv WHERE RegNumber =@RegNumber AND Session=@Session AND Form=@Form AND Class=@Class";
SqlCommand cmdB = new SqlCommand(upSql, connection);

cmdB.CommandTimeout = 980000;

//I had to guess at the sql types you used here. 
//Adjust this to match your actual column data types
cmdB.Parameters.Add("@EngPosFT", SqlDbType.Int);  
cmdB.Parameters.Add("@RegNumber", SqlDbType.Int); 

//It's really better to use explicit types here, too.
//I'll just update the first parameter as an example of how it looks:
cmdB.Parameters.Add("@EngFTAv", SqlDbType.Decimal).Value = Math.Round((engtot / arrayCount), 2));
cmdB.Parameters.AddWithValue("@Session", drpSess.SelectedValue);
cmdB.Parameters.AddWithValue("@Form", drpForm.SelectedValue);
cmdB.Parameters.AddWithValue("@Class", SqlDbTypedrpClass.SelectedValue);

for (int i = 0; i < myClass.Length; i++)
{
    cmdB.Parameters[0].Value = Convert.ToInt32(Pos.GetValue(i)));
    cmdB.Parameters[1].Value = myClass.GetValue(i));

    int idd = Convert.ToInt32(cmdB.ExecuteScalar());
}
于 2012-10-20T21:12:59.683 に答える
1

この場合、Table Valued Parameterを受け入れるストアド プロシージャを作成することをお勧めします。.NET 側では、DataTable使用する値のセットごとに行を含むオブジェクトを作成します。

SQL Server 側では、パラメーターをクエリ内の別のテーブルとして扱うことができます。したがって、ストアド プロシージャ内では、次のようになります。

UPDATE a
SET
    EngPosFT = b.EngPosFT,
    EngFTAv=b.EngFTAv
FROM
    CumulativeTable a
       inner join
    @MyParm b
       on
           a.RegNumber =b.RegNumber AND
           a.Session=b.Session AND
           a.Form=b.Form AND
           a.Class=b.Class

@MyParmテーブル値パラメーターはどこにありますか。

これは、サーバーへの単一のラウンドトリップとして処理されます。

于 2012-10-22T06:53:29.717 に答える
0

このようなシナリオでは、ストアド プロシージャを記述し、そのストアド プロシージャforループで呼び出し、各呼び出しで必要な引数を渡すことが常に最善です。

于 2012-10-22T06:45:06.180 に答える