I'm trying to pull data from ACCESS database.
As it is, the code works, and gives no errors...
However, I can't seem to be able to display a messagebox if the record doesn't exist. It simply returns an empty string.
Using dbCon = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source = '" & Application.StartupPath & "\Res\T500G.accdb'")
dbCon.Open()
Dim Query1 As String = "SELECT SUM(Total) FROM [T500] WHERE Pro=#Pro"
Dim cmd1 As OleDb.OleDbCommand = New OleDbCommand(Query1, dbCon)
cmd1.Parameters.AddWithValue("#Pro", ComboBoxBP.SelectedItem.ToString)
Dim reader As OleDb.OleDbDataReader
reader = cmd1.ExecuteReader
While reader.Read()
TextBox1.Text = reader.GetValue(0).ToString
End While
reader.Close()
dbCon.Close()
End Using
I've tried using If reader.hasrows then display result in textbox, else show messagebox etc, but it doesn't work.
If reader.HasRows Then
While reader.Read()
TextBox1.Text = reader.GetValue(0).ToString
End While
Else
MessageBox.Show("asd")
End If
If I remove the .ToString from reader.GetValue(0) I get an error if the selected item from the combobox doesn't exist in the database. Cannot convert DBNull to integer or something.
So my question is, how to display a messagebox if the record "#Pro" doesn't exist?
Thanks~
Fixed(Workaround) with this
Dim ValueReturned As String
While reader.Read()
ValueReturned = reader.GetValue(0).ToString
If ValueReturned = "" Then
MessageBox.Show("Not Found", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
MetroTextBox1.Text = ValueReturned
End If
End While
Using OleDbDataReader is suboptimal for your query because it is never going to return a set of records to traverse:
Dim sql = "SELECT SUM(...=#p1"
' rather than sprinkling you connection string all over
' the app, you can make a function returning one
Using conn As OleDbConnection = GetConnection(),
cmd As New OleDbCommand(sql, GetConnection())
conn.Open())
' ToDo: Check that ComboBoxBP.SelectedItems.Count >0 before this
cmd.Parameters.AddWithValue("#p1", ComboBoxBP.SelectedItem.ToString)
' execute the query, get a result
Dim total = cmd.ExecuteScalar
' if there is no matches, OleDb returns DBNull
If total Is System.DBNull.Value Then
' no matches
MessageBox.Show("No matching records!"...)
Else
MessageBox.Show("The Total is: " & total.ToString()...)
End If
End Using ' disposes of the Connection and Command objects
Alteratively, you could use If IsDBNull(total) Then.... If you want, you can also convert it:
Dim total = cmd.ExecuteScalar.ToString()
' DBNull will convert to an empty string
If String.IsNullOrEmpty(total) Then
MessageBox.Show("No Soup For You!")
Else
...
End If
You could change your query to (this is for SQL-Server):
IF EXISTS (SELECT * FROM [T500] WHERE Pro = #Pro) SELECT SUM(Total) FROM [T500] WHERE Pro = #Pro ELSE SELECT 'Not Found'
And change your code to:
Dim ValueReturned As String
While reader.Read()
ValueReturned = reader.GetValue(0).ToString
End While
If ValueReturned Is Nothing OrElse ValueReturned = "Not Found" Then
MessageBox.Show("Not Found", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
TextBox1.Text = ValueReturned
End If
Related
I have a problem with the following:
Dim sql As String = "SELECT ArithmeticScore FROM " & tablename & " WHERE DateAscending = " & todaysdate.ToString("%dd/mm/yyyy")
Using connection As New OleDbConnection(getconn)
Dim findscore As New OleDbCommand(sql, connection)
connection.Open()
Dim reader As OleDbDataReader = findscore.ExecuteReader() 'ERROR OCCURS HERE
While reader.Read()
If Not reader.IsDBNull(0) Then
scoreexists = True
MsgBox("score exists")
Else
scoreexists = False
MsgBox("score does not exist")
End If
End While
reader.Close()
connection.Close()
End Using
I want to check if the cell in ArithmeticScore is empty when DateAscending = todaysdate
getconn Holds the connection string, tablename holds the name of the table.
I'm getting the error: 'Division by zero'
I understand why the program can't do that, but why on earth would it? I'm only trying to find out if a cell has a value in it or if its empty. The cell in question does have a value, 51.606 as a Decimal. I'm using an access database.
i have this code,,its work (kind of).
Dim connString As String = ConfigurationManager.ConnectionStrings("connectionstring").ConnectionString
Dim conn As New SqlConnection(connString)
conn.Open()
Dim comm As New SqlCommand("SELECT username, Password,type FROM users WHERE username='" & TextBox1.Text & "' AND Password='" & TextBox2.Text & "'", conn)
Dim reader As SqlDataReader
reader = comm.ExecuteReader
Dim count As Integer
count = 0
While reader.Read
count = count + 1
End While
If count = 1 Then
MessageBox.Show("username and password are correct")
Form2.Show()
Form2.Label1.Text = Me.TextBox1.Text
Form2.Label2.Text = reader(2).ToString
ElseIf count > 1 Then
MessageBox.Show("username and password are duplicated")
Else
MessageBox.Show("username and password are wrong")
End If
im getting error with this line:
Form2.Label2.Text = reader(2).ToString
and error is "Invalid attempt to read when no data is present"
why its says "no data"
i have all data in database?
can someone help me to correct this code?
thank you ..
You should not be using a loop at all. There should be no way that you can get more than one record so what use would a loop be? You should be using an If statement and that's all:
If reader.Read() Then
'There was a match and you can get the data from reader here.
Else
'There was no match.
End If
If it's possible to have two records with the same username then there's something wrong with your database design and your app. That column should be unique and your app should be testing for an existing record when someone tries to register.
A SqlDataReader is a forward only data read element. The error is occurring because you're calling the reader's READ function twice; once as true to increment to 1, and a second time to get a false to fall out of the while statement. Since you're no longer in the WHILE statement, the reader had to have read the end of the result set, thus there is no data for you to read.
Consider the changed code below:
Dim connString As String = ConfigurationManager.ConnectionStrings("connectionstring").ConnectionString
Dim count As Integer = 0
Dim userType as string = ""
Using conn As New SqlConnection(connString)
conn.Open()
Using Comm as SqlCommand = conn.CreateCommand
comm.commandText = "SELECT username, Password, type FROM Users WHERE username = #UserName AND Password = #Pwd; "
comm.parameters.AddWithValue("#Username", TextBox1.Text)
comm.parameters.AddWithValue("#Password", Textbox2.text)
Dim reader As SqlDataReader
reader = comm.ExecuteReader
If reader IsNot Nothing Then
If reader.HasRows() Then
While reader.read
count = count + 1
If Not reader.IsDbNull(2) Then userType = reader(2).ToString
End While
End If
If Not reader.IsClosed Then reader.close
reader = Nothing
End If
End Using
End Using
If count = 1 Then
MessageBox.Show("username and password are correct")
Form2.Show()
Form2.Label1.Text = Me.TextBox1.Text
Form2.Label2.Text = userType
ElseIf count > 1 Then
MessageBox.Show("username and password are duplicated")
Else
MessageBox.Show("username and password are wrong")
End If
First off, SQLParameters are your friend. Learn them. They are the single easiest way to fight against SQL Injection when using the SqlClient classes.
Secondly, notice that I'm doing the actual retrieval of the data from the reader inside the WHILE loop. This ensures that there's actual data for me to read.
Third, notice the USING statements on the SqlConnection and SqlCommand objects. This helps with garbage collection, and has a couple of other benefits as well.
Finally, notice the checks I'm doing on the SqlDataReader before I ever attempt to access it. Things like that would prevent from another error appearing if you did not return any results.
An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
Additional information: Index was out of range. Must be non-negative and less than the size of the collection.
The above unhandled exception shows when i run below code :
Private Sub chUser()
conn = New SqlConnection(conStr)
conn.Open()
myConn.clName = clNameDGV.SelectedRows.Item(0).Cells(0).Value //EXCEPTION SHOWS FOR THIS LINE
Dim comStr As String = "Select Count(*) from Login_Detail Where Clinic_Name = '" & clNameDGV.SelectedRows.Item(0).Cells(0).Value & "'"
Dim comm As New SqlCommand(comStr, conn)
Dim i As Integer = comm.ExecuteScalar()
If i = 0 Then
If MessageBox.Show("No User Information found for '" + clNameDGV.SelectedRows.Item(0).Cells(0).Value + "'." + vbNewLine + "Do you want to enter new user details ?", "No Users Found", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = vbYes Then
Dim nf As New CreateUser
nf.TopMost = True
nf.ShowDialog(Me)
End If
End If
Dim nf1 As New LoginForm
nf1.TopMost = True
nf1.ShowDialog(Me)
conn.Close()
End Sub
I have only one column with multiple rows in my datagridview. I run above function on doubleclick event of datagridview.
As you have a one-column DGV, you only need to use the .SelectedCells property, and you should check that only one cell is selected, something like this:
Private Sub ChUser()
If clNameDGV.SelectedCells.Count <> 1 Then
' not exactly one row was selected
Exit Sub
End If
Dim clinicName As String = CStr(clNameDGV.SelectedCells.Item(0).Value)
Dim nFoundRecords As Integer
Dim conn As SqlConnection = Nothing
Try
conn = New SqlConnection(conStr)
conn.Open()
myConn.clName = clinicName
Dim sql As String = "SELECT COUNT(*) FROM Login_Detail WHERE Clinic_Name = #ClinicName"
Using cmd As New SqlCommand(sql, conn)
'TODO: Set the .SqlDbType parameter correctly.
'TODO: Add the .Size parameter to match the setting in the database.
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "#ClinicName", .SqlDbType = SqlDbType.NVarChar, .Value = clinicName})
nFoundRecords = CInt(cmd.ExecuteScalar())
End Using
conn.Close()
Finally
If conn IsNot Nothing Then
conn.Dispose()
End If
End Try
If nFoundRecords = 0 Then
Dim message As String = "No User Information found for '" & clinicName & "'." & vbNewLine & "Do you want to enter new user details?"
Dim userChoice As DialogResult = MessageBox.Show(message, "No Users Found", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If userChoice = DialogResult.OK Then
Dim nf As New CreateUser
nf.TopMost = True
nf.ShowDialog(Me)
End If
End If
Dim nf1 As New LoginForm
nf1.TopMost = True
nf1.ShowDialog(Me)
End Sub
Please note how I have used CStr and CInt in appropriate places. If you use Option Strict On then it will point out for you where you should make explicit conversions (among other things). Also, I split up some lines into several lines to make it easier to read, and hence easier to edit.
I have based my codes from my professors. I typed the right username and password but it keeps on saying invalid user. The name of the table is also correct. I don't know why it keeps on saying it's an invalid user kindly help me please.
If Len(Trim(txtUsername.Text)) = 0 Then
MessageBox.Show("Please enter user name", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
txtUsername.Focus()
Exit Sub
End If
If Len(Trim(txtPassword.Text)) = 0 Then
MessageBox.Show("Please enter password", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
txtPassword.Focus()
Exit Sub
End If
Dim query As String = "SELECT * FROM Users"
Dim dt As New DataTable
ExecuteQuery(query)
Dim ctr As Integer
If dt.Rows.Count > 0 Then
If (dt.Rows(ctr)("Username")) = txtUsername.Text Then
If (dt.Rows(ctr)("Password")) = txtPassword.Text Then
frmMainMenu.Show()
Me.Hide()
End If
Else
MsgBox("Incorrect password")
txtPassword.Text = ""
txtPassword.Focus()
End If
Else
MsgBox("Invalid user")
txtPassword.Text = ""
txtUsername.Text = ""
txtUsername.Focus()
End If
You are never initializing the dt DataTable. So a new DataTable will have 0 rows, and you will fall into the Else of If dt.Rows.Count > 0. I presume you had intended to have dt be the DataTable that results from the ExecuteQuery statement, but as you are neither passing dt in nor assigning a result from ExecuteQuery to the dt variable, it is still blank.
Not knowing what ExecuteQuery does, I would imagine it should be either
ExecuteQuery(query, dt)
or
dt = ExecuteQuery(query)
After which point you might fall into the intended username/password comparison block, if there are actually rows in the Users table.
However your matching still will not work unless the matching record is the first in the DataTable, as you never actually iterate/increment ctr.
this is my codes for ExecuteQuery()
Dim connectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\nikko\Documents\Visual Studio 2010\Projects\PayrollSystemThesis\PayrollSystemThesis\bin\Debug\Thesis.accdb"
Public Function ExecuteQuery(ByVal query As String) As DataTable
Try
Dim dbCon As New OleDbConnection(connectionString)
Dim dbDA As New OleDbDataAdapter(query, dbCon)
Dim dbCB As New OleDbCommandBuilder(dbDA)
Dim dbDT As New DataTable
dbDA.Fill(dbDT)
Return dbDT
Catch ex As Exception
MessageBox.Show(ex.Message)
Return Nothing
End Try
End Function
it reads sql statements.
I've been trying to use an IF/ELSE statement to query my MySQL database, but can't seem to figure out why the ELSE statement is being ignored by VB. Here's the code - any help would be appreciated:
dbConn = New MySqlConnection("Server=" & FormLogin.ComboBoxServerIP.SelectedItem & ";Port=3306;Uid=qwertyuiop;Password=lkjhgfdsa;Database=zxcvbnm")
Dim account As Boolean = True
If dbConn.State = ConnectionState.Open Then
dbConn.Close()
End If
dbConn.Open()
Dim dbQuery As String = "SELECT * FROM customer WHERE accountNumber = '" & TextBoxSearch.Text & "';"
Dim dbData As MySqlDataReader
Dim dbAdapter As New MySqlDataAdapter
Dim dbCmd As New MySqlCommand
dbCmd.CommandText = dbQuery
dbCmd.Connection = dbConn
dbAdapter.SelectCommand = dbCmd
dbData = dbCmd.ExecuteReader
While dbData.Read()
If dbData.HasRows() = True Then
MessageBox.Show("Customer Account Found!")
Else
MessageBox.Show("No Customer Records Found! Please try again!")
dbData.Close()
End If
End While
My intent is to replace the messagebox in the "IF" clause with the code that will populate my form with the data from the database.
That's because you are already reading it:
While dbData.Read()
If dbData.HasRows() = True Then
MessageBox.Show("Customer Account Found!")
Else
MessageBox.Show("No Customer Records Found! Please try again!")
dbData.Close()
End If
End While
If your reader has no records, the whole While loop will be skipped.
Try it the other way around:
If dbData.HasRows Then
While dbData.Read()
'looping through records here
End While
Else
MessageBox.Show("No Customer Records Found! Please try again!")
End If
And also the obligatory note: Don't keep your connections open and alive. Use the Using End Using bracket to automatically close your disposable objects.
I wouldn't say it's skipping your else clause, but it could be evaluating your if condition differently that you expect.
Personally, I don't like comparing anything to True. If you drop the = true, does it work?