0

異なる日付を含む (IDcolumn, int)、(Differencecolumn, int)、および (Datecolumn DateTime) を持つテーブルがあります。

そして、週末を無視して日付の差を計算するメソッド。

    public static double GetBusinessDays(DateTime startD, DateTime endD)
    {
        double calcBusinessDays =
            1 + ((endD - startD).TotalDays * 5 -
            (startD.DayOfWeek - endD.DayOfWeek) * 2) / 7;

        if ((int)endD.DayOfWeek == 6) calcBusinessDays--;
        if ((int)startD.DayOfWeek == 0) calcBusinessDays--;

        return calcBusinessDays;
    }

今日の日付から各 Datecolumn の各 GetBusinessDays 値を取得したいと考えています。そして、それを対応する各 Differencecolumn に挿入します。

例えば

ID  Date        Difference
1   4-22-2013
2   4-23-2013
3   4-24-2013

今日の日付が 2013 年 4 月 28 日であるとします。差には、それぞれ 6、5、4 が含まれている必要があります。

これは私が今のところやったことですが、うまくいきません:(

        myDatabaseConnection.OpenConnection();
        mySqlCommand.CommandType = CommandType.Text;
        mySqlCommand.CommandText = "select * from Table1 where Difference IS Null";
        SqlDataReader sqlreader = mySqlCommand2.ExecuteReader();

        int i;

        while (sqlreader.Read())
        {
            i = sqlreader.GetInt32(0);
            double y = GetBusinessDays(sqlreader.GetDateTime(1), DateTime.Now);
            string commandtext = "Update Table1 SET Difference = " + y + " Where ID = " + i + " ";
            mySqlCommand.CommandText = " " + commandtext + " ";
        }
        myDatabaseConnection.CloseConnection();
4

1 に答える 1

1

何よりもまず、あなたは への呼び出しを見逃しているようmySqlCommand.ExecuteNonQuery()です。whileに割り当てた後、ループ内に移動する必要がありますmySqlCommand.CommandText

また、結果セットを反復処理するときに既存のオブジェクトが使用されるSqlCommandため、Update クエリには別のオブジェクトを使用する必要があります。また、常にパラメータ化された SQLを使用することをお勧めします。この 2 つのポイントをまとめると、次のようになります。SqlDataReader

SqlCommand myUpdateCmd = new SqlCommand("Update [Table1] SET [Difference] = @Difference Where [ID] = @ID", myDatabaseConnection);
myUpdateCmd.Parameters.AddWithValue("@ID", i);
myUpdateCmd.Parameters.AddWithValue("@Difference", (int)y);
myUpdateCmd.ExecuteNonQuery();

さらに、役立つと思われるいくつかの提案を以下に示します。

Difference 列が最初は NULL になると想定しているようですが、Table1 の正確な定義は示していません。Difference 列で NULL 値が許可されていること、およびデフォルト値が設定されていないこと (またはデフォルト値が NULL であること) を確認してください。

列が期待どおりの順序になっていることを保証するには、次のいずれかを実行することをお勧めします。

  1. selectクエリで列名を指定します。

    select [id], [date], [difference] from [Table1] where [difference] is null
    
  2. を介して列の値を取得する場合SqlDataReader、列の序数 (0、1、2、...) をハードコーディングしないでください。代わりに、GetOrdinal()メソッドを使用して、列の序数を動的に決定してください。例えば:

    i = sqlreader.GetInt32(sqlreader.GetOrdinal("id"));
    

これらの ADO.NET オブジェクトのほとんどすべてがIDisposable. usingしたがって、これらのオブジェクトが確実にクリーンアップされるようにするには、C# のステートメントを使用するのが一般的です。

using (SqlConnection myDatabaseConnection = new SqlConnection(myConnectionString))
{
    // code that uses myDatabaseConnection goes here
}

これらのポイントをすべてまとめると、次のようになります。

using (SqlConnection myDatabaseConnection = new SqlConnection("DB connection string goes here"))
{
    myDatabaseConnection.Open();

    using (SqlCommand mySqlCommand = new SqlCommand("select [id], [difference], [date] from [Table1] where [difference] is null", myDatabaseConnection))
    using (SqlDataReader sqlreader = mySqlCommand.ExecuteReader())
    using (SqlCommand myUpdateCmd = new SqlCommand("update [Table1] set [difference] = @difference where [id] = @id", myDatabaseConnection))
    {
        int i;

        myUpdateCmd.Parameters.Add("@id", SqlDbType.Int);
        myUpdateCmd.Parameters.Add("@difference", SqlDbType.Int);

        while (sqlreader.Read())
        {
            i = sqlreader.GetInt32(sqlreader.GetOrdinal("id"));
            double y = GetBusinessDays(sqlreader.GetDateTime(sqlreader.GetOrdinal("date")), DateTime.Now);
            myUpdateCmd.Parameters["@id"].Value = i;
            myUpdateCmd.Parameters["@difference"].Value = (int)y;
            myUpdateCmd.ExecuteNonQuery();
        }
    }
}

更新: Karlx は、アプリケーションが機能する前に、データベース接続で複数のアクティブな結果セットを有効にする必要があると述べました。これを行うには、データベース接続文字列に "MultipleActiveResultSets=True" を追加します。

于 2013-04-27T20:08:25.743 に答える