[RESOLVED] Help with datareader
I need a little help with this.
I don't usually use a DataReader in this way but now have a need for a one way, forward communication this allows.
Anyway I got this code for the reader off the net but what it doesn't seem to handle is the null values in the db.
The repro is:
I do have a matching username and pcname but the user choose not to password protect, so the Password field is null.
Code:
Private Sub btnLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogin.Click
If txtUsername.Text = "" Then
MessageBox.Show("Please complete the required fields..", "Authentication Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
' Check if user exist in OneData database
' Connect to DB
Dim conn As New System.Data.OleDb.OleDbConnection()
conn.ConnectionString = My.Settings.OneDataConnectionString
Try
'Select the Staff record that matches the username, pcname and password
Dim sql As String = "SELECT * FROM IDStaff WHERE StaffName= '" & Trim(txtUsername.Text) & "'" & _
" AND PCNAME= '" & Trim(txtPcName.Text) & "'" & " AND [Password] = '" & Trim(txtPassword.Text) & "'"
Dim sqlCom As New System.Data.OleDb.OleDbCommand(sql)
'Open Database Connection
sqlCom.Connection = conn
conn.Open()
Dim sqlRead As System.Data.OleDb.OleDbDataReader = sqlCom.ExecuteReader()
'Check if this user is in the database
If sqlRead.Read() Then
'Yes, username/password/pcname check has passed
UserModule.PCName = txtPcName.Text
UserModule.UserName = txtUsername.Text
Me.Close()
Else
' No username/password/pcname checked failed
' Throw an error message
MessageBox.Show("The Username/MachineName combination is either incorrect or not registered in the system..", "Authentication Failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
'Focus on Username field
txtUsername.Focus()
End If
' Close and dispose of the connection resource
conn.Close()
conn.Dispose()
Catch ex As Exception
MessageBox.Show("Failed to connect to Database..", "Database Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End If
End Sub
any guidance in using a datareader and dbnulls?
I know how to check a data row for dbnull but since I'm not going that route leaves me at a lose.
Re: [RESOLVED] Help with datareader
With a DataReader it will read one row at a time. With a OleDbDataReader you have to use the object as a vehicle to do comparison on by calling the Read method which in turn returns a Boolean value, this is why you'll often see OleDbDataReaders in a Do/Until loop with the condition at the beginning:
Code:
Do Until Not MyDataReader.Read
Loop
'Or
Do While MyDataReader.Read
Loop
If there is a row that is returned then you can get the values based on the column name or index. In your situation since you only want to know if there is a Row you could just return the value of Read:
Code:
Return MyDataReader.Read
ExecuteScalar will only ever return a single value. The way that I structure my SQL command is that it will return the Count value from the amount of rows returned. Let's take a different example of where you want to get the username based on the ID value, then you'd use:
Code:
Private Function GetUsername(ByVal id As Integer) As String
'...
Dim user As String = String.Empty
Using cmd As OleDbCommand = New OleDbCommand("SELECT [StaffName] FROM [IDStaff] WHERE [ID]=@id", con)
'Parameterize the query
cmd.Parameters.AddWithValue("@id", id)
'Open the connection
con.Open()
'Use ExecuteScalar to return a single value
user = cmd.ExecuteScalar().ToString()
'...
Return user
End Function
Re: [RESOLVED] Help with datareader
So if I'm following correctly:
Use ExecuteScalar in query's where I only need to return a single value. Seems to me there has to be a reader somewhere but maybe that's getting too technical. Never-the-less, this must be faster than looping through all the rows.
AND
Use a OleDbDataReader in query's where I would want to return multipal values. This would be accomplished by looping.
Re: [RESOLVED] Help with datareader
Quote:
Originally Posted by
crater
So if I'm following correctly:
Use ExecuteScalar in query's where I only need to return a single value. Seems to me there has to be a reader somewhere but maybe that's getting too technical.
You're counting screw threads when you don't need to. Behind the scenes it maybe using a stream of some kind to get the data... but that's so far down the technical line that it doesn't matter. It's like worrying about the car starting because you're sure there must be a spark plug in there somewhere - not all engines use a spark plug, some use a glow plug, which works differently, but it still works.
It's an implementation detail that the framework takes care of for you so you don't need to worry about it. It might be that today it uses a reader of some kind on the back end. Then one day someone discovers a faster method... and so the framework is re-wired to use this new method... because it is baked right in, you don't see the change, but get the benefit of it.
Quote:
Originally Posted by
crater
Never-the-less, this must be faster than looping through all the rows.
AND
Use a OleDbDataReader in query's where I would want to return multipal values. This would be accomplished by looping.
IT depends... there are multiple ways to get data for a reason... it might be that a reader isn't alwyas the best way. Sometimes you'll need to dump it into a datatable and then loop through that. then there's stored procedures and even parameterized quiesries that can have output parameters...
-tg
Re: [RESOLVED] Help with datareader
Quote:
You're counting screw threads when you don't need to. Behind the scenes it maybe using a stream of some kind to get the data... but that's so far down the technical line that it doesn't matter. It's like worrying about the car starting because you're sure there must be a spark plug in there somewhere - not all engines use a spark plug, some use a glow plug, which works differently, but it still works.
It's an implementation detail that the framework takes care of for you so you don't need to worry about it. It might be that today it uses a reader of some kind on the back end. Then one day someone discovers a faster method... and so the framework is re-wired to use this new method... because it is baked right in, you don't see the change, but get the benefit of it.
This is what I kind-of thought.
Quote:
IT depends... there are multiple ways to get data for a reason... it might be that a reader isn't alwyas the best way. Sometimes you'll need to dump it into a datatable and then loop through that. then there's stored procedures and even parameterized quiesries that can have output parameters...
This is my own challenge: To separate the ways of getting data based on the reason or logic.
I have become very accustom to using strongly typed datasets, data adapters and bindingsources that are produced via the datasource wizard, sadly without giving much thought of the "built-in functions these assembly's provide.
Thanks for the info
Re: [RESOLVED] Help with datareader
Here's how I grab data from the database... again, note there is no explicit reader here...
Code:
Private Function GetColumnNames(dbConn As SqlClient.SqlConnection, ImportProcessID As Guid) As DataTable
Dim retDataTable As New DataTable
Dim sqlAdapter As New SqlClient.SqlDataAdapter
Dim sqlCommand As New SqlClient.SqlCommand()
sqlCommand.Connection = dbConn
sqlCommand.CommandType = CommandType.StoredProcedure
sqlCommand.CommandText = "usp_ExtractTableData"
sqlCommand.Parameters.AddWithValue("PROCESSID", ImportProcessID)
sqlAdapter.SelectCommand = sqlCommand
sqlAdapter.Fill(retDataTable)
Return retDataTable
End Function
This is fairly typical of how I'll call a stored proc that returns a bunch of data... I dump it into a datatable, then return that... from there I work disconnected and can loop through the data. In fact, rigght after I call this funciton, I call another one almost exactly like it to get some additional data from elsewhere... I then take both of those dataTables and pass them to yet another function that does some UI updating. Readers in this case would not work for me.
-tg