AllExperts > Experts 
Search      

VB.NET

Volunteer
Answers to thousands of questions
 Home · More Questions · Answer Library  · Encyclopedia ·
More VB.NET Answers
Question Library

Ask a question about VB.NET
Volunteer
Experts of the Month
Expert Login

Awards

About Us
Tell friends
Link to Us
Disclaimer

 
 
 
 
About Chris
Expertise
I can answer pretty much any question relating to VB.NET and its use in a Windows environment. I specialize in ASP.NET web development and MSSQL database access.

Experience
I have over 5 years of industry experience using VB.NET and other .NET technologies for web and database development.

Education/Credentials
I have some college education, but does it really matter in this field of work?

 
   

You are here:  Experts > Computing/Technology > Basic > VB.NET > SqlDataReader Issue

Topic: VB.NET



Expert: Chris
Date: 9/20/2007
Subject: SqlDataReader Issue

Question
Chris,
I am having an issue with some vb.net code that I hope that you can help.  I need to find all dups in a recordset then take information from one of the dup records an place it into a the other record then delete the first record.
I do this by looping through a datareader to find the distinct dup records.  I then loop through a second datareader and run an insert query and a delete query.
The problem is that I get the following error:
There is already an open DataReader associated with this Command which must be closed first.
But there is not a datareader associated with the command.

This is what I do:
I open the connection to the database:
Dim MSSQLConnect As New SqlConnection("Server=xxxx;Database=xxxx;Trusted_Connection=yes;")
MSSQLConnect.Open()

I then create the SQL for the main datareader and create the reader and start the loop:
Dim MainSQLcmd = New SqlCommand(SQLstr, MSSQLConnect)
Dim MainSQLdr As SqlDataReader = MainSQLcmd.ExecuteReader()
Do While MainSQLdr.Read()
Then I create the second SQL to get both records by passing in data from my main datareader.  Then I create the second reader:
Dim Dupcmd = New SqlCommand(SQLstr, MSSQLConnect)
Dim Dupdr As SqlDataReader = Dupcmd.ExecuteReader()
after the above line I get the error: There is already an open DataReader associated with this Command which must be closed first.


Any assistance is greatly appreciated.

Bob

Entire code:

   Sub RmvRecTwo()
       Dim SQLstr As String = Nothing
       Dim SELECTstr As String = Nothing
       Dim FROMstr As String = Nothing
       Dim WHEREstr As String = Nothing
       Dim GROUPBYstr As String = Nothing
       Dim UNIONstr As String = Nothing
       Dim ORDERBYstr As String = Nothing

       Dim MSSQLConnect As New SqlConnection("Server=UNCWDBVS1;Database=OIR;Trusted_Connection=yes;")
       MSSQLConnect.Open()

       SQLstr = Nothing
       SELECTstr = "SELECT DISTINCT ID "
       FROMstr = "FROM " + Environment.UserName + "ZGRAD" + frmGrad.txtTerm.Text + " "
       WHEREstr = "WHERE ID IN(SELECT ID FROM " + Environment.UserName + "ZGRAD" + frmGrad.txtTerm.Text + " GROUP BY ID HAVING (Count(ID) > 1))"
       UNIONstr = Nothing
       ORDERBYstr = Nothing

       SQLstr = SELECTstr & FROMstr & WHEREstr & UNIONstr & ORDERBYstr

       Dim MainSQLcmd = New SqlCommand(SQLstr, MSSQLConnect)
       Dim MainSQLdr As SqlDataReader = MainSQLcmd.ExecuteReader()

       Do While MainSQLdr.Read()
           SQLstr = Nothing
           SELECTstr = "SELECT Degree_1, Major_1, Minor_1, Conc_1, Degree_2, Major_2, Minor_2, Conc_2 "
           FROMstr = "FROM " + Environment.UserName + "ZGRAD" + frmGrad.txtTerm.Text + " "
           WHEREstr = "WHERE ID = " + Trim(MainSQLdr.Item(0).ToString) + " "
           UNIONstr = Nothing
           ORDERBYstr = "ORDER BY SEQ_No DESC"

           SQLstr = SELECTstr & FROMstr & WHEREstr & UNIONstr & ORDERBYstr

           Dim Dupcmd = New SqlCommand(SQLstr, MSSQLConnect)
*ERROR START AT NEXT LINE*      
           Dim Dupdr As SqlDataReader = Dupcmd.ExecuteReader()

           Dim x = 0
           Dim deg = Nothing
           Dim maj = Nothing
           Dim minr = Nothing
           Dim conc = Nothing

           Do While Dupdr.Read()
               If x = 0 Then
                   deg = Trim(Dupdr.Item(0).ToString)
                   maj = Trim(Dupdr.Item(1).ToString)
                   minr = Trim(Dupdr.Item(2).ToString)
                   conc = Trim(Dupdr.Item(3).ToString)
               Else
                   SQLstr = "UPDATE " + Environment.UserName + "ZGRAD" + frmGrad.txtTerm.Text + "SET DEGREE_2 = " + deg + ", MAJOR_2 = " + maj + ", MINOR_2 = " + minr + ", CONC_2 = " + conc + " Where ID = " + MainSQLdr.Item(0).ToString
                   Dim Updatecmd = New SqlCommand(SQLstr, MSSQLConnect)
                   Updatecmd.ExecuteNonQuery()
                   Updatecmd.Dispose()
                   Updatecmd = Nothing

                   SQLstr = "DELETE " + Environment.UserName + "ZGRAD" + frmGrad.txtTerm.Text + " Where ID = " + MainSQLdr.Item(0).ToString + " AND Degree_1 = Degree_2 AND Major_1 = Major_2 AND Minor_1 = Minor_2 AND Conc_1 = Conc_2"
                   Dim Deletecmd = New SqlCommand(SQLstr, MSSQLConnect)
                   Deletecmd.ExecuteNonQuery()
                   Deletecmd.Dispose()
                   Deletecmd = Nothing
               End If
               x = x + 1
           Loop
       Loop
       MainSQLcmd.Dispose()
       MainSQLdr.Dispose()
       MainSQLcmd.close()
       MainSQLdr.Close()
       MainSQLcmd = Nothing
       MainSQLdr = Nothing
   End Sub


Answer
The problem with your code is because of this:

 Dim MainSQLcmd = New SqlCommand(SQLstr, MSSQLConnect)
 Dim MainSQLdr As SqlDataReader = MainSQLcmd.ExecuteReader()

 Do While MainSQLdr.Read()
  ...
 Loop


You're creating an SqlDataReader, which uses an SqlCommand, which in turn uses an SqlConnection.  This is done outside of the loop, and inside the loop you use the same SqlConnection with other SqlCommands, and other SqlDataReaders.  Unfortunately, you need to consume that first SqlDataReader before you can open any other one using that same connection.  You could create multiple connections, one for each SqlCommand/SqlDataReader you're going to work with at any given time, but this is not recommended.  What you should do is create a small class to encapsulate the data you'll retrieve from each SqlDataReader, or fill a DataTable with the results, then dispose of the SqlDataReader before creating another to retrieve more results.

If you want a simple tool to automatically generate a class to access your SQL database tables, you can get this program I made called Table Assimilator from my website at http://www.beyourown.net/areas/Developers/TableAssimilator.aspx, but this will only be useful if you're retrieving all columns from a particular table, and not retrieving any fields used in your JOINs.

Add to this Answer    Ask a Question



  Rate this Answer
   Was this answer helpful?
Not at allDefinitely              
   12345  

     
About Us | Advertise on This Site | User Agreement | Privacy Policy | Help
Copyright  © 2008 About, Inc. About and About.com are registered trademarks of About, Inc. The About logo is a trademark of About, Inc. All rights reserved.