insert or update with single button in vb.net - vb.net

how to insert and update data in database(sql server) with single button in vb.net i tried but not get the result.
here is my code.......
Private Sub Button5_Click(sender As System.Object, e As System.EventArgs) Handles Button5.Click
Try
Dim reader As SqlDataReader
Dim query As String
Dim n As Integer
n = 0
sqlcom1 = New SqlCommand("select * from mydatabase.masters")
sqlcom1.ExecuteReader()
sqlcom = New SqlCommand("select * from mydatabase.masters")
sqlcom.ExecuteReader()
reader = sqlcom1.ExecuteReader
reader = sqlcom.ExecuteReader
sqlcom = New SqlCommand("Update masters SET EmpName=#EmpName, Age=#Age, Address=#Address where Empid=#Empid", conn)
sqlcom.Parameters.Add("#EmpName", SqlDbType.VarChar).Value = TextBox4.Text
sqlcom.Parameters.Add("#Age", SqlDbType.Int).Value = TextBox3.Text
sqlcom.Parameters.Add("#Address", SqlDbType.VarChar).Value = TextBox2.Text
sqlcom.Parameters.Add("#Empid", SqlDbType.Int).Value = TextBox1.Text
sqlcom1 = New SqlCommand("insert into masters(Empid, EmpName, Age, Address) values(#Empid, #EmpName, #Age, #Address)", conn)
sqlcom1.Parameters.AddWithValue("#Empid", TextBox1.Text)
sqlcom1.Parameters.AddWithValue("#EmpName", TextBox4.Text)
sqlcom1.Parameters.AddWithValue("#Age", TextBox3.Text)
sqlcom1.Parameters.AddWithValue("#Address", TextBox2.Text)
conn.Open()
While reader.Read
n = n + 1
End While
If table.Rows.Count = n Then
sqlcom1.ExecuteNonQuery()
ElseIf table.Rows.Count = n + 1 Then
sqlcom.ExecuteNonQuery()
End If
Catch ex As Exception
MessageBox.Show("error" + ex.Message)
End Try
End Sub

Using block ensures that your connection object is closed and disposed even if there is an error.
Normally I put comments in line but the code got so cluttered that had to move most of them up here. I hope you can figure out where they belong.
Dim reader As SqlDataReader - Unused
Dim query As String - Unused
Integers are automatically initialized to zero
Pass the query and the connection to the constructor of the command.
Your connection string will tell SQL Server what database to use. It is not necessary in the query.
Apparently all you want is the count, not all the data.
This query is exactly the same as sqlcom1
Dim sqlcom As New SqlCommand("select * from mydatabase.masters", cn)
sqlcom.ExecuteReader()
You did this twice
reader = sqlcom1.ExecuteReader
Not necessay, we already retrieved the count
`While reader.Read
n = n + 1
End While`
I made the assumption that table was a DataTable populated at some other time. Using the count as comparison to the count in the table is not a great way to determine if the command is Insert or Update but it might work as long as database and table were not used with a DataAdapter that updated the database.
Private Sub Button5_Click(sender As System.Object, e As System.EventArgs) Handles Button5.Click
Try
Dim n As Integer
Using cn As New SqlConnection("Your connection string")
Dim sqlcom1 As New SqlCommand("select Count(*) from masters", cn)
cn.Open()
n = CInt(sqlcom1.ExecuteScalar) 'n is now the number of rows in the database table
Dim sqlcom As New SqlCommand
sqlcom.Parameters.Add("#EmpName", SqlDbType.VarChar).Value = TextBox4.Text
'Age is not a good idea to enter in a database. It changes over time.
'Enter the birth date and calculate the age as needed.
sqlcom.Parameters.Add("#Age", SqlDbType.Int).Value = CInt(TextBox3.Text)
sqlcom.Parameters.Add("#Address", SqlDbType.VarChar).Value = TextBox2.Text
If table.Rows.Count > n Then
'Normally EmpId would be an auto increment (identity) field
'and would NOT be included in an insert.
sqlcom.CommandText = "insert into masters(EmpName, Age, Address) values(#EmpName, #Age, #Address)"
Else
sqlcom.CommandText = "Update masters SET EmpName=#EmpName, Age=#Age, Address=#Address where Empid=#Empid"
sqlcom1.Parameters.Add("#Empid", SqlDbType.Int).Value = CInt(TextBox1.Text)
End If
sqlcom.ExecuteNonQuery()
End Using
Catch ex As Exception
MessageBox.Show("error" + ex.Message)
End Try
End Sub
On second thought, forget the whole thing. Use a DataGridView and a DataAdapter. Then you can just use Update and it will update, insert and delete.

Related

Save a DataGridView data to Access database

I am trying to save a DataGridView data to an Access database (database is already connected to Visual Studio).
Here's my code:
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Try
Dim cn As OleDbConnection
cn = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source= |DataDirectory|\GEFORSERVI V2.1.accdb;")
cn.Open()
Dim cmd As New OleDbCommand
cmd.Connection = cn
cmd.CommandType = Data.CommandType.Text
Dim Strcommandtext As String = "inserto into Factura(Designacao,PrecoUnitario,Qtd,Total,Nome,Entidade,NIF,Telefone,Morada,CodigoProduto,DataEmissao) VALUES(#Servico_Produto,#Valor,#Qtd,#Total,#Nome,#Entidade,#NIF,#Telemovel,#Bairro,#Data_de_Emissao)"
Dim values As String = ""
For i As Integer = 0 To Factura2DataGridView.Rows.Count - 1
values = Strcommandtext & Factura2DataGridView.Rows(i).Cells(11).Value & ")"
cmd.CommandText = values
cmd.ExecuteNonQuery()
Next i
cmd = Nothing
cn.Close()
MsgBox("Your Record Inserted Successfully ")
Catch myException As Exception
MsgBox("No Record Inserted" + myException.ToString())
Finally
'MsgBox("Closing Connection")
End Try
End Sub
Connections and Commands need to be disposed so they can release unmanaged resources. Using...End Using blocks are the best way to handle this since the will do this even if there is an error. In this code I both the connection and command are included in the Using block. Note the comma at the end of the first Using line.
Pass the CommandText and the Connection directly to the constructor of the command. I noticed you had missed one of the parameters that was in the field list. I also noticed the you typed "inserto". I believe it must be "Insert". It is not necessary to set CommandType since CommandType.Text is the default.
In OleDb the order that the parameters appear in the sql string must match the order that they are added to the Parameters collection.
Build the parameters collection once outside the loop. It is only the Values of the parameters that change in the loop.
Open the connection once, outside the loop.
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Try
Using cn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source= |DataDirectory|\GEFORSERVI V2.1.accdb;"),
cmd As New OleDbCommand("Insert into Factura(Designacao,PrecoUnitario,Qtd,Total,Nome,Entidade,NIF,Telefone,Morada,CodigoProduto,DataEmissao)
VALUES(#Servico_Produto,#Valor,#Qtd,#Total,#Nome,#Entidade,#NIF,#Telemovel,#Bairro,#CodigoProduto,#Data_de_Emissao)", cn)
With cmd.Parameters
.Add("#Servico_Produto", OleDbType.Integer)
.Add("#Valor", OleDbType.VarWChar)
.Add("#Qtd", OleDbType.Integer)
.Add("#Total", OleDbType.Decimal)
.Add("#Nome", OleDbType.VarWChar)
.Add("#Entidade", OleDbType.VarWChar)
.Add("#NIF", OleDbType.VarWChar)
.Add("#Telemovel", OleDbType.VarWChar)
.Add("#Bairro", OleDbType.VarWChar)
.Add("#CodigoProduto", OleDbType.Integer)
.Add("#Data_de_Emissao", OleDbType.Date)
End With
cn.Open()
For i As Integer = 0 To Factura2DataGridView.Rows.Count - 1
cmd.Parameters("#Servico_Produto").Value = Factura2DataGridView.Rows(i).Cells(0).Value
cmd.Parameters("#Valor").Value = Factura2DataGridView.Rows(i).Cells(1).Value
cmd.Parameters("#Qtd").Value = Factura2DataGridView.Rows(i).Cells(2).Value
cmd.Parameters("#Total").Value = Factura2DataGridView.Rows(i).Cells(3).Value
cmd.Parameters("#Nome").Value = Factura2DataGridView.Rows(i).Cells(4).Value
cmd.Parameters("#Entidade").Value = Factura2DataGridView.Rows(i).Cells(5).Value
cmd.Parameters("#NIF").Value = Factura2DataGridView.Rows(i).Cells(6).Value
cmd.Parameters("#Telemovel").Value = Factura2DataGridView.Rows(i).Cells(7).Value
cmd.Parameters("#Bairro").Value = Factura2DataGridView.Rows(i).Cells(8).Value
cmd.Parameters("#CodigoProduto").Value = Factura2DataGridView.Rows(i).Cells(9).Value
cmd.Parameters("#Data_de_Emissao").Value = Factura2DataGridView.Rows(i).Cells(10).Value
cmd.ExecuteNonQuery()
Next
End Using
MsgBox("Your Record Inserted Successfully ")
Catch myException As Exception
MsgBox("No Record Inserted" + myException.Message)
End Try
End Sub
There are easier ways to do this. If you have a DataTable bound to the DataGridView you can use a DataAdpater.Update method.

How to update access db by editing datagridview cells?

Im trying to edit items after inserting to access by clicking the save button? How can i save the edits done in datagridview rows to access?
Already tried the update query
For each loop
vb.net
Private Sub BunifuFlatButton1_Click(sender As Object, e As EventArgs) Handles BunifuFlatButton1.Click
Dim constring As String = ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source= C:\Users\PU-IMO\Desktop\BlueWavesIS - Copy\BlueWavesIS\BlueWavesIS.accdb")
Dim conn As New OleDbConnection(constring)
For Each row As DataGridViewRow In DataGridView1.Rows
Using con As New OleDbConnection(constring)
'nettxt.Text = (grosstxt.Text * perdistxt.Text / 100) - (dislctxt.Text + disusd.Text + distax.Text)
Dim cmd As New OleDbCommand("Update PurchaseInvoice set [Itemnum] = #ItemNum, [Itemname]= #ItemName, [Itemqty]= #ItemQty, [Itemprice] = #ItemPrice, [discount] =#discount, [subtotal] = #subtotal,[Preference] = " & preftxt.Text & ", [Suppnum] = " & pnumtxt.Text & ", [UniqueID] = " & pautotxt.Text & " Where [UniqueID] = " & pautotxt.Text & "", con)
cmd.Parameters.AddWithValue("#ItemID", row.Cells("ItemID").Value)
cmd.Parameters.AddWithValue("#ItemName", row.Cells("ItemName").Value)
cmd.Parameters.AddWithValue("#ItemQty", row.Cells("ItemQty").Value)
cmd.Parameters.AddWithValue("#ItemPrice", row.Cells("ItemPrice").Value)
cmd.Parameters.AddWithValue("#discount", row.Cells("discount").Value)
cmd.Parameters.AddWithValue("#subtotal", row.Cells("subtotal").Value)
cmd.Parameters.AddWithValue("#Ref", preftxt.Text.ToString)
cmd.Parameters.AddWithValue("#Suppnum", Convert.ToInt32(pnumtxt.Text))
cmd.Parameters.AddWithValue("#UniqueID", Convert.ToInt32(pautotxt.Text))
DataGridView1.AllowUserToAddRows = False
con.Open()
cmd.ExecuteNonQuery()
con.Close()
End Using
Next
'This the code i used to show the data in datagridview:
Private Sub NewPurchaseInvoice_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim con As New OleDbConnection
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source= C:\Users\PU-IMO\Desktop\BlueWavesIS - Copy\BlueWavesIS\BlueWavesIS.accdb"
con.Open()
Dim sql As String = "Select [Itemnum],[Itemname],[Itemprice],[ItemQty],[discount],[subtotal] from PurchaseInvoice where [UniqueID] = " & pautotxt.Text & ""
Dim cmd10 As OleDbCommand = New OleDbCommand(Sql, con)
'Dim adap As New OleDbDataAdapter("Select [Itemnum],[Itemname],[Itemprice],[discount],[subtotal] from PurchaseInvoice where UniqueID = " & pautotxt.Text & "", con)
'Dim ds As New System.Data.DataSet
'adap.Fill(ds, "PurchaseInvoice")
Dim dr As OleDbDataReader = cmd10.ExecuteReader
Do While dr.Read()
DataGridView1.Rows.Add(dr("ItemNum"), dr("ItemName"), dr("ItemQty"), dr("ItemPrice"), dr("discount"), dr("subtotal"))
Loop
con.Close()
I expect that all the rows will be updated as each other, but the actual output is that each row has different qty name etc...
This code does not seem appropriate in the load event because pautotxt.Text will not have a value yet. Can you move it to a Button.Click?
I guessed that the datatype of ID is an Integer. You must first test if the the .Text property can be converted to an Integer. .TryParse does this. It returns a Boolean and fills IntID that was provided as the second parameter.
You can pass the connection string directly to the constructor of the connection. The Using...End Using blocks ensure that your database objects are closed and disposed even if there is an error. You can pass the Select statement and the connection directly to the constructor of the command.
ALWAYS use Parameters, never concatenate strings to avoid sql injection. Don't use .AddWithValue. See http://www.dbdelta.com/addwithvalue-is-evil/
and
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
and another one:
https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications
The DataAdapter will open the connection, fiil the DataTable and close the connection if it finds it closed; however if it is found open it will leave it open.
The last line binds the grid to the DataTable.
Private Sub FillGrid()
If Not Integer.TryParse(pautotxt.Text, IntID) Then
MessageBox.Show("Please enter a number")
Return
End If
dt = New DataTable()
Using con As New OleDbConnection(ConnString)
Using cmd As New OleDbCommand(Sql, con)
cmd.Parameters.Add("#ID", OleDbType.Integer).Value = IntID
Dim adap = New OleDbDataAdapter(cmd)
adap.Fill(dt)
End Using
End Using
DataGridView1.DataSource = dt
End Sub
DataTables are very clever. When bound to a DataGridView they keep track of changes and mark rows as update, insert, or delete. The DataAdapter uses this info to update the database. Once the database is updated we call .AcceptChanges on the DataTable to clear the marking on the rows.
Private Sub UpdateDatabase()
Using cn As New OleDbConnection(ConnString)
Using da As New OleDbDataAdapter(Sql, cn)
da.SelectCommand.Parameters.Add("#ID", OleDbType.Integer).Value = IntID
Using builder As New OleDbCommandBuilder(da)
da.Update(dt)
End Using
End Using
End Using
dt.AcceptChanges()
End Sub

Compare db value with textbox value VB

My Table
I load the windows user name to textbox1.text using 'System.Environment'
After that I query this and compare the textbox value to the PersonName in db
if it matches, I want to get the relevant Department name ie if it's 'manager'
then I want to display a form from menuitem_click event. My code is below
it dosent work can some one please help with this.
Private Sub MySamplesToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles MySamplesToolStripMenuItem.Click
Dim cn As New SqlClient.SqlConnection("Data Source=ffff;Initial Catalog=ffff;User ID=****;Password=****;")
Dim cmd As New SqlClient.SqlCommand
Dim tbl As New DataTable
Dim da As New SqlClient.SqlDataAdapter
Dim reader As SqlClient.SqlDataReader
Dim ta As String
Try
cn.Open()
Dim sql As String
sql = "select * from dbo.Person where [PersonName] ='" + TextBox1.Text + "'"
cmd = New SqlClient.SqlCommand(sql, cn)
reader = cmd.ExecuteReader
While reader.Read
ta = reader.Item("Department")
If ta = 'Maneger' Then
Form2.Show()
End If
' TextBox2.Text = reader.Item("Department")
'TextBox2.Text = reader.Item("dob")
End While
cn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
No matter how you spell it, Manager or Maneger, just make sure what is in the database matches what is in your If statement. I think I would use a drop down box for you to select the Department wherever you are inserting the Person so the Department name would match.
The Using...End Using blocks ensure that you database objects are closed and disposed even if there is an error.
You can pass your Sql statement and the connection directly to the constructor of the command. If all you need is the Department then don't drag down all the date with "*".
Never concatenate strings to build Sql statements. A hacker could type in TextBox1 "Joe; Drop Table dbo.Person;" Using parameters stops this hole because the .Value of the parameter is treated as only a value not executable code.
You are only expecting one value in return so you can use .ExecuteScalar which returns the first column of the first row in the result set.
Your code is very fragile because I suspect you could have duplicate names unless you require unique user names.
Private Sub MySamplesToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles MySamplesToolStripMenuItem.Click
Try
Using cn As New SqlClient.SqlConnection("Data Source=ffff;Initial Catalog=ffff;User ID=****;Password=****;")
Using cmd As New SqlClient.SqlCommand("Select Department From dbo.Person Where PersonName = #Name;", cn)
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = TextBox1.Text
cn.Open()
Dim ta As String = cmd.ExecuteScalar.ToString
If ta = "Maneger" Then
Form2.Show()
End If
TextBox2.Text = ta
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub

The right way to save 2 table to access database in vb,net

I tried to save all of records of 2 tables to Access database. My idea is save first table then save next table. But I think it isn't the right way when save multi tables to access because It take a long time.
Here is my code and it run ok but I don't know is there another ways which better to save multi tables to access.
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\1_Project\Project_of_VB_Net\AccessDatabase\StudentDatabase.accdb"
cmd.Connection = cnn
Dim cmdupdate As String
Dim cmdinsert As String
For Each dr In dt.Rows
cmdupdate = "UPDATE StudentData SET ID=#ID, StudentName=#StudentName, StudentID=#StudentID, StudentClass=#StudentClass WHERE StudentID=#StudentID"
cmdinsert = "INSERT INTO StudentData(ID,StudentName,StudentID,StudentClass) VALUES(#ID,#StudentName,#StudentID,#StudentClass)"
cmd.Parameters.Clear()
cmd.CommandText = cmdupdate
cmd.Parameters.AddWithValue("#ID", dr("ID"))
cmd.Parameters.AddWithValue("#StudentName", dr("StudentName"))
cmd.Parameters.AddWithValue("#StudentID", dr("StudentID"))
cmd.Parameters.AddWithValue("#StudentClass", dr("StudentClass"))
cnn.Open()
Dim count = cmd.ExecuteNonQuery()
If count = 0 Then
cmd.CommandText = cmdinsert
cmd.ExecuteNonQuery()
End If
cnn.Close()
Next
For Each dr2 In dt2.Rows
cmdupdate = "UPDATE StudentData2 SET ID2=#ID2, StudentName2=#StudentName2, StudentID2=#StudentID2, StudentClass2=#StudentClass2 WHERE StudentID2=#StudentID2"
cmdinsert = "INSERT INTO StudentData2(ID2,StudentName2,StudentID2,StudentClass2) VALUES(#ID2,#StudentName2,#StudentID2,#StudentClass2)"
cmd.Parameters.Clear()
cmd.CommandText = cmdupdate
cmd.Parameters.AddWithValue("#ID2", dr2("ID2"))
cmd.Parameters.AddWithValue("#StudentName2", dr2("StudentName2"))
cmd.Parameters.AddWithValue("#StudentID2", dr2("StudentID2"))
cmd.Parameters.AddWithValue("#StudentClass2", dr2("StudentClass2"))
cnn.Open()
Dim count2 = cmd.ExecuteNonQuery()
If count2 = 0 Then
cmd.CommandText = cmdinsert
cmd.ExecuteNonQuery()
End If
cnn.Close()
Next
End Sub

fetching single value form database in vb.net

this my database table
id name
1   abc
2    xyz
it i enter 1 then respective value "abc" display in different text box???
Private Sub butsea_Click(sender As Object, e As EventArgs) Handles butsea.Click
Dim dset As New DataSet
Dim da As SqlDataAdapter
Dim myCmd As New SqlCommand
Try
myConn.ConnectionString = "Data Source=THEONE\PARTH;Initial Catalog=testdatabase;Integrated Security=True;"
myConn.Open()
Dim avalue As String = (InputBox("Input Student Id", "Search Student")).ToString
txt_id.Text = avalue
da = New SqlDataAdapter("SELECT * FROM studentdetails where student_id= '" & txt_id.Text & "", myConn)
If dset.Tables(0).Rows.Count > 0 Then
'what should i write here
Else
MsgBox("No Record Found")
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
myConn.Close()
End Try
End Sub
If you need to fetch just a single value - using DataAdapter and DataSet is overkill. Use SqlCommand.ExecuteScalar method and in your query instead of "SELECT * ..." do a "SELECT YOURFIELD ... ".
this way you don't have to jump thru hoops building a dataset, checking number of rows etc. and just check returned value for Nothing instead.
UPDATE Here is your code modified to use ExecuteScalar
Private Sub butsea_Click(sender As Object, e As EventArgs) Handles butsea.Click
Dim myCmd As SqlCommand
Dim myConn As New SqlConnection
Dim oResult As Object
Try
myConn.ConnectionString = "Data Source=THEONE\PARTH;Initial Catalog=testdatabase;Integrated Security=True;"
myConn.Open()
Dim avalue As String = (InputBox("Input Student Id", "Search Student")).ToString
txt_id.Text = avalue
myCmd = New SqlCommand("SELECT student_name FROM studentdetails where student_id= '" & txt_id.Text & "'", myConn)
oResult = myCmd.ExecuteScalar()
If oResult IsNot Nothing Then
txt_name.text = oResult.ToString
Else
MsgBox("No Record Found")
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
myConn.Close()
End Try
End Sub
This code assumes that database field that u need to display is called student_name and that you added TextBox called txt_name to your form.
You need to add other textboxes for every field you want to show.
(For example a textbox called txtStudentName could be used for the name, and so on for other fields present in the table studentdetails).
The correct way to query your database (leaving out other methods like using a SqlDataReader) should be the following
Dim dset As New DataSet
Dim da As SqlDataAdapter
Try
myConn.ConnectionString = "Data Source=THEONE\PARTH;Initial Catalog=testdatabase;Integrated Security=True;"
myConn.Open()
Dim avalue As String = (InputBox("Input Student Id", "Search Student")).ToString
txt_id.Text = avalue
' prepare the adapter with a commandtext. Do not use string concatenation from user input'
da = New SqlDataAdapter("SELECT * FROM studentdetails where student_id=#id", myConn)
da.SelectCommand.Parameters.AddWithValue("#id", txt_id.Text)
' Fill the dataset'
da.Fill(dset)
If dset.Tables(0).Rows.Count > 0 Then
' Supposing you have a field for the studentname in the first column of the returned
' datatable rows(rowindex)(columnindex)
txtStudentName.Txt = dset.Tables(0).Rows(0)(0).ToString()
.....
' Set the text property of other textboxes for other fields to show'
Else
MsgBox("No Record Found")
End If