Type mismatch in criteria expression - vb.net

I am new to visual basic . I want to delete a record based on phone number . The program will ask the user to enter his number and will delete the record after matching the phone number with the database . I tried doing so but it is giving me an error "Type mismatch in criteria expression".
I am using ms access 2007 and I have speciefied the data type of the phone column as Number . Here is my vb code . Please help me . It must be one of my silly mistakes . In the insert data module , I have specified the datatype as Long , before that I had specified it as Integer but the same error persists .
Imports System.Data.OleDb
Public Class Form5
Public Connstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source = C:\Users\AMEN\Documents\Railway.accdb"
Public Conn As New OleDbConnection
Private Sub Form5_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Conn.ConnectionString = Connstring
If Conn.State = ConnectionState.Closed Then
Conn.Open()
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim okToDelete As MsgBoxResult = MsgBox("Are you sure you want to cancel your ticket?", MsgBoxStyle.YesNo)
If okToDelete = MsgBoxResult.Yes Then
Dim str As String
str = "Delete from Table2 Where Phone = '" & TextBox1.Text & "'"
Dim cmd As OleDbCommand = New OleDbCommand(str, Conn)
Try
cmd.ExecuteNonQuery()
cmd.Dispose()
Conn.Close()
MsgBox("Your Ticket Cancelled Sucessfully ! ")
Catch ex As Exception
MsgBox(ex.Message)
End Try
ElseIf okToDelete = MsgBoxResult.No Then
End If
End Sub
End Class

Phone numbers should be stored as strings not as numbers.
But a part from this your query is wrong if your Phone field is numeric.
In that case you don't need quotes around the TextBox1.Text. This will treat your input as a string and this string cannot be used to search in a numeric field.
The best approach is to use a parameterized query where you could specifiy the datatype of the parameter passed
(I have assumed that you have created the field Phone as Long Number in Access)
If okToDelete = MsgBoxResult.Yes Then
' Check if your user types really a number.
Dim number As Integer
if Not Int32.TryParse(TextBox1.Text, number) Then
MessageBox.Show("Not a valid number!")
return
End If
Dim str As String
str = "Delete from Table2 Where Phone = #phone"
Dim cmd As OleDbCommand = New OleDbCommand(str, Conn)
Try
cmd.Parameters.Add("#phone", OleDbType.Integer).Value = number
cmd.ExecuteNonQuery()
....

Related

change format date and can update in textbox with blank or zero in vb.net

I wanted to change the date format in the textbox to the format "dd-mmm-yy" but it did not work when in datagridview did not appear the date with the time and also I could not update in the textbox with blank and zero which caused the error "data type error". if I do not perform sql command for update in the "DATE" field then do not cause error. I use visual studio 2010
so the problem in the date column and if I update without a date column then it runs perfectly. Problem error : syntax error in update statement
thanks
jack
Dim Path As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim cn As String = "provider=Microsoft.Jet.OLEDB.4.0; data source=" & Path & "; Extended Properties=dBase IV"
Private connectionString As String
Private con As OleDbConnection
Private cmd As OleDbCommand
Private da As OleDbDataAdapter
Private sql As String
Public x As Integer
Public Sub dbConnection()
connectionString = CStr(cn)
con = New OleDbConnection(connectionString)
con.Open()
End Sub
Private Sub DataGridView1_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
x = DataGridView1.Rows.IndexOf(DataGridView1.CurrentRow)
txtCODE.Text = DataGridView1.Rows(x).Cells(0).Value.ToString()
DateTimePicker1.Value = DataGridView1.Rows(x).Cells(1).Value.ToString()
NumericUpDown1.Value = DataGridView1.Rows(x).Cells(2).Value.ToString()
End Sub
Private Sub FillDataGridView()
Try
Dim query = "select CODE,DTE,QTY FROM EXAMPLE"
Using con As OleDbConnection = New OleDbConnection(CStr(cn))
Using cmd As OleDbCommand = New OleDbCommand(query, con)
Using da As New OleDbDataAdapter(cmd)
Dim dt As DataTable = New DataTable()
da.Fill(dt)
Me.DataGridView1.DataSource = dt
End Using
End Using
End Using
Catch myerror As OleDbException
MessageBox.Show("Error: " & myerror.Message)
Finally
End Try
End Sub
Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click
Try
dbConnection()
x = DataGridView1.Rows.IndexOf(DataGridView1.CurrentRow)
'sql = "UPDATE EXAMPLE SET QTY=? WHERE CODE=?"
sql = "UPDATE EXAMPLE SET DTE=?,QTY=? WHERE CODE=?"
cmd = New OleDbCommand(sql, con)
cmd.Parameters.Add("DTE", OleDbType.Date)
cmd.Parameters.Add("QTY", OleDbType.Numeric)
cmd.Parameters.Add("CODE", OleDbType.VarChar)
cmd.Parameters("DTE").Value = DateTimePicker1.Value
cmd.Parameters("QTY").Value = NumericUpDown1.Value
cmd.Parameters("CODE").Value = txtCODE.Text
cmd.ExecuteNonQuery()
MessageBox.Show("Successfully Updated...", "Update")
con.Close()
FillDataGridView()
Catch myerror As OleDbException
MessageBox.Show("Error: " & myerror.Message)
Finally
End Try
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
FillDataGridView()
End Sub
Your SQL line must be written like:
sql = "UPDATE EXAMPLE SET DATE=#d,QTY=#q WHERE CODE=#c"
You set the values of these #xxx by adding more code:
cmd.Parameters.AddWithValue("#d", dtpDATE.Value)
cmd.Parameters.AddWithValue("#q", nudQTY.Value)
cmd.Parameters.AddWithValue("#c", txtCODE.Text)
Change your date time TextBox to be a datetimepicker instead. Instead of using textboxes for numeric values, use a NumericUpDown instead.
You must call AddWithValue("#xxx"... in the same order as the #xxx appear in the SQL. Access ignores the names and looks at the order Parameters appear in the SQL so it is important to call AWV on the same order. One day when you upgrade o using a different database it will support the name part of the parameter so you can add your values in any order but right now on access, order is important
You must write your SQL like I've shown. Never, ever do what you were doing before. Never use string concatenation to build a user-supplied data value into an SQL statement. It makes your program trivial to hack into. This might not matter while you're writing a tiny app to index grandma's record collection but it must never be done on any system of importance such as one used by many people

Displaying multiple pieces of data from a database, and display it in one text box [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am making a game, and want to display all of a students results in one text box ( or however else it can be done to display it)
In my database, i have a field called username. This adds the same users name as a new record every time a game finishes, containing the score too. The problem is, I can only seem to display the latest score. How would I go about displaying all of the results for one student in one box. Also, how would I seperate them with commas ? Thank you
Imports System.Data.OleDb
' Accesses my database, and checks whether the teacher is in the database '
Public Class RetrieveResults
Dim provider As String
Dim dataFile As String
Dim connString As String
Public myConnection As OleDbConnection = New OleDbConnection
Public dr As OleDbDataReader
Private Sub Retrieveresults_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
dataFile = "D:\Student Database1.accdb"
connString = provider & dataFile
myConnection.ConnectionString = connString
End Sub
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
myConnection.Open()
surname.Clear()
Classs.Clear()
Score.Clear()
Dim str As String
str = "SELECT * FROM [SCORE] WHERE (Student_UserName = '" & Student_name.Text & "')"
Dim cmd As OleDbCommand = New OleDbCommand(str, myConnection)
dr = cmd.ExecuteReader
While dr.Read()
surname.Text = dr("Student_Username").ToString
Classs.Text = dr("class").ToString
Score.Text = dr("score").ToString
End While
myConnection.Close()
End Sub
End Class
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
surname.Clear()
Classs.Clear()
Score.Clear()
Dim str As String = "SELECT * FROM [SCORE] WHERE (Student_UserName = #StudentName);"
Using myConnection As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source =D:\Student Database1.accdb")
Using cmd As OleDbCommand = New OleDbCommand(str, myConnection)
cmd.Parameters.Add("#StudentName", OleDbType.VarChar).Value = Student_name.Text
myConnection.Open()
Using dr As OleDbDataReader = cmd.ExecuteReader
While dr.Read()
Classs.Text &= dr("class").ToString & ", "
Score.Text &= dr("score").ToString & ", "
End While
End Using
End Using
End Using
surName.Text = Student_name.Text
End Sub
Instead of all the strings I passed the connection string directly in the Connection constructor. I moved the Form level variables to the button event.
I used the Using ...End Using statements on the Connection, Command, and DataReader to make sure they are disposed properly even if there is an error.
I changed the Select statement to use parameters. Access doesn't care what you call it as long as it add the parameter in the same order as in the SQL statement. Not a problem here since there is only one.
I took the surName out of the Whiile loop there should only be one value for this.
I added an & before the equals sign so the loop will add the next value to text box and I added the comma to each iteration
I hope this helps.

VB.net/MS Access Monthly Donations System Assistance

I'm doing a project for my Database Management subject. I cannot figure out how to add an amount to a previously added amount. For now, I'm only able to update the amount. Here's the code. I'm sorry if I cannot explain it well.
I have 2 forms. My first form allows me to enter a last name and retrieve the data to my list view.
My second form lets me retrieve the data I entered in my first form and it will show up on a separate list view with a "Last Name | Amount" tab.
I have two textboxes. One for last name set to readonly to disable editing, and another for the amount I want to enter.
After entering an amount, let's say 20, it will update on the listview and my database as 20.
The problem is that when I enter a new amount for the same last name, let's say 30, the 30 will replace the 20 but it should be 50 because 20+30 = 50.
I understand the logic and I have tried adding another textbox for addition but I simply do not know the codes for it.
Imports System.Data.OleDb
Public Class Form2
Dim conString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Israel De Leon\Documents\testing.accdb;"
Dim con As OleDbConnection = New OleDbConnection(conString) 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database2.accdb
Dim cmd As OleDbCommand
Dim adapter As OleDbDataAdapter
Dim dt As DataTable = New DataTable()
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'SET LISTVIEW PROPERTIES
ListView1.View = View.Details
ListView1.FullRowSelect = True
'Construct Columns
ListView1.Columns.Add("Last Name", 100)
ListView1.Columns.Add("Amount", 100)
End Sub
Private Sub UpdateLV(lname As String)
'Updates last name and amount entered into the database
Dim sql As String = "UPDATE Table1 SET LastName='" + TextBox1.Text + "',Amount='" + TextBox2.Text + "' WHERE LastName='" + lname + "'"
cmd = New OleDbCommand(sql, con)
'OPEN CON, EXECUTE, UPDATE, CLOSE
Try
con.Open()
adapter = New OleDbDataAdapter(cmd)
adapter.UpdateCommand = con.CreateCommand()
adapter.UpdateCommand.CommandText = sql
If (adapter.UpdateCommand.ExecuteNonQuery() > 0) Then
MsgBox("Successfully Updated")
End If
con.Close()
Retrieve()
ClearBox()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
Private Sub Retrieve()
ListView1.Items.Clear()
'SQL STM
Dim sql As String = "SELECT * FROM Table1 "
cmd = New OleDbCommand(sql, con)
'OPEN CON, RETRIEVE, FILL LISTVIEW
Try
con.Open()
adapter = New OleDbDataAdapter(cmd)
adapter.Fill(dt)
'LOOP THROUGH DT
For Each row In dt.Rows
Populate(row(0), row(1)) 'Index of database row
Next
'CLEAR DATATABLE
dt.Rows.Clear()
con.Close()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
Private Sub Populate(lname As String, aamount As String)
'ROW ARRAY
Dim row As String() = New String() {lname, aamount}
Dim item As ListViewItem = New ListViewItem(row)
'ADD TO ROWS COLLECTION
ListView1.Items.Add(item)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Retrieve()
End Sub
Private Sub ListView1_MouseClick(sender As Object, e As MouseEventArgs) Handles ListView1.MouseClick
Dim llname As String = ListView1.SelectedItems(0).SubItems(0).Text
Dim amounts As String = ListView1.SelectedItems(0).SubItems(1).Text
TextBox1.Text = llname
TextBox2.Text = amounts
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim amounts As String = ListView1.SelectedItems(0).SubItems(0).Text
UpdateLV(amounts)
End Sub
Private Sub ClearBox()
TextBox1.Text = ""
TextBox2.Text = ""
End Sub
End Class
Mathematical operation should not be done using strings. This is a real basic principle that many VB.NET programmers don't think enough thanks to the forgiveness allowed by Option Strict Off in the VB.NET project settings.
If you are just starting a new project in VB.NET don't use this setting but switch it ASAP to On. This will give you an halt when you try to use strings as they were numbers and force you to do the appropriate conversion and checking on the values provided.
So your code that updates the amount rewritten
Private Sub UpdateLV(lname As String)
' Get the amount as a number (decimal for currency is the best)
Dim addAmt As Decimal
if Not decimal.TryParse(textbox2.Text, addAmt) Then
MessageBox.Show("Insert a valid amount please")
return
End If
' Sanity check
if addAmt <= 0 Then
MessageBox.Show("Amount should be > 0")
return
End If
'Updates last name and amount entered into the database
Dim sql As String = "UPDATE Table1 SET LastName=#name
,Amount=Amount+#amt
WHERE LastName=#oldname"
cmd = New OleDbCommand(sql, con)
Try
con.Open()
' Using an adapter here is wrong. You use directly the command
cmd.Parameters.Add("#name", OleDbType.VarWChar).Value = textBox1.Text
cmd.Parameters.Add("#amt", OleDbType.Decimal).Value = addAmt
cmd.Parameters.Add("#oldname", OleDbType.VarWChar).Value = lName
If (cmd.ExecuteNonQuery() > 0) Then
MsgBox("Successfully Updated")
End If
con.Close()
Retrieve()
ClearBox()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
Something else is not clear in your code. What is the purpose of changing also the LastName here? Finally do not keep a global connection object. Instead create it when you need it and destroy it afterward with Using statement. It will be better for your memory footprint and for your database

VB.Net SQL Count Statement into a label

I'm trying to count the students whose teacher where teacher = '" & lblTeacher.Text & "'"
EXAMPLE :
Public Class Form1
Dim conn As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Richard\Desktop\Dbase.mdb"
Dim con As New OleDbConnection
Dim da, da1 As New OleDbDataAdapter
Dim dt, dt1 As New DataTable
Dim sql As String
Dim ds As New DataSet
Public Sub display()
sql = "select * from Info"
dt.Clear()
con.Open()
da = New OleDbDataAdapter(sql, con)
da.Fill(dt)
con.Close()
DataGridView1.DataSource = dt.DefaultView
End Sub
Public Sub count()
sql = "select COUNT(name) from Info where teacher = '" & lblTeacher.Text & "'"
da1 = New OleDbDataAdapter(sql, con)
ds.Clear()
con.Open()
da.Fill(ds)
lblCount.Text = ds.Tables(0).Rows.Count.ToString
con.Close()
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
con.ConnectionString = conn
display()
End Sub
Private Sub DataGridView1_Click(sender As System.Object, e As System.EventArgs) Handles DataGridView1.Click
lblTeacher.Text = DataGridView1.CurrentRow.Cells("teacher").Value.ToString
count()
End Sub
End Class
1:
Try this instead of your current count() method. Pay special attention to my comments; they address some poor practices from the original code:
' Better functional style: accept a value, return the result
Public Function GetStudentCount(teacher As String) As Integer
'**NEVER** use string concatenation to put data into an SQL command!!!
Const sql As String = "select COUNT(name) from Info where teacher = ?"
'Don't try to re-use the same connection in your app.
' It creates a bottleneck, and breaks ADO.Net's built-in connection pooling,
' meaning it's more likely to make object use *worse*, rather than better.
'Additionally, connection objects should be created in a Using block,
' so they will still be closed if an exception is thrown.
' The original code would have left the connection hanging open.
Using con As New OleDbConnection(conn), _
cmd As New OleDbCommand(sql, con)
'This, rather than string concatenation, is how you should put a value into your sql command
'Note that this NEVER directly replaces the "?" character with the parameter value,
' even in the database itself. The command and the data are always kept separated.
cmd.Parameters.Add("teacher", OleDbType.VarChar).Value = teacher
con.Open()
' No need to fill a whole dataset, just to get one integer back
Return DirectCast(cmd.ExecuteScalar(), Integer)
'No need to call con.Close() manually. The Using block takes care of it for you.
End Using
End Function
Here it is again, without all the extra comments:
Public Function GetStudentCount(teacher As String) As Integer
Const sql As String = "select COUNT(name) from Info where teacher = ?"
Using con As New OleDbConnection(conn), _
cmd As New OleDbCommand(sql, con)
cmd.Parameters.Add("teacher", OleDbType.VarChar).Value = teacher
con.Open()
Return DirectCast(cmd.ExecuteScalar(), Integer)
End Using
End Function
Call it like this:
Private Sub DataGridView1_Click(sender As System.Object, e As System.EventArgs) Handles DataGridView1.Click
lblTeacher.Text = DataGridView1.CurrentRow.Cells("teacher").Value.ToString()
lblCount.Text = GetStudentCount(lblTeacher.Text).ToString()
End Sub

Data type mismatch in criteria expression. MS Access VB

' OK button
Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK.Click
Dim con As New OleDbConnection("Provider=Microsoft.jet.oledb.4.0;data source=C:\Users\Jill\Desktop\saddbase\Sadsystem\Sadsystem\bin\Debug\tenant.mdb")
Dim cmd As OleDbCommand = New OleDbCommand("SELECT * FROM info WHERE TN_ID = '" & UsernameTextBox.Text & "' AND Password = '" & PasswordTextBox.Text & "' ", con)
con.Open()
Dim sdr As OleDbDataReader = cmd.ExecuteReader()
' If the record can be queried, Pass verification and open another form.
If (sdr.Read() = True) Then
MessageBox.Show("The user is valid!")
Me.Hide()
Else
MessageBox.Show("Invalid Tenant ID or password!")
End If
When I run the program there's an error in cmd.ExecuteReader(). Data type mismatch in criteria expression please help how to fix this error.
In your query you pass two strings for the TN_ID and Password fields.
Probably the TN_ID is a numeric field and you don't need to put quotation marks around it and I find really strange that you pass the value of a UserName textbox.
Said that, I wish to examine your query because there are potential problems that you have not seen:
First of all PASSWORD is a reserved Keyword and thus you need to use Square Brackets around it.
Second, do not use string concatenation to build sql commands but use a parameterized query like this
Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK.Click
Dim commandText = "SELECT * FROM info WHERE TN_ID = ? AND [Password] = ?"
Using con = New OleDbConnection(......))
Using cmd = New OleDbCommand(commandText,con))
con.Open()
' If the TN_ID is really a numeric field then you need '
' to conver the first parameter to a number '
' cmd.Parameters.AddWithValue("#p1", Convert.ToInt32(UsernameTextBox.Text))'
cmd.Parameters.AddWithValue("#p1", UsernameTextBox.Text)
cmd.Parameters.AddWithValue("#p2", PasswordTextBox.Text)
Using sdr As OleDbDataReader = cmd.ExecuteReader())
.....
End Using
End Using
End Using
End Sub
As a side note, not related to your problem, consider also to NOT store password in plain text in the database. There are techniques that HASH the password text and store the result in the database. In this way none can get the password simply looking at the database file. See the details in this question
Private Sub SumOfIR()
Try
Dim con As New System.Data.OleDb.OleDbConnection(ConnectionString)
Dim com As New System.Data.OleDb.OleDbCommand
con.Open()
com.Connection = con
com.CommandText = "Select Sum(IR) from Spectrum where StdNu='" + TxtNuTeif.Text + "'"
com.Parameters.Clear()
Dim SumIR As OleDbDataReader = com.ExecuteScalar
LblIRTeif.Text = com.ExecuteScalar("SumIR").ToString
con.Close()
com.Dispose()
Catch ex As Exception
BehComponents.MessageBoxFarsi.Show(ex.ToString, "", BehComponents.MessageBoxFarsiButtons.OK, MessageBoxIcon.Warning)
End Try
End Sub