please help retrieving data to put it on label - vb.net

I want to retrieve the price from table Products to use it as label2 on the orderinfo form.
Dim con As New OleDb.OleDbConnection
Dim com As New OleDb.OleDbCommand
com = New OleDb.OleDbCommand("Select Price FROM Products WHERE ProductName='" & ListBox1.SelectedItem.ToString & "'", con)
con.ConnectionString = "PROVIDER = Microsoft.ACE.OLEDB.12.0; Data Source=Database_AntoninosCafe.accdb"
con.Open()
com.ExecuteNonQuery()
orderInfo.Label2.Text = retrieve data
con.Close()

The correct approach to your simple problem
Dim cmdText = "Select Price FROM Products WHERE ProductName=?"
Using con = New OleDb.OleDbConnection( ... connection string here ...)
Using com = New OleDb.OleDbCommand(cmdText, con)
com.Parameters.AddWithValue("#p1", ListBox1.SelectedItem.ToString)
con.Open()
Using reader = com.ExecuteReader()
if reader.Read() Then
orderInfo.Label2.Text = reader("Price").ToString
End If
End Using
End Using
End Using
The first thing is to use a parameterized query to avoid sql injections and parsin problems, then use the Using statement to encapsulate you disposable object in a block of code that ensures the closing and disposing of these objects.
Finally, to read data from a datatable you use the ExecuteReader command that returns an OleDbDataReader instance. It is this instance that could be used to extract the data from your database
As a side note, I have used, as placeholder for the parameter, a question mark. This is the predefined symbol used by OleDb. But, when adding the parameter value to the collection, I have used a different name (#p1). This is acceptable because OleDb do not use the parameter names to find the corresponding placeholders in the query text like the SqlClient or other providers, but use the position of the placeholder. So, first placeholder replaced by the first parameter and so on.

Related

'No value given for one or more required parameters.' Error, Can't get over it

I'm trying to take a Yes/No value from my database on Access and make it so if the Yes/No is checked on Access it will check it on the form. Although I keep getting
System.Data.OleDb.OleDbException: 'No value given for one or more required parameters.'
On the line Dim rs As OleDbDataReader = SQLCmd.ExecuteReader()
Sorry if it's a really easy and stupid mistake, I'm a college student and googling isn't helping me figure this one out.
cn.Open()
Dim SQLCmd As New OleDbCommand
SQLCmd.Connection = cn
SQLCmd.CommandText = "SELECT *, staffIn FROM Staff WHERE staffName = DarrenSloan"
Dim rs As OleDbDataReader = SQLCmd.ExecuteReader()
While rs.Read
Dim DisplayValue As String = rs("staffIn")
SQLCmd.Parameters.AddWithValue("#inorout", inOrOut.Checked)
SQLCmd.ExecuteNonQuery()
End While
cn.Close()
I know this is an old post but I seem to remember that OleDb does not support named parameters.
Also, pretty sure that DarrenSloan should be surrounded by single quotes, like any string value. And indeed, reusing the SQL command like this is not the way to do it.
The CommandText:
SQLCmd.CommandText = "SELECT *, staffIn FROM Staff WHERE staffName = DarrenSloan"
does not contain any parameter.
Thus, the parameter inorout has no effect:
SQLCmd.Parameters.AddWithValue("#inorout", inOrOut.Checked)
Either use two statements, one SELECT and one UPDATE.
Or use a different mechanism like a databound grid. Maybe you are using a datagridview control to display the data. Then there are different techniques to keep the data in sync. It depends on how you choose to render the data on your form.
Firstly, get rid of the loop. You would only use a loop if you were expecting more than one record. By the looks of it, you are expecting only one record, so no loop.
Secondly, stop calling ExecuteNonQuery. That is for making changes to the database, which you're obviously not trying to do. You obviously know how to get data from the query because you're doing it here:
Dim DisplayValue As String = rs("staffIn")
If you want to get data from another field, do the same thing. You can then use that data in whatever way you like, e.g.
Using connection As New OleDbConnection("connection string here"),
command As New OleDbCommand("SELECT * FROM Staff WHERE staffName = 'DarrenSloan'", connection)
connection.Open()
Using reader = command.ExecuteReader()
If reader.Read() Then
Dim inOrOut = reader.GetBoolean(reader.GetOrdinal("inorout"))
inOrOutCheckBox.Checked = inOrOut
End If
End Using
End Using
Notice that I have wrapped the text literal in the SQL in single-quotes? I would expect that you would normally not want to hard-code a name there, but use input from the user instead, In that case, you would use a parameter, e.g.
Using connection As New OleDbConnection("connection string here"),
command As New OleDbCommand("SELECT * FROM Staff WHERE staffName = #staffName", connection)
command.Parameters.Add("#staffName", OleDbType.VarChar, 50).Value = staffNameTextBox.Text
connection.Open()
Using reader = command.ExecuteReader()
If reader.Read() Then
Dim inOrOut = reader.GetBoolean(reader.GetOrdinal("inorout"))
inOrOutCheckBox.Checked = inOrOut
End If
End Using
End Using

Deleting record by ID

I'm trying to delete a record in my database via the ID, but it says
"Data Type mismatch in criteria expression."
Why do you think so?
Private Sub testdelete()
'THIS SAVES TO THE DEBUG ACCESS DATABASE!!!!!
Dim conn As New OleDbConnection
conn = New OleDbConnection
dbprovider = "Provider=Microsoft.ACE.OLEDB.12.0;"
Dim databasePath = "Data Source = FULL YUGIOH ACCESS DATABASE.accdb;"
conn.ConnectionString = dbprovider & databasePath
Dim Stringc As String = "delete from cmon11 where ID='" & TextBox2.Text & "'"
Dim command As OleDbCommand = New OleDbCommand(Stringc, conn)
Try
conn.Open()
command.ExecuteNonQuery()
command.Dispose()
conn.Close()
Catch ex As Exception
MsgBox(ex.Message)
Finally
conn.Dispose()
End Try
End Sub
As noted in the comments, a data type mismatch occurs because the where clause in your SQL statement is attempting to compare the value of your field ID (which you have stated is an integer) with a string value.
Following the concatenation, the SQL code might look something like this:
delete from cmon11 where ID='123'
Here, '123' is a string, not an integer - to supply an integer value, you would remove the single quotes to yield:
delete from cmon11 where ID=123
However, this does not solve the underlying issue of the potential for SQL injection when constructing SQL statements using values held by textboxes permitting arbitrary text input.
After modifying your code to remove the single quotes, consider the implications of your user typing the following into the textbox:
;drop table cmon11;--
The solution is to use parameters such that the query will fail in such circumstances, rather than performing unwanted actions. This answer from Erik is an excellent reference detailing the various ways to parameterise queries in MS Access.
The Using...End Using ensure that your database objects are closed and disposed even if there is an error.
Always use parameters to minimize type mismatches and protect against Sql Injection. I guessed at Integer for the datatype of the Id field but you will have to check your database for the actual datatype.
Private Sub testdelete()
Using conn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source = FULL YUGIOH ACCESS DATABASE.accdb;")
Using command As New OleDbCommand("Delete From cmon11 Where ID= #ID;", conn)
command.Parameters.Add("#ID", OleDbType.Integer).Value = CInt(TextBox2.Text)
conn.Open()
command.ExecuteNonQuery()
End Using
End Using
End Sub

How to display a column total from an access databse in a textbox in vb?

I'm trying to display the sum total of a column in a access databse for a vb program. I've written the following code, but it doesn't do anything - the textbox is still on the default value when the program runs.
Dim command As OleDbCommand
Dim data_reader As OleDbDataReader
connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=H:\Computing\Year 13\Computing Project Course-work\Database41.accdb")
command = New OleDbCommand("SELECT SUM(Distance) As Int32 FROM [Table3];", Conn)
dr = command.ExecuteReader
While dr.Read
TextBox7.Text = dr.GetValue(4)
End While
You have only one column returned from that command.
You can't use try to read a value from column at index 4, it simply doesn't exist. And you should get an exception for this attempt. If you don't see the exception only means that you have somewhere an empty try/catch block that hides your error. You should use dr.GetValue(0) but giving the fact that you use a scalar function in your query (SUM) then it is better to use ExecuteScalar
Using connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=H:\Computing\Year 13\Computing Project Course-work\Database41.accdb")
Using command = New OleDbCommand("SELECT SUM(Distance) As Total FROM [Table3];", Conn)
Dim total = Convert.ToInt32(command.ExecuteScalar)
TextBox7.Text = total.ToString
End Using
End Using
(Notice that disposable objects like the connection, commands, and Readers should be disposed when you have finished to use them. The using block ensures this)

Which is the correct way to send Update Command to SQL Server

ConnString = Connection String // StrQuery = Sql Query String
First Method
Dim con As New SqlConnection(ConnString)
Dim adapter As New SqlDataAdapter
con.Open()
adapter.InsertCommand = New SqlCommand(StrQuery, con)
adapter.InsertCommand.ExecuteNonQuery()
con.Close()
Second Method
Dim con As New SqlConnection(ConnString)
Dim cmd As SqlCommand
cmd = New SqlCommand(StrQuery, con)
con.Open()
cmd.ExecuteNonQuery()
con.Close()
Data can be inserted to Database using both ways. I want to know which is the better way, and what difference exactly is between them. Any drawbacks in one or the other. Thanks.
The first way is wrong. The second way is correct. You would use a data adapter to Fill a DataTable, the contents of which you would edit. Then you'd use the same data adapter to Update the database with the changes from the DataTable. If you're not using a DataTable then a data adapter is pointless. It is supposed to group together the four CRUD operations. If you're just issuing an UPDATE directly then use the second option.

Cant save or update my SQL Server tables using vb.net

I am a complete beginner to .net and am confused at some basic things. Please help.
First of all the table I create and populate (by right clicking tables in server explorer) disappear once I restart the computer. how do I keep them.
Is there any better place/interface to type SQL queries in vb.net than the command prompt.
In the following code:
Dim cn As SqlConnection = New SqlConnection(strConnection)
cn.Open( )
' Create a data adapter object and set its SELECT command.
Dim strSelect As String = _
"SELECT * FROM Categories"
Dim da As SqlDataAdapter = New SqlDataAdapter(strSelect, cn)
' Load a data set.
Dim ds As DataSet = New DataSet( )
da.Fill(ds, "Categories")
This far the code runs fine but just to gain better understanding, I would like to ask that
while data from SQL Server database was saved into da in accordance to the query, why do we need to save/transfer it in the dataset object ds.
Is there any additional benefit of SqlCommand over SqlDataAdapter besides speed?
Dim autogen As New SqlCommandBuilder(da)
Dim dt As DataTable = ds.Tables("Categories")
' Modify one of the records.
Dim row As DataRow = dt.Select("CategoryName = 'Dairy Products'")(0)
row("Description") = "Milk and stuff"
gives an error when I use it with
da.Update(ds, "Categories")
regarding dt.select not returning any value.
What is the way out?
to answer your questions :
The tables you create with the server explorer are IN MEMORY. Same goes for dataset, they are in-memory representation of your table. As for your 2nd example, the DS you use isnt filled when you try to get the DT. hence why the DT is empty.
If your starting, I would suggest you go look into Linq-to-Sql (http://msdn.microsoft.com/en-us/library/bb425822.aspx) for a more up-to-date way of doing sql in .net ( I think its 4.0 framework)
As for the 2nd point, I'd say normally you should use store procedure for most of your sql commands .. the sqlcommand is use like this
Try
Cmd = New SqlClient.SqlCommand("st_InventoryStatus_Or_AnyStoreProcName_Or_ASqlQuery")
Cmd.CommandTimeout = 300 'not really needed'
Cmd.CommandType = CommandType.StoredProcedure 'you can type CommandType.Text here to use directly your "Select * from Category"'
Cmd.Parameters.Clear() 'just to be sure its empty, its not mandatory'
Cmd.Parameters.Add("#idCategory", SqlDbType.Int).Value = myCategory.Id 'here are the parameters of your store proc, or of your query ("select * from Category where Category.id = #Id")'
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Information)
End Try