How can i set the value from the last row in an specific column in a variable in VB.Net - vb.net

I'm develop an application using forms in vb.net with visual studio 2019
I have code in the event click for one button
Dim oda As New OleDbDataAdapter
Dim ods As New DataSet
Dim consulta As String
Dim cadena As New OleDbConnection
Dim comando As New OleDbCommand
Try
cadena.Open()
comando = New OleDbCommand("Insert into QRQC (Nombre,NumControl,Fecha,Hora,Turno)" &
"values(txt_nombre,txt_numControl,lbl_fecha,lbl_hora,cBox_turno)", cadena)
consulta = "Select *From QRQC"
oda = New OleDbDataAdapter(consulta, cadena)
ods.Tables.Add("QRQC")
oda.Fill(ods.Tables("QRQC"))
Dim row As Integer
row = ods.Tables("QRQC").Rows.Count - 1
courrentId = ods.Tables("QRQC")(row)("ID_QRQC").ToString()
frm_newPt2.lbl_folioQRQC.Text = courrentId
cadena.Close()
Catch ex As Exception
MsgBox("Error al generar el registro en la base de datos", vbCritical, "Aviso")
Console.WriteLine(ex)
cadena.Close()
GoTo skip
End Try
Everything goes perfectly, but when I delete some record on my DB this part of the code always return the value 102
courrentId = ods.Tables("QRQC")(row)("ID_QRQC").ToString()
How can i solve this problem?

First of all, your insert command is wrong, and will not work.
You have "values(txt_nombre. etc etc."
But that is just a string and NOT the actual values from the form. So you are actually going to "instert txt_nombre" into that table and NOT the value of that label or text box on the form!!!
So you need to fix and get your insert command working FIRST.
And if this is just editing data then consider using the data binder, since navigation, editing, deleting and saving of data to/from the table can occur 100% automatic whiteout ANY code on your part.
so first up is to fix that insert command. You can't JUST use a string with the names of the controls else that would actually as noted try to insert the names of the controls as text and NOT the values of the controls.
And lets clean up a few other things. No need for a dataset, since a dataset is a SET of tables - we only dealing with one table (so use a data table).
But as noted, before we mess with data tables, we have to fix that insert command.
It will, can look like this:
Dim strSQL As String
strSQL = "Insert into QRQC (Nombre,NumControl,Fecha,Hora,Turno) " &
"VALUES(#nombre,#numControl,#fecha,#hora,#turno)"
Using cmdSQL As New OleDbCommand(strSQL,
New OleDbConnection(My.Settings.TestDB))
cmdSQL.Parameters.Add("#nombre", OleDbType.Integer).Value = txt_nombre.Text
cmdSQL.Parameters.Add("#numControl", OleDbType.Integer).Value = txt_numControl.Text
cmdSQL.Parameters.Add("#fecha", OleDbType.Integer).Value = lbl_fecha.Text
cmdSQL.Parameters.Add("#hora", OleDbType.Integer).Value = lbl_hora.Text
cmdSQL.Parameters.Add("#turno", OleDbType.Integer).Value = txt_nombre.Text
cmdSQL.Connection.Open()
cmdSQL.ExecuteNonQuery()
End Using
So you have to "replace" the string values in the sql with the ACTUAL values you are using.
You also don't show where/how you setup your connection to the database. I guessed that you used the applications settings and the connection builder - so you have to change TestDB to your actual connection that you used.
The above will thus get your insert command working.
At that point, you can post a new question in that after you do a insert, how to get the new autonumber primary key, or whatever else you wanted to do, but your insert statement as written will not work.
As noted, perhaps it better to use data bound controls. This will result in a Access like design experience, and you not having to write ANY code to edit a table in vb.net.
And it not clear if the control names I used are correct (or they are even controls on the form), but if they are, then ".Text" is required to grab the values. You have to of course change (check) that the control names I used and guessed are correct.
You also have to change the data type "integer" I used in above to the correct data types. For text I recommend you use .VarWChar

Related

Deleting SQL datarow from a table swipes position of first and second row in vb.net

adding updating everything is fine even delete command is working but the strange part is after executing del command from vb.net application it swipes the position of EMPLOYEE_IDAND NAMEit shows normally in datagridviewafter adding or updating but specifically after deleting the record position of these to column changes until I stop the application and re run the entire project for debugging
Dim con As New MySqlConnection("server=localhost; user=root; password=Masoom1; database=airtech_db; convert zero datetime=true;")
Dim cmd As New MySqlCommand
Dim dt As New DataTable
Dim da As New MySqlDataAdapter
Dim sql As String
Dim DR As MySqlDataReader
Dim SQL_CMD_TXT As String
SQL_CMD_TXT = "DELETE FROM `employees` WHERE (`EMPLOYEE_ID` ='" &
EMPLOYEE_DEL_FRM.DEL_ID_TXT.Text & "'); SELECT * FROM `employees`;"
EMPLOYEE_DEL_FRM.Controls.Add(OBJECT_DATAGRIDVIEW)
With OBJECT_DATAGRIDVIEW
.Size = New Size(587, 242)
.Location = New Size(221, 171)
End With
Try
'DB CMD EXECUTION
con.Open()
With cmd
sql = SQL_CMD_TXT
.Connection = con
.CommandText = sql
End With
da.SelectCommand = cmd
da.Fill(dt)
'Command for datagridview object
With OBJECT_DATAGRIDVIEW
.DataSource = dt
'Scroll to the last row.
.Name = "MYDATAGRIDVIEW"
.FirstDisplayedScrollingRowIndex = .RowCount - 1
End With
con.Close()
Catch ex As Exception
Dim MEB = MessageBox.Show("ERROR FOR SQL CMD EXECUTION SECTION-" & ex.Message,
"SQL CMD EXECUTION", MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End Try
attaching the normal and after delete result in images
enter image description here
I am not sure I completely understood your problem, but your problem could that the datagridview generates the columns automatically. See: DataGridView.AutoGenerateColumns
Instead of doing SELECT * FROM is would better to select just the fields you need. If you add more fields to your table in the future, the columns in the datagridview may be displaced because they are in no particular order.
Rather than add the datagridview to your form at runtime:
EMPLOYEE_DEL_FRM.Controls.Add(OBJECT_DATAGRIDVIEW)
I would add it directly in the form layout (so you can see it at design time), and then customize it, bind each column to a database field. The appearance of the grid will be more predictable. Here is a small guide: How to bind datatable/list to datagridview with headers?
Relying on AutoGenerateColumns is not a great idea, because this will show all columns (usually not desirable) and not necessarily in the order that you want.
Other remarks:
Records can be edited or deleted directly in the datagridview, by simply selecting one or more rows, and pressing the Del key. Then just invoke the DataAdapter to commit the changes to the database. You should not even be doing DELETE FROM. Just let the user use the datagridview. The benefit is that if the user makes a mistake, you can roll back changes because you are using a datatable. Here you are deleting immediately and without warning.
Don't do stuff like:
SQL_CMD_TXT = "DELETE FROM `employees` WHERE (`EMPLOYEE_ID` ='" &
EMPLOYEE_DEL_FRM.DEL_ID_TXT.Text & "'); SELECT * FROM `employees`;"
Use parameterized queries instead, this code is insecure and will choke on single quotes or special characters (try it !). Here is a simple example: FAQ: How do I make a parameterized query in the database with VB.NET?. Please use parameterized queries from now on, don't develop bad habits that will always bite you sooner or later. The security risk alone is too high.
Also I am wondering why you did stacked queries. It would better to separate the SELECT from the DELETE.
In this code variable sql is not needed:
With cmd
sql = SQL_CMD_TXT
.Connection = con
.CommandText = sql
End With
Just use SQL_CMD_TXT directly. Otherwise it makes the code more difficult to follow.

'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

VB Access DB Update statement

I am new to this forum, please could you help me get this code to work, when i execute it, it simply does nothing and does not update the DB. If i remove the square brackets it gives an error: "SYNTAX ERROR in UPDATE statement"
Any help appreciated!
Dim connection As OleDbConnection
connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=UserDB.accdb;Jet OLEDB:Database;")
connection.Open()
Dim pass As String
pass = txtconfirm.Text
Dim user As String
user = LoginForm.UsernameTextBox.Text
Dim query As String = "UPDATE [Users] SET [Password]= '" & pass & "' WHERE [Username]= '" & user & "';"
Dim command As New OleDbCommand(query, connection)
command.ExecuteNonQuery()
connection.Close()
Given your actual connection string, the database that will be updated is the one in the directory where your application starts. This means that if you work with a WinForms application this folder is \BIN\DEBUG or x86 variant. If there is not error then you could get the return value of the ExecuteNonQuery call to verify if a record has been updated or not
Dim rowsUpdated = command.ExecuteNonQuery()
MessageBox.Show("Record updated count = " & rowsUpdated)
If this value is not zero then your database has been updated and you are looking for changes in the wrong database. Check the one in the BIN\DEBUG folder.
In any case your code has big problems. If your variables user or pass contain a single quote, then your code will crash again because your string concatenation will form an invalid SQL. As usual the only workaround is to use a parameterized query
Dim pass = txtconfirm.Text
Dim user = LoginForm.UsernameTextBox.Text
Dim query As String = "UPDATE [Users] SET [Password]= #p1 WHERE [Username]= #p2"
Using connection = New OleDbConnection("...........")
Using command As New OleDbCommand(query, connection)
connection.Open()
command.Parameters.Add("#p1", OleDbType.VarWChar).Value = pass
command.Parameters.Add("#p2", OleDbType.VarWChar).Value = user
command.ExecuteNonQuery()
End Using
End Using
The parameterized approach has many advantages. Your query text is more readable, there is no misunderstanding between your code and the values expected by your database engine. And while not easy to exploit with MS-Access there is no problem with Sql Injection
I think Steve presents a much better approach for you coding this...
Let me just throw out a few more things:
The reason you can't take those brackets out is some of your column names are reserved words; just FYI.
Since you report "it does nothing..." when you execute, it sounds like you have a valid connection and sql syntax, in which case my next step would be to copy the sql command text while in debug mode, change it to a select and run it in your DB. You should get one result when you do. If not, either your criteria or field contents are not what you think they are...
Just change the Update table SET field-value ... to SELECT * FROM table and leave the WHERE clause as is.

selecting from one database and inserting row to new database

I'm looking for a pseudo code to write a VB.NET cursor to select columns from one table in one database and inserting it into another table in a different database (they are *not on the same server) using data adapter etc.
I just need something to refer to as I learn. Thanks
Dim selectStr As String = _
"select * from db1"
Dim insertStr As String = _
"insert into db2(col1)"
Try
da_adapter = New OleDb.OleDbDataAdapter(selectStr, connStr)
da2_adapter = New OleDb.OleDbDataAdapter(insertStr, connStr2)
da_adapter.SelectCommand.CommandTimeout = 720
da_adapter.Fill(ds)
da2_adapter.SelectCommand.CommandTimeout = 720
da2_adapter.Fill(ds)
Catch ex As Exception
End Try
In your original code, this part is wrong:
da2_adapter = New OleDb.OleDbDataAdapter(insertStr, connStr2)
When you create a data adapter that way, the SQL statement you provide becomes part of the SelectCommand. You want yours to be part of the InsertCommand, which you need to do yourself:
Dim cmd2 As New OleDb.OleDbCommand(insertStr, connStr2)
da2_adapter = New OleDb.OleDbDataAdapter
da2_adapter.InsertCommand = cmd2
Also, you need to set the AcceptChangesDuringFill property of the first data adapter to False. That way, instead of setting the RowState of all the rows to Unchanged after populating the DataTable, they will remain as Added and ready to be inserted.
You then need to call Update on the second data adapter to save the data rather than calling Fill, which retrieves data.

Using TableAdapter to insert rows into a dataset does not do anything

I have a question similar to this one, but reading the (accepted) answer didn't give me much insight, so I'm hoping to state it more clearly and get a clearer response back.
I'm attempting to insert a data row into a table. I'm using TableAdapter's custom "insert nonQuery" that I wrote (it works, I tested) to accept some parameters. I'm fairly new to this business of communication with a database via .NET and what I'm doing is probably wrong by design. My questions are why is it wrong and what's the right way to do it? Both are equally important, IMO.
Here's some sample VB code I wrote:
Dim arraysTableAdapter As New UnitTestsDataSetTableAdapters.ArraysTableAdapter
Try
arraysTableAdapter.InsertArray("Test Array", 2, 1, 2, "Test user")
Catch ex As SqlException
MsgBox("Error occured when trying to add new array." _
& vbNewLine & vbNewLine _
& ex.Message)
End Try
...and that's pretty much it. There is no exception raised, my table does not get a new row inserted. Everything is just the way it was before I called the InsertArray method. When I test my query in the QueryBuilder with the same parameters, a new row gets added to the database.
Now, I do understand some of the reasons this would not work. I understand that I need to create and select a row in my DataSet (no idea how to do it) in order to tell the TableAdapter what it's adding the data to. Or at least I got that impression from reading the vast abyss of forums.
I would really like to use TableAdapter at some point, because it knows that .InsertArray exists and it knows which parameters it likes. I could try and do it using
Dim con As New SqlConnection
Dim cmd As New SqlCommand
con.ConnectionString = connString
con.Open()
cmd.CommandText = "INSERT ...... all that jazz"
but it's not nearly clean enough for how clean I like my code to be. So, is there any way to do what I'm trying to do the way I'm doing it? In other words, how do I use the neat structure of a TableAdapter to communicate to my DataSet and put a new row in it?
Thanks in advance!
There were two things that were wrong:
(minor issue) I did not have a DataTable filled from the TableAdapter (see code below)
(major, sneaky issue) My method worked from the very beginning. There is nothing extra to be added except for the line above. However, the ConnectionString of arraysTableAdapter was pointing my program (automatically, by default) to a wrong location. Once I manually set the ConnectionString, it worked perfectly.
Here's my complete code:
Dim connString As String = "Some correct connection string"
Dim arraysDataTable As New SpeakerTestsDataSet.ArraysDataTable
Dim arraysTableAdapter As New UnitTestsDataSetTableAdapters.ArraysTableAdapter
'Set the correct connection string'
arraysTableAdapter.Connection.ConnectionString = conn
'Fill table from the adapter'
arraysTableAdapter.Fill(arraysDataTable)
Try
arraysTableAdapter.Insert("Test", 2, 1, 2, Now, Now, "Me")
Catch ex As Exception
MsgBox("Error occured when trying to add new array." _
& vbNewLine & vbNewLine _
& ex.Message)
End Try
The accepted answer in the question you linked to is correct, but sometimes saying it in different words helps:
A TableAdapter is used to communicate between a DataTable (there can be one or more DataTables in a DataSet) and a database. It can pull data from a database and add it to a DataTable and it can send data from a DataTable to the database. It's purpose is to create and execute the SQL code required to make this communication work.
You are trying to use the TableAdapter to directly add data to your DataTable. This will not work. Instead, you should use the methods that come with the DataTable to add a new row to the DataTable and then (if necessary) use your TableAdapter to send that row to a database.
For instance, with a Dataset called DataSet1 that contains a DataTable called DataTable1 that has three text columns you can add a record like this:
Dim d As New DataSet1
d.DataTable1.AddDataTable1Row("value1", "value2", "value3")
That AddDataTable1Row method is automatically created for you, and I think is what you are looking for.