我的SQL2000数据库的一个表没有主键,用DataSet很难做到自动同步数据库。原贴地址:http://topic.csdn.net/u/20110723/10/0d9bf468-d6e4-4485-9c7d-5b213cf5cafb.html于是我想用SQLDataReader一条一条的判断记录是否是需要更新的记录,然后用和SQLCommand进行修改。
然而最后用和SQLCommand要进行更新时出现了提示“已有打开的与此连接相关联的 DataReader,必须首先将它关闭。”如果关闭也就不能更新了,不知如何解决。我试看建立两个SQLDataReader,也是不行,请高手指教:using System;
using System.Data;
using System.Data.SqlClient;namespace ConsoleApplication2
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
class Class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序
int i=0;
string myConnectionString="Server=.;database=hq2;uid=sa;pwd=";
string TimeString,CommandTime;
SqlConnection myConnection=new SqlConnection(myConnectionString);
SqlCommand myCommand=myConnection.CreateCommand();
myCommand.CommandText="select ValueID,TimeStamp,RealValue,sn from tag ";

myConnection.Open();
SqlDataReader myDataReader=myCommand.ExecuteReader();            //查看状态
Console.WriteLine("Flag  {0}  \n",myDataReader.Read());
while(myDataReader.Read())
{

if ((int)myDataReader["ValueID"]==14)
{

TimeString=myDataReader["TimeStamp"].ToString();
CommandTime="update tag set sn="+i.ToString() +" where TimeStamp=="+"'"+TimeString+"'" +" and ValueID=14";
myCommand.CommandText=CommandTime; //下面这条语句不能执行,提示“已有打开的与此连接相关联的 DataReader,必须首先将它关闭。”要怎么办呢?怎样才能实现更新?
myCommand.ExecuteNonQuery();

i++;
//查看命令文本
Console.WriteLine("Done! \n {0}",myCommand.CommandText);
}

}
            
myConnection.Close();
myDataReader.Close();
Console.WriteLine(" \n i= {0} \nDone!Press Enter key to exit! \n",i);
Console.Read();
//
}
}
}

解决方案 »

  1.   

    给你改造了一下。using System;
    using System.Data;
    using System.Data.SqlClient;namespace ConsoleApplication2
    {    class Class1
        {
            [STAThread]
            static void Main(string[] args)
            {
                int i = 0;
                string myConnectionString = "Server=.;database=hq2;uid=sa;pwd=";
                string TimeString, CommandTime;
                SqlConnection myConnection = new SqlConnection(myConnectionString);
                myConnection.Open();
                SqlCommand myCommand = myConnection.CreateCommand(); 
                TimeString = "select ValueID,TimeStamp,RealValue,sn from tag ";
                SqlDataAdapter adapter = new SqlDataAdapter(TimeString, myConnection);
                DataSet ds = new DataSet();
                adapter.Fill(ds);
                //查看状态
                Console.WriteLine("Flag {0} \n", ds.Tables[0].Rows.Count);
                if (ds.Tables[0].Rows.Count > 0)
                {
                    foreach (DataRowView drv in ds.Tables[0].DefaultView)
                    {
                        if ((int)drv["ValueID"] == 14)
                        {                        TimeString = drv["TimeStamp"].ToString();
                            CommandTime = "update tag set sn=" + i.ToString() + " where TimeStamp==" + "'" + TimeString + "'" + " and ValueID=14";
                            myCommand.Connection = myConnection;
                            myCommand.CommandText = CommandTime;
                            //下面这条语句不能执行,提示“已有打开的与此连接相关联的 DataReader,必须首先将它关闭。”要怎么办呢?怎样才能实现更新?
                            myCommand.ExecuteNonQuery();
                            i++;
                            //查看命令文本
                            Console.WriteLine("Done! \n {0}", myCommand.CommandText);
                        }
                    }
                }
                myConnection.Close();
                Console.WriteLine(" \n i= {0} \nDone!Press Enter key to exit! \n", i);
                Console.Read();
            }
        }
    }
      

  2.   

    如果是 紧紧是读取,修改,保存的过程
    可以考虑 SqlCommandBuilder 自动生成单表命令,用于将对 DataSet 所做的更改与关联的 SQL Server 数据库的更改相协调。无法继承此类。 
      

  3.   

    DataReader独占一个Connection,如果同时再有其它的方法使用Connection则要么关闭DataReader的Connection,要么再建立一个新的.
      

  4.   

    MSDN 详细介绍若要创建 SqlDataReader,必须调用 SqlCommand 对象的 ExecuteReader 方法,而不要直接使用构造函数。在使用 SqlDataReader 时,关联的 SqlConnection 正忙于为 SqlDataReader 服务,对 SqlConnection 无法执行任何其他操作,只能将其关闭。除非调用 SqlDataReader 的 Close 方法,否则会一直处于此状态。例如,在调用 Close 之前,无法检索输出参数。SqlDataReader 的用户可能会看到在读取数据时另一进程或线程对结果集所做的更改。但是,确切的行为与执行时间有关。当 SqlDataReader 关闭后,只能调用 IsClosed 和 RecordsAffected 属性。尽管当 SqlDataReader 存在时可以访问 RecordsAffected 属性,但是请始终在返回 RecordsAffected 的值之前调用 Close,以保证返回精确的值。
      

  5.   

    也可以创建一个实体类,先读取实体类中,然后再循环实体类再更新。
    因为SqlDataReader 是长连接的。
      

  6.   

    用了二楼的方法,不错。但是我修改了
    CommandText = "Update Tag set RealValue=(SELECT RealValue FROM Tag WHERE ValueID = 18 AND TimeStamp = '" + TimeString + " ') - (SELECT RealValue FROM Tag WHERE ValueID = 19 AND TimeStamp = '" + TimeString +" ') where ValueID=20";运行后结果不正确呀,是怎么回事?
    18 2011-1-30 9:00:00 234 1158.42016601563 128 8392704 1
    19 2011-1-30 9:00:00 234 43.3449058532715 128 8392704 1
    20 2011-1-30 9:00:00 234 1118.14240264893 128 8392704 1
    18 2011-1-30 9:10:00 234 1130.20837402344 128 8392704 1
    19 2011-1-30 9:10:00 234 43.4606475830078 128 8392704 1
    20 2011-1-30 9:10:00 234 1118.14240264893 128 8392704 1
    18 2011-1-30 9:20:00 234 1151.90966796875 128 8392704 1
    19 2011-1-30 9:20:00 234 42.8240737915039 128 8392704 1
    20 2011-1-30 9:20:00 234 1118.14240264893 128 8392704 1
    18 2011-1-30 9:30:00 234 1145.83337402344 128 8392704 1
    19 2011-1-30 9:30:00 234 49.6527786254883 128 8392704 1
    20 2011-1-30 9:30:00 234 1118.14240264893 128 8392704 1
    18 2011-1-30 9:40:00 234 1124.56591796875 128 8392704 1
    19 2011-1-30 9:40:00 234 49.1898155212402 128 8392704 1
    20 2011-1-30 9:40:00 234 1118.14240264893 128 8392704 1
    18 2011-1-30 9:50:00 234 1145.39929199219 128 8392704 1
    19 2011-1-30 9:50:00 234 48.7847213745117 128 8392704 1
    20 2011-1-30 9:50:00 234 1118.14240264893 128 8392704 1
    18 2011-1-30 10:00:00 234 1136.28466796875 128 8392704 1
    19 2011-1-30 10:00:00 234 48.7268524169922 128 8392704 1
    20 2011-1-30 10:00:00 234 1118.14240264893 128 8392704 1
      

  7.   

    按照你原先写的
    if ((int)drv["ValueID"] == 14)
    你已经过滤出来ValueID是14的值了,后面循环里你的
    CommandText = "Update Tag set RealValue=(SELECT RealValue FROM Tag WHERE ValueID = 18 AND TimeStamp = '" + TimeString + " ') - (SELECT RealValue FROM Tag WHERE ValueID = 19 AND TimeStamp = '" + TimeString +" ') where ValueID=20";这些里的判断都是无效的了。
      

  8.   

    这里我已经修改为if ((int)drv["ValueID"] == 20)
    目的是把所有ID为20的数据值替换成相同时间段内ID是18和19两个数据值的和。
    要如何实现?有时间段在限制,为什么还是相同的结果呀?
      

  9.   

    那你断点跟踪一下,看看CommandTime这个SQL字符串是什么???