|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Re: making datareadersi am getting data back
i will delete the new keyword; it was choking during compilation saying i needed to do something with it before i get values from it or something along those lines.. can i do Dim DR as System.Data.SqlClient.SqlDataReader = GetDataReader("EXEC spRootFoldersToCatalog") ?? You'd have to write your GetDataReader function to return a DataReader,
but yes, that is probably the preferred method. ok i am looking through the factory methods; i've been looking into
that for a while now but i just swear; it is something much much simpler I rewrote it so that i dont have to deal with the 'getDataReader' procedure but still i get the same error: ---------------------------------- There is already an open DataReader associated with this command which must be closed first. ---------------------------------- This is my first ADO.net conversion and i'm just kinda banging my head against a wall. >From what i understand; this is like a 2003 bug and it's fixed by MARS-- multiple active result sets.Right?? I know that the connection works; i've tested it with commands and it works like a charm. Dim cmd As System.Data.SqlClient.SqlCommand = cnnX.CreateCommand() cmd.CommandText = "EXEC spRootFoldersToCatalog" Dim DR As System.Data.SqlClient.SqlDataReader = cmd.ExecuteReader While DR.Read RootFolder = DR.GetValue(1).ToString rootFolderID = CInt(DR.GetValue(0).ToString) Call RootFolder_Catalog(RootFolder, rootFolderID) End While A DataReader requires a constant connection to the database and only
one DataReader can be open on a connection at once. If the Sql query returns more than one result set, you can advance to the next one by calling the DataReader.NextResult method. only one can be open on a connection at once.
i swear; i've seen documentation in several places that SQL 2005 against VB 2005 supports MARS -- multiple active result sets. i guess i'm just mistaken. So. How can i get the results of a datareader into an array?? This example is from the 101 Samples, VB 2005, Data from microsoft.com/visualbasic or whatever the url is. version 2005. ''' <summary> ''' This method fills employee and address information using Multiple Active Result Sets ''' This is set in the connection string by setting the MultipleActiveResultSets to true ''' by default it is set to true if ommitted. ''' By setting Multiple Active Results Sets, multiple data readers can be opened ''' by using the same connection without any blocking from occurring. ''' </summary> Private Sub FillUserAddressesWithMARS() Dim myEmployeeID As Integer = 0 Dim myAddressReader As SqlDataReader Dim myWatch As Stopwatch = New Stopwatch() Dim myFinalString As String = "" Dim myConnectionCount As Integer = 0 Try '' explicitly set the connection string to support Multiple Active Result Sets. Dim connectionString As String = ConfigurationManager.AppSettings("myMarsConnectionString") '' Set the query strings Dim myEmployeeQuery As String = "SELECT * FROM Employees ORDER BY LastName" Dim myAddressQuery As String = "SELECT * FROM Addresses WHERE EmployeeID = @EmployeeID" '' Use the new StopWatch class to time the retrieval and display of data myWatch.Start() '' Encapsulate the retrieval with this one connection Using myConnection As SqlConnection = New SqlConnection(connectionString) '' Open the connection and incrase the count myConnection.Open() myConnectionCount = myConnectionCount + 1 '' We create both SqlCommand objects using the same connection Dim myEmployeeCommand As SqlCommand = New SqlCommand(myEmployeeQuery, myConnection) Dim myAddressCommand As SqlCommand = New SqlCommand(myAddressQuery, myConnection) '' Add the parameter to the address command, this will allow us '' to get all the addresses for each employee id myAddressCommand.Parameters.AddWithValue("@EmployeeID", SqlDbType.Int) '' We are going to go through all the Employee records Using myEmployeeReader As SqlDataReader = myEmployeeCommand.ExecuteReader() While myEmployeeReader.Read() '' We want to display the name of the employee in the final text box Dim myName As String = myEmployeeReader("FirstName").ToString() & " " & myEmployeeReader("LastName").ToString() myFinalString = myFinalString & myName & vbCrLf '' Retrieve the EmployeeID for getting all the addresses myEmployeeID = Convert.ToInt32(myEmployeeReader("EmployeeID")) myAddressCommand.Parameters("@EmployeeID").Value = myEmployeeID '' get the address information myAddressReader = myAddressCommand.ExecuteReader() Using myAddressReader If myAddressReader.HasRows Then '' retrieve all the addresses in the DataReader object While myAddressReader.Read() Dim myAddress As String = myAddressReader("Address").ToString() Dim myCity As String = myAddressReader("City").ToString() Dim myState As String = myAddressReader("State").ToString() Dim myZipCode As String = myAddressReader("ZipCode").ToString() Dim myAddressType As String = myAddressReader("AddressType").ToString() myFinalString = myFinalString & myAddress + vbCrLf _ & myCity & ", " & myState & " " & myZipCode & vbCrLf _ & "Address Type: " & myAddressType & vbCrLf & vbCrLf End While Else myFinalString = myFinalString & "No Address " & vbCrLf & vbCrLf End If End Using End While End Using '' Close the connection myConnection.Close() End Using '' Stop the StopWatch so that we can display the time myWatch.Stop() '' Display the time elapsed elapsedTimeLabel.Text = myWatch.ElapsedMilliseconds.ToString() & " ms" '' Display how many connections were created connectionNumberLabel.Text = myConnectionCount.ToString() '' set some properties for the RichTextBox displayedDataRichTextBox.ScrollBars = RichTextBoxScrollBars.Vertical displayedDataRichTextBox.WordWrap = True '' Assign the final data displayedDataRichTextBox.Text = myFinalString Catch ex As Exception MessageBox.Show("There was an error retrieving data using MARS", "Alert") End Try End Sub Here's an example of what we do.
We execute the sql query to get a datareader back then pass that datareader into a method to fill and object (or it could be an array) and return that object: Private Function FillUserObect(rdr As SqlDataReader) As User Dim u As New User() u.Id = rdr.GetInt32("Id") u.Name = rdr.GetString("Name") 'More lines for the rest of the fields here Return u End Function You can also use the data reader's GetValues method to fill an object array with the values. but the getValues only handles one record at a time right?
i'm so in over my head lol. kneedeep in dotnet and loving it; im a VB6 / VBA convert. -Aaron I don't see any code for closing any datareader. You have to close the
datareader when you are done with it, or the connection won't be usable again. aaron.ke***@gmail.com wrote: Show quoteHide quote > only one can be open on a connection at once. > > i swear; i've seen documentation in several places that SQL 2005 > against VB 2005 supports MARS -- multiple active result sets. > > i guess i'm just mistaken. > > So. How can i get the results of a datareader into an array?? > > This example is from the 101 Samples, VB 2005, Data from > microsoft.com/visualbasic or whatever the url is. > version 2005. > > > ''' <summary> > ''' This method fills employee and address information using > Multiple Active Result Sets > ''' This is set in the connection string by setting the > MultipleActiveResultSets to true > ''' by default it is set to true if ommitted. > ''' By setting Multiple Active Results Sets, multiple data readers > can be opened > ''' by using the same connection without any blocking from > occurring. > ''' </summary> > Private Sub FillUserAddressesWithMARS() > > Dim myEmployeeID As Integer = 0 > Dim myAddressReader As SqlDataReader > Dim myWatch As Stopwatch = New Stopwatch() > Dim myFinalString As String = "" > Dim myConnectionCount As Integer = 0 > > Try > > '' explicitly set the connection string to support Multiple > Active Result Sets. > Dim connectionString As String = > ConfigurationManager.AppSettings("myMarsConnectionString") > > > '' Set the query strings > Dim myEmployeeQuery As String = "SELECT * FROM Employees > ORDER BY LastName" > Dim myAddressQuery As String = "SELECT * FROM Addresses > WHERE EmployeeID = @EmployeeID" > > '' Use the new StopWatch class to time the retrieval and > display of data > myWatch.Start() > > '' Encapsulate the retrieval with this one connection > Using myConnection As SqlConnection = New > SqlConnection(connectionString) > > '' Open the connection and incrase the count > myConnection.Open() > myConnectionCount = myConnectionCount + 1 > > '' We create both SqlCommand objects using the same > connection > Dim myEmployeeCommand As SqlCommand = New > SqlCommand(myEmployeeQuery, myConnection) > Dim myAddressCommand As SqlCommand = New > SqlCommand(myAddressQuery, myConnection) > > '' Add the parameter to the address command, this will > allow us > '' to get all the addresses for each employee id > myAddressCommand.Parameters.AddWithValue("@EmployeeID", > SqlDbType.Int) > > '' We are going to go through all the Employee records > Using myEmployeeReader As SqlDataReader = > myEmployeeCommand.ExecuteReader() > > While myEmployeeReader.Read() > > '' We want to display the name of the employee > in the final text box > Dim myName As String = > myEmployeeReader("FirstName").ToString() & " " & > myEmployeeReader("LastName").ToString() > myFinalString = myFinalString & myName & vbCrLf > > '' Retrieve the EmployeeID for getting all the > addresses > myEmployeeID = > Convert.ToInt32(myEmployeeReader("EmployeeID")) > > > myAddressCommand.Parameters("@EmployeeID").Value = myEmployeeID > > > '' get the address information > myAddressReader = > myAddressCommand.ExecuteReader() > Using myAddressReader > If myAddressReader.HasRows Then > > '' retrieve all the addresses in the > DataReader object > While myAddressReader.Read() > > Dim myAddress As String = > myAddressReader("Address").ToString() > Dim myCity As String = > myAddressReader("City").ToString() > Dim myState As String = > myAddressReader("State").ToString() > Dim myZipCode As String = > myAddressReader("ZipCode").ToString() > Dim myAddressType As String = > myAddressReader("AddressType").ToString() > > myFinalString = myFinalString & > myAddress + vbCrLf _ > & myCity & ", " & myState & " " & > myZipCode & vbCrLf _ > & "Address Type: " & myAddressType > & vbCrLf & vbCrLf > End While > > Else > myFinalString = myFinalString & "No > Address " & vbCrLf & vbCrLf > End If > End Using > End While > End Using > '' Close the connection > myConnection.Close() > End Using > '' Stop the StopWatch so that we can display the time > myWatch.Stop() > '' Display the time elapsed > elapsedTimeLabel.Text = > myWatch.ElapsedMilliseconds.ToString() & " ms" > '' Display how many connections were created > connectionNumberLabel.Text = myConnectionCount.ToString() > '' set some properties for the RichTextBox > displayedDataRichTextBox.ScrollBars = > RichTextBoxScrollBars.Vertical > displayedDataRichTextBox.WordWrap = True > '' Assign the final data > displayedDataRichTextBox.Text = myFinalString > > Catch ex As Exception > MessageBox.Show("There was an error retrieving data using > MARS", "Alert") > End Try > > End Sub > i mean doesn't my example say this should work? i just dont understand
i guess that the bottom line is that i figured out the root of my performance problem; a simple little cartesian. THANK GOD. Yes, if the database supports MARS. Judging by the error message it doesn't.
You should close the datareaders anyway. aaron.ke***@gmail.com wrote: Show quoteHide quote > i mean doesn't my example say this should work? i just dont understand > > i guess that the bottom line is that i figured out the root of my > performance problem; a simple little cartesian. > > THANK GOD. > I kinda feel like I'm stuck in the (bad) old days of DAO where you had
to close all these objects for stability sake. If I Dim a SqlDataReader why should i need to close it when it's gone out of scope? -Aaron Because if you don't, it will remain open (and keep the database object
alive) until the garbage collector wants to collect it but finds it unclosed, so it calls it's finalizer to dispose of it. As you can't control (or rather shouldn't interfer with) when carbage collections occur, you don't know how long the datareader and connection will remain in memory. aaron.ke***@gmail.com wrote: Show quoteHide quote > I kinda feel like I'm stuck in the (bad) old days of DAO where you had > to close all these objects for stability sake. > > If I Dim a SqlDataReader why should i need to close it when it's gone > out of scope? > > -Aaron > well i'm on SQL 2005 Standard on Windows 2000 professional.
I do have a 4gb limit on db size; so maybe SQL thinks that i'm in personal edition or something. I'd love to get around the 4gb limit on my laptop; it drives me crazy!! Is there anywhere that says which OS support MARS? -Aaron SQL 2005 should support MARS.
Have you actually specified in the connection string that it should use MARS? aaron.ke***@gmail.com wrote: Show quoteHide quote > well i'm on SQL 2005 Standard on Windows 2000 professional. > I do have a 4gb limit on db size; so maybe SQL thinks that i'm in > personal edition or something. > > I'd love to get around the 4gb limit on my laptop; it drives me crazy!! > > Is there anywhere that says which OS support MARS? > > -Aaron > the MS documentation right here says that it's on by default.
''' <summary> ''' This method fills employee and address information using Multiple Active Result Sets ''' This is set in the connection string by setting the MultipleActiveResultSets to true ''' by default it is set to true if ommitted. ''' By setting Multiple Active Results Sets, multiple data readers can be opened ''' by using the same connection without any blocking from occurring. ''' </summary> where can i learn about 10,000 times more about garbage collection and GAC? I've been banging my head against the wall on the tiniest performance optimizations; i'd love to get to know the big picture. like for starters-- this ETL job im running.. if i run it twice; it usually goes a lot faster the 2nd time than the first time. and i'd like to find out more about that effect. i dont think that it's as simple as database caching or anything; i hit the db pretty damn hard; the same tables over and over and over again. any good references / websites? non-MS websites? i dont trust MS anymore; years and years of betrayals. those bunch of drunk idiots across the pond (lake washington lol) can't even fix sql authentication. -Aaron
Substring question
vb.net, so slow !!!??? General Question About Web Apps, VB/ASP? Support for multiple database msmapi32.ocx Accessing existing Excel Workbook from complete path VB2005 Short address pointer How to control Bluetooth? Screen Scraper that does Automated data entry. Debugging DLLs - best practice |
|||||||||||||||||||||||