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 值。并将其插入到每个对应的差异列中。

例如

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为更新查询使用一个单独的对象,因为当您遍历结果集时,现有的对象正在被使用SqlDataReader我还建议始终使用参数化 SQL。把这两点放在一起:

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();

除此之外,这里有一些您可能会觉得有帮助的建议:

您似乎假设差异列最初将为 NULL,但您没有显示 Table1 的确切定义。确保差异列允许 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. 因此,通常最好使用 C# 的using语句来保证这些对象将被清除。

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 回答