Cell not updated - VB.net, oledb - vb.net

Ive been wrestling with the code below for a long time now, and just when i thought it works it doesnt, and it doesnt even give me an error.
Dim sql As String = "UPDATE " & table & " SET ArithmeticScore = #score WHERE DateAscending = " & todaysdate
Using connection As New OleDbConnection(conn)
Using command As New OleDbCommand(sql, connection)
connection.Open()
command.Parameters.Add("#score", OleDbType.Decimal).Value = score
MsgBox("score was added = " & score)
command.ExecuteNonQuery()
connection.Close()
End Using
End Using
todaysdate currently holds the value 27/04/2020 as date
conn holds the connection string, table holds the table name.
The messagebox outputs what it is meant to, with score having a decimal value that should be added into the table.
The purpose of this code is to update the ArithmeticScore column in the table, Where DateAscending = 27/04/2020. When the program is finished, and i check the database, the cell remains blank. Why could this be?

This is because executed query can not find required record.
Try to set correct type for sql parameter for DateAscending column.
Dim sql As String =
$"UPDATE {table} SET ArithmeticScore = #score WHERE DateAscending = #todaysdate"
Using connection As New OleDbConnection(conn)
Using command As New OleDbCommand(sql, connection)
command.Parameters.Add("#score", OleDbType.Decimal).Value = score
command.Parameters.Add("#todaysdate", OleDbType.Date).Value = DateTime.Now.Date
connection.Open()
Dim affectedRows As Integer = command.ExecuteNonQuery()
' Check or display that affectedRows is greater than zero
End Using
End Using

Related

Dividing by Zero?! - Datareader OleDB VB.Net

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.

How do I read HasRow then Update?

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

Converting VBA function to VB.net to get sql data

I am trying to convert VBA code into VB.net and I have made it to a point but I can't convert resultset into vb.net. RS was 'dim as resultset' in VBA, thought i could just change it to dataset but am getting errors with the '.fields' and other options?
Function GetG(sDB As String, sServ As String, sJob As String) As String
'sDB = Database name, sServ = Server\Instance, path = job.path
Dim conString As String = ("driver={SQL Server};server = " &
TextBox1.Text & " ; uid = username;pwd=password:database = " &
TextBox2.Text)
Dim RS As DataSet
Dim conn As SqlConnection = New SqlConnection(conString)
Dim cmd As SqlCommand
conn.Open()
'This is where my problems are occuring
cmd = New SqlCommand("SELECT [ID],[Name] FROM dbo.PropertyTypes")
Do While Not RS.Tables(0).Rows.Count = 0
If RS.Fields(1).Value = sJob Then
GetG = RS.Fields(0).Value
GetG = Mid(GetG, 2, 36)
Exit Do
End If
DataSet.MoveNext
Loop
conn.Close
End Function
Based on my understanding and some guesswork, here is what I came up with for what I think you're wanting.
As I stated in my comment above, it appears you can just use a WHERE clause to get the exact record you want (assuming a single instance of sJob appears in the name column).
Build the connectionstring off the input arguments, not controls on your form. That is after all why you allow for arguments to be passed along. Also note that there is a SqlCommandBuilder object that may be of interest. But for now
Function GetG(sDB As String, sServ As String, sJob As String) As String
'we'll pretend your connectionstring is correct based off of the sDB and sServ arguments
Dim conStr As String = ("driver={SQL Server};server = " & sServ & " ; uid = username;pwd=password:database = " & sDB)
'Create a connection and pass it your conStr
Using con As New SqlConnection(conStr)
con.Open() 'open the connection
'create your sql statement and add the WHERE clause with a parameter for the input argument 'sJob'
Dim sql As String = "SELECT [ID], [Name] FROM dbo.PropertyTypes WHERE [Name] = #job"
'create the sqlCommand (cmd) and pass it your sql statement and connection
Using cmd As New SqlCommand(sql, con)
'add a parameter so the command knows what #job holds
cmd.Parameters.Add(New SqlParameter("#job", SqlDbType.VarChar)).Value = sJob
'Now that have the command built, we can pass it to a reader object
Using rdr As SqlDataReader = cmd.ExecuteReader
rdr.Read()
'i admin i'm a little confused here on what you are
'trying to achieve so ID may not be what you are
'really wanting to get a substring of.
Return rdr("ID").ToString.Substring(2, 36)
End Using
End Using
End Using
End Function
An example to see if this is working could be to call a messagebox do display the result. For this example, I'm going to pretend that TextBox3 holds the sJob you're wanting. With that knowledge, you could simply do:
MessageBox.Show(GetG(TextBox2.Text, TextBox1.Text, TextBox3.Text))
This should then produce the result in a messagebox.
It seems that you're not filling your DataSet. So, when you try to loop through it, it's uninitialized or empty.
Check this answer to see an example: Get Dataset from DataBase

Updating 3 Rows (fixed) Using 1 UPDATE Statement

So far I have this code updating only 1 row but is there a way to specify the three rows? (3 different ID's)
Public Shared Sub UpdatePrice(ByVal NewPrice As Decimal, ByVal id As Integer)
Dim dtoffenseinfo As New DataTable
If Not DBConnection.State = ConnectionState.Open Then
'open connection
DBConnection.Open()
Else
End If
cmd.Connection = DBConnection
cmd.CommandText = "UPDATE tblStockPrice " & _
" SET Price=" & NewPrice & " WHERE id=" & id & ""
cmd.ExecuteNonQuery()
DBConnection.Close()
End Sub
I assume I need 2 more parameters for the other two rows and that would be fine.
You can use one UPDATE statement with an appropriate WHERE clause to affect multiple records but, if you want to affect each record differently, calling ExecuteNonQuery once is not a very good option. Just create one command with appropriate parameters and then you can set the Value of each parameter multiple times to affect multiple records, e.g.
Using connection As New SqlConnection("connection string here"),
command As New SqlCommand("UPDATE MyTable SET Price = #Price WHERE Id = #Id", connection)
Dim priceParameter = command.Parameters.Add("#Price", SqlDbType.Money)
Dim idParameter = command.Parameters.Add("#Id", SqlDbType.Int)
Dim prices = {12.45, 132.67, 9.8}
Dim ids = {1, 19, 56}
connection.Open()
For i = 0 To 2
priceParameter.Value = prices(i)
idParameter.Value = ids(i)
command.ExecuteNonQuery()
Next
End Using

How do I assign the results of an SQL query to multiple variables in VB.NET?

This is my first attempt at writing a program that accesses a database from scratch, rather than simply modifying my company's existing programs. It's also my first time using VB.Net 2010, as our other programs are written in VB6 and VB.NET 2003. We're using SQL Server 2000 but should be upgrading to 2008 soon, if that's relevant.
I can successfully connect to the database and pull data via query and assign, for instance, the results to a combobox, such as here:
Private Sub PopulateCustomers()
Dim conn As New SqlConnection()
Dim SQLQuery As New SqlCommand
Dim daCustomers As New SqlDataAdapter
Dim dsCustomers As New DataSet
conn = GetConnect()
Try
SQLQuery = conn.CreateCommand
SQLQuery.CommandText = "SELECT Customer_Name, Customer_ID FROM Customer_Information ORDER BY Customer_Name"
daCustomers.SelectCommand = SQLQuery
daCustomers.Fill(dsCustomers, "Customer_Information")
With cboCustomer
.DataSource = dsCustomers.Tables("Customer_Information")
.DisplayMember = "Customer_Name"
.ValueMember = "Customer_ID"
.SelectedIndex = -1
End With
Catch ex As Exception
MsgBox("Error: " & ex.Source & ": " & ex.Message, MsgBoxStyle.OkOnly, "Connection Error !!")
End Try
conn.Close()
End Sub
I also have no problem executing a query that pulls a single field and assigns it to a variable using ExecuteScalar. What I haven't managed to figure out how to do (and can't seem to hit upon the right combination of search terms to find it elsewhere) is how to execute a query that will return a single row and then set various fields within that row to individual variables.
In case it's relevant, here is the GetConnect function referenced in the above code:
Public Function GetConnect()
conn = New SqlConnection("Data Source=<SERVERNAME>;Initial Catalog=<DBNAME>;User Id=" & Username & ";Password=" & Password & ";")
Return conn
End Function
How do I execute a query so as to assign each field of the returned row to individual variables?
You probably want to take a look at the SqlDataReader:
Using con As SqlConnection = GetConnect()
con.Open()
Using cmd As New SqlCommand("Stored Procedure Name", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add("#param", SqlDbType.Int)
cmd.Parameters("#param").Value = id
' Use result to build up collection
Using dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection Or CommandBehavior.SingleResult Or CommandBehavior.SingleRow)
If (dr.Read()) Then
' dr then has indexed columns for each column returned for the row
End If
End Using
End Using
End Using
Like #Roland Shaw, I'd go down the datareader route but an other way.
would be to loop through
dsCustomers.Tables("Customer_Information").Rows
Don't forget to check to see if there are any rows in there.
Google VB.Net and DataRow for more info.