Sorry in advance, Im new to vb,
Im creating a small application for assignment as a MCQ quiz, Im using the same form but use the function of [nextques] proceed to next question and use [answer] to update the user answer to database(access).
I previously uses SQL Server and it work good but due to i need to run the application in school's computer where they wont allow me to install anything, I have no idea at all then decided to use access as it is easier to export and include it in debug file.
Ive go through some topics as well as did some changes however the problem persist. I set the [input] in access as integer, i did put parameter on it but it still not working.
ERROR code : Data type mismatch in criteria expression
Public Function answer(ans As Integer)
Try
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=mom.mdb;"
con.Open()
cmd.Connection = con
' Update the answer 1234 (as abcd) according to id in lblnum.text
Dim updatecmd As String = "UPDATE question SET [input] = #ans WHERE id = '" & lblnum.Text & "'"
cmd.Parameters.AddWithValue("#ans", ans)
cmd.CommandText = updatecmd
updatecmd = cmd.ExecuteNonQuery()
con.Close()
'Proceed to next question by calling Function NextQues
nextques()
Catch ex As Exception
MsgBox(ex.Message)
End Try
Return 0
End Function
I tried also to make it like this however another error shows: COM object that has been separated from its underlying RCW cannot be used
Public Function answer(ans As Integer)
Dim countid As Integer = 1
Try
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=mom.mdb;"
con.Open()
cmd.Connection = con
Dim updatecmd As String = "UPDATE question SET [input] = #ans WHERE id = #countid"
cmd.Parameters.AddWithValue("#countid", countid)
cmd.Parameters.AddWithValue("#ans", ans)
cmd.CommandText = updatecmd
updatecmd = cmd.ExecuteNonQuery()
countid = countid + 1
con.Close()
'Proceed to next question by calling Function NextQues
nextques()
Catch ex As Exception
MsgBox(ex.Message)
End Try
Return 0
End Function
change this line
Dim updatecmd As String = "UPDATE question SET [input] = #ans WHERE id = '" & lblnum.Text & "'"
to
Dim updatecmd As String = "UPDATE question SET [input] = #ans WHERE id = " & lblnum.Text
Related
Is it possible to read HasRow and then Update ?
This is the code what I have tried so far :
If conn.State = ConnectionState.Closed Then
conn.Open()
End If
Dim sqlcmd As New MySqlCommand("SELECT * FROM tbl_online_attendance where employees_id = '" & lvRealAtt.Items(itms).SubItems(0).Text & "' and in_time = '" & lvRealAtt.Items(itms).SubItems(1).Text & "' ", conn)
Dim dr As MySqlDataReader
dr = sqlcmd.ExecuteReader
If dr.HasRows Then
Dim query As String
query = "UPDATE tbl_online_attendance SET out_time = '" & lvRealAtt.Items(itms).SubItems(2).Text & "' where employees_id = '" & lvRealAtt.Items(itms).SubItems(0).Text & "' and in_time = '" & lvRealAtt.Items(itms).SubItems(1).Text & "' "
sqlcmd.Connection = conn
sqlcmd.CommandText = query
sqlcmd.ExecuteNonQuery() 'It error in this part
Else
End If
But it give's me error saying:
There is already an open DataReader associated with this Connection which must be closed first
Please avoid commenting Use Parameters Your code is Prone to SQL injection attack
You should not have to check connection state if you keep your connections local to the method that they are used. Database objects like connections and commands need to be closed and disposed as soon as possible. Using...End Using blocks take care of this for you even if there is an error. Don't open a connection until directly before the .Execute....
Don't pull down data when you only need Count. .ExecuteScalar returns the first column of the first row of the result set, which in this case, is the Count. If you have a large table you need to look into If Exists which will stop as soon it finds a match whereas Count looks at the whole table.
Always use Parameters. Never concatenate strings to build sql queries to avoid sql injection. I had to guess at the datatypes of the parameters. Check your database to get the actual types and adjust the code accordingly.
Private Sub OPCode(ByVal itms As Integer)
Dim RowCount As Integer
Using conn As New MySqlConnection("Your connection string"),
sqlcmd As New MySqlCommand("SELECT Count(*) FROM tbl_online_attendance where employees_id = #id and in_time = #inTime;", conn)
sqlcmd.Parameters.Add("#id", MySqlDbType.Int32).Value = CInt(lvRealAtt.Items(itms).SubItems(0).Text)
sqlcmd.Parameters.Add("#inTime", MySqlDbType.String).Value = lvRealAtt.Items(itms).SubItems(1).Text
conn.Open()
RowCount = CInt(sqlcmd.ExecuteScalar)
If RowCount > 0 Then
sqlcmd.CommandText = "UPDATE tbl_online_attendance SET out_time = #outTime where employees_id = #id and in_time = #inTime;"
sqlcmd.Parameters.Add("#outTime", MySqlDbType.String).Value = lvRealAtt.Items(itms).SubItems(2).Text
sqlcmd.ExecuteNonQuery()
End If
End Using
End Sub
Every SqlDataReader needs to be closed before you could execute another query.
so i suggest you to separate the sqlreader and the update query, put the reader into a boolean function to check either a row with those parameters exist or not.
Private Function HasRow(ByVal employeeid As Integer, ByVal date as DateTime) As Boolean
HasRow = False
Dim reader As SqlDataReader
'do select query here
'use the if reader.Read if you want to
HasRow = reader.HasRows
reader.Close()
End Function
Call the function before updating, if it's True then proceed the update. Let's say we put it into a Update Sub.
Private Sub Update()
If HasRows(parameters here) Then
'update query here
End If
End Sub
I used NuGet Package Manager to install SQLite package in my Visual Basic 2015 Project so that i can use it in my application. The problem i am facing is that i have a sub in my application whose code is indicated below that i am using to update a table in SQLite but it does not update the values.
AddErrors is another sub that adds the errors that are captured by the try catch to the same SQLite database but different table and works fine. Can you tell me what i am doing wrong.
I have tried both the commented and the uncommitted code with both not updating the database and not throwing any errors.
Public Sub PostedLink(ByVal id As String, ByVal link As String)
Dim query As String = "UPDATE Table SET torf = 1 , link = '" & link & "' WHERE id = '" & id & "';"
Dim affectedRows As Integer = 0
Try
Using con As New SQLiteConnection(connectionString)
con.Open()
Using cmd As New SQLiteCommand(con)
cmd.CommandTimeout = 20
cmd.CommandText = query
'Dim dr As SQLiteDataReader
'dr = cmd.ExecuteReader()
affectedRows = cmd.ExecuteNonQuery()
End Using
con.Close()
End Using
Catch ex As Exception
AddErrors("Updating table", ex.ToString)
End Try
End Sub
The table i am trying to update has the following structure.
CREATE TABLE Table
(
id VARCHAR(100) PRIMARY KEY NOT NULL,
text VARCHAR(100),
link VARCHAR(254) DEFAULT "",
torf BOOLEAN NOT NULL DEFAULT 0
);
Solution by OP.
I changed the code to use parameterized query as follows and it worked flawlessly.
Public Sub PostedLink(ByVal id As String, ByVal link As String)
Dim query As String = "UPDATE Table SET torf = 1, link = #link WHERE id = #id;"
Dim affectedRows As Integer = 0
Try
Using con As New SQLiteConnection(connectionString)
con.Open()
Using cmd As New SQLiteCommand(con)
cmd.CommandTimeout = 20
cmd.CommandText = query
With cmd.Parameters
.Add(New SQLiteParameter("#link", link))
.Add(New SQLiteParameter("#id", id))
End With
'Dim dr As SQLiteDataReader
'dr = cmd.ExecuteReader()
affectedRows = cmd.ExecuteNonQuery()
End Using
con.Close()
End Using
Catch ex As Exception
AddErrors("Updating table", ex.ToString)
End Try
End Sub
i have this code [Sample 1] and it is working.
It show me ID for actual inserted data from Access, but I would like to use something like in [Sample 2], but i still don't know find out how to write right code for that. :(
Sample 1 [working]
Dim query As String = "Insert Into REGISTER (DC,Price) Values (?,?)"
Dim FindID As String = "Select ##Identity"
Dim ID As Integer
Dim connect As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\sourcepath\db.accdb"
Using conn As New OleDbConnection(connect)
Using cmd As New OleDbCommand(query, conn)
conn.Open()
cmd.Parameters.AddWithValue("", Format(Now, "yy") & Format(DatePart(DateInterval.WeekOfYear, Now), "00"))
cmd.Parameters.AddWithValue("", PriceTextBox.Text)
cmd.ExecuteNonQuery()
cmd.CommandText = FindID
ID = cmd.ExecuteScalar()
conn.Close()
End Using
End Using
Sample 2 [here I need help]
This code write data to Access but I can't get the ID.
(Part for get ID isn't in code)
Dim rw As DataRow
rw = RegisterDBDataSet.REGISTER.NewRow
rw.Item("Price") = Format(Now, "dd.MM.yyyy")
rw.Item("DC") = Format(DatePart(DateInterval.WeekOfYear, Now), "00"))
Try
RegisterDBDataSet.REGISTER.Rows.Add(rw)
REGISTERTableAdapter.Update(RegisterDBDataSet.REGISTER)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
what must i put into code for get ID in sample 2?
thanks
You should add an handler for the RowUpdated event of the OleDbDataAdapter, then in this handler execute your command to retrieve the Identity value generated by your query
RegisterDBDataSet.REGISTER.Rows.Add(rw)
AddHandler REGISTERTableAdapter.RowUpdated, AddressOf(rowUpdateEvent)
REGISTERTableAdapter.Update(RegisterDBDataSet.REGISTER)
.....
Sub rowUpdateEvent(sender As Object , args As OleDbRowUpdatedEventArgs)
Dim identity = "SELECT ##IDENTITY"
Dim cmd = New OleDbCommand(identity, args.Command.Connection)
ID = cmd.ExecuteScalar()
End Sub
Of course that ID variable is global to your form code
I am trying to do an update query from a winform with two variables without using a dataset.
I assign both of my variable and then run the query but it keeps giving the error that zcomp is not a valid column name. Which of course is true but I tell it which column before I say = zcomp. Below is my code that is running the query.
Dim zamnt As Integer = WopartsDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
Dim zcomp As Integer = gridRow.Cells(0).Value
Dim con As New SqlConnection
Dim cmd As New SqlCommand
Try
con.ConnectionString = "Data Source=MNT-MGR-2\SQLEX;Initial Catalog=MT;Integrated Security=True"
con.Open()
cmd.Connection = con
cmd.CommandText = "UPDATE dbo.sparts SET [dbo.sparts.QtyonHand] = [dbo.sparts.QtyonHand] - zamnt WHERE [ComponentID] = zcomp"
cmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show("Error while updating record on table..." & ex.Message, "Update Records")
Finally
con.Close()
gridRow.Cells(4).Value = "Yes"
End Try
I have tried it several different ways. It works just fine if I take out the zamnt and zcomp and put the actual number values that are in the variables. Please help I've been searching all day for a way to use the variables with this update query.
Thanks,
Stacy
You are probably looking for how to use parameters in ADO.NET. For your example, it can look like this:
cmd.Parameters.Add("#zamnt", zamnt);
cmd.Parameters.Add("#zcomp", zcomp);
Put these two lines anywhere before ExecuteNonQuery.
Because parameters need a # prefix, you would also need to change your query to say #zamnt instead of just zamnt, and same for zcomp:
cmd.CommandText = "UPDATE dbo.sparts SET [dbo.sparts.QtyonHand] = [dbo.sparts.QtyonHand] - #zamnt WHERE [ComponentID] = #zcomp"
In addition to using parameters, the "Using" statement closes the connection and disposes resources:
Dim zamnt As Integer = WopartsDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
Dim zcomp As Integer = gridRow.Cells(0).Value
Try
Using con As New SqlConnection("Data Source=MNT-MGR-2\SQLEX;Initial Catalog=MT;Integrated Security=True")
con.Open()
Using cmd As New SqlCommand
cmd.CommandText = "UPDATE dbo.sparts SET [dbo.sparts.QtyonHand] = [dbo.sparts.QtyonHand] - #zamnt WHERE [ComponentID] = #zcomp"
cmd.Parameters.AddWithValue("#zamt", zamnt)
cmd.Parameters.AddWithValue("#zcomp", zcomp)
cmd.ExecuteNonQuery()
End Using
End Using
Catch ex As Exception
MessageBox.Show("Error while updating record on table..." & ex.Message, "Update Records")
Finally
con.Close()
gridRow.Cells(4).Value = "Yes"
End Try
have u tried this?
Dim zamnt As Integer = WopartsDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
Dim zcomp As Integer = gridRow.Cells(0).Value
Dim con As New SqlConnection
Dim cmd As New SqlCommand
Try
con.ConnectionString = "Data Source=MNT-MGR-2\SQLEX;Initial Catalog=MT;Integrated Security=True"
con.Open()
cmd.Connection = con
cmd.CommandText = "UPDATE dbo.sparts SET [dbo.sparts.QtyonHand] = [dbo.sparts.QtyonHand] -" + zamnt + " WHERE [ComponentID] =" + zcomp
cmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show("Error while updating record on table..." & ex.Message, "Update Records")
Finally
con.Close()
gridRow.Cells(4).Value = "Yes"
End Try
Im running the following code to tell if a user excists on a database - standard stuff. Obviously once the code is run a boolean true or false will be returned if there is a result. If a result is found i want to store the ID of the said result. Can anyone tell me how'd id go about doing this?
code:
Username = txtUserName.Text
Password = txtPassword.Text
dbConnInfo = "PROVIDER=Microsoft.Jet.OLEDB.4.0; Data Source = C:\Users\Dave\Documents\techs.mdb"
con.ConnectionString = dbConnInfo
con.Open()
Sql = "SELECT * FROM techs WHERE userName = '" & Username & "' AND '" & Password & "'"
LoginCommand = New OleDb.OleDbCommand(Sql, con)
CheckResults = LoginCommand.ExecuteReader
RowsFound = CheckResults.HasRows
con.Close()
If RowsFound = True Then
MsgBox("Details found")
TechScreen.Show()
Else
MsgBox("Incorrect details")
End If
There are a lot of problems with the code snippet you posted. Hopefully, I can help you correct these problems.
In order to load the ID of the result you'll want to use SqlCommand.ExecuteScalar() as this is optimized to pull back one result from Sql.
As to what is wrong with your code, you're wide open to Sql Injection attacks and you should be using Parametrized Queries as shown in my sample below.
Public Function AddProductCategory( _
ByVal newName As String, ByVal connString As String) As Integer
Dim newProdID As Int32 = 0
Dim sql As String = _
"INSERT INTO Production.ProductCategory (Name) VALUES (#Name); " _
& "SELECT CAST(scope_identity() AS int);"
Using conn As New SqlConnection(connString)
Dim cmd As New SqlCommand(sql, conn)
cmd.Parameters.Add("#Name", SqlDbType.VarChar)
cmd.Parameters("#Name").Value = newName
Try
conn.Open()
newProdID = Convert.ToInt32(cmd.ExecuteScalar())
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Using
Return newProdID
End Function
Source: MSDN