My Code inserts only first row data in sqldatabase - vb.net

How do I insert data of second row in SQL Server database? Here is my code:
Private Sub InsertStockDatagrid()
con.Open()
Dim cmdsrl As New SqlCommand("Select Code, Qty, Rate, Amt, Taxable, cgstamt, sgstamt,Type,Prefix,Srl,Branch FROM stock", con)
cmdsrl.Parameters.AddWithValue("Type", ComboBoxTranType.SelectedItem.ToString())
cmdsrl.Parameters.AddWithValue("Prefix", Lblprefix.Text)
cmdsrl.Parameters.AddWithValue("srl", TextINVNo.Text)
cmdsrl.Parameters.AddWithValue("Branch", LBLBranchcode.Text)
Dr8 = cmdsrl.ExecuteReader()
If (Dr8.Read()) Then
MessageBox.Show(" Unique field checked")
dr.Close()
Else
For Each Rw As DataGridViewRow In DataGridView1.Rows
'For RW As Integer = 0 To DataGridView1.Rows.Count - 1
Dim cmd = New SqlCommand("Insert into Stock (Code, Qty, Rate, Amt, Taxable, cgstamt, sgstamt,Type,Prefix,Srl,Branch) values('" & Rw.Cells(15).Value.ToString() & "','" & Rw.Cells(6).Value.ToString() & "','" & Rw.Cells(7).Value.ToString() & "','" & Rw.Cells(13).Value.ToString() & "','" & Rw.Cells(13).Value.ToString() & "','" & Rw.Cells(11).Value.ToString() & "','" & Rw.Cells(12).Value.ToString() & "','" & ComboBoxTranType.Text & "','" & Lblprefix.Text & "','" & TextINVNo.Text & "','" & LBLBranchcode.Text & "')", con)
cmd.ExecuteNonQuery()
Next
MessageBox.Show("Stock Data Entered")
con.Close()
Updatestocksrl()
End If
End Sub

Don't loop through the rows of DataGridView at all. Create a DataTable with the appropriate schema, populate it with initial data if appropriate and then bind it to the grid via a BindingSource. When it comes time to save the data, call Update on a SqlDataAdapter - the same one you used to retrieve the data if you did actually retrieve data - to save the changes from the DataTable. In its simplest form, that might look like this:
Private table As New Datatable
Private adapter As New SqlDataAdapter("SELECT * FROM MyTable", "connection string here")
Private commands As New SqlCommandBuilder(adapter)
Private Sub GetData()
adapter.Fill(table)
BindingSource1.DataSource = table
DataGridView1.DataSource = BindingSource1
End Sub
Private Sub SaveData()
Validate()
BindingSource1.EndEdit()
adapter.Update(table)
End Sub

Related

System.Data.SqlClient.SqlException: Violation of PRIMARY KEY

I create a SQL Server database and I want to add some data in a particular table of that database. I use some textbox to input the data and an add button to complete. But when I tap the button the whole process was stopped and indicate an error in the DBSQL module which is shown below.
Here's my code:
Imports System.Data
Imports System.Data.SqlClient
Module DBSQLServer
Public con As New SqlConnection("Data Source=JOYALXDESKTOP\SQLEXPRESS;Initial Catalog=SaleInventory;Integrated Security=True")
Public cmd As New SqlCommand
Public da As New SqlDataAdapter
Public ds As New DataSet
Public dt As DataTable
Public qr As String
Public i As Integer
Public Function searchdata(ByVal qr As String) As DataSet
da = New SqlDataAdapter(qr, con)
ds = New DataSet
da.Fill(ds)
Return ds
End Function
Public Function insertdata(ByVal qr As String) As Integer
cmd = New SqlCommand(qr, con)
con.Open()
i = cmd.ExecuteNonQuery()
con.Close()
Return i
End Function
End Module
The error occurs on this line:
i = cmd.ExecuteNonQuery()
In the table, I have 5 columns:
ProID, ProName, ProDesc, ProPrice, ProStock
ProID is my primary key.
Here's my add button code to add the data into the database:
Private Sub Add_Click(sender As Object, e As EventArgs) Handles add.Click
If (isformvalid()) Then
qr = "Insert into tblProductInfo (ProName, ProDesc, ProPrice, ProStock) Values('" & nametext.Text & "','" & descriptiontext.Text & "','" & pricetext.Text & "','" & stocktext.Text & "')"
Dim logincorrect As Boolean = Convert.ToBoolean(insertdata(qr))
If (logincorrect) Then
MsgBox("Stock Added Successfully ...", MsgBoxStyle.Information)
Else
MsgBox("Something Wrong. Record Not Saved. Please Check and Try Again...", MsgBoxStyle.Critical)
End If
End If
End Sub
When my query is:
qr = "Insert into tblProductInfo (ProName, ProDesc, ProPrice, ProStock) Values('" & nametext.Text & "','" & descriptiontext.Text & "','" & pricetext.Text & "','" & stocktext.Text & "')"
The error is below :
System.Data.SqlClient.SqlException: 'Cannot insert the value NULL into column 'ProID', table 'SaleInventory.dbo.tblProductInfo'; column does not allow nulls. INSERT fails.
And when my query is:
qr = "Insert into tblProductInfo (ProID, ProName, ProDesc, ProPrice, ProStock) Values('" & idtext.Text & "','" & nametext.Text & "','" & descriptiontext.Text & "','" & pricetext.Text & "','" & stocktext.Text & "')" `
Then the error is:
System.Data.SqlClient.SqlException: 'Violation of PRIMARY KEY constraint 'PK_tblProductInfo'. Cannot insert duplicate key in object 'dbo.tblProductInfo'. The duplicate key value is (1).
This is because in tblProductInfo there is a row with ProID=1. You should code so that avoid this duplicate, for example you can first run a script to find the maximum of ProID in your table ("Select MAX(ProID) from tblProductInfo"), and run your query with MAX(ProID)+1.
Assuming you have corrected your database making the ProdID an identity field.
Notice that all interaction with the user interface is performed in the Form code. All interaction with the database is performed in the Module. Although you still need to Import System.Data (for the DataTable type) it is not necessay to Import System.Data.SqlClient in the Form. All validation is done in the Form.
In the Module code, the Using...EndUsing blocks ensure that your database objects are closed and disposed even if there is an error. I have demonstrated how to use parameters to avoid Sql injection but I had to guess at the datatypes. Check your database for the actual datatypes and adjust the SqlDbType and the parameter types and the validation code in the Form accordingly.
Connections are precious resources. Notice that the connection is opened at the last minute and closed and disposed by the End Using immediately after it is used by and .Execute...
Module DBSQLServer
Private conString As String = "Data Source=JOYALXDESKTOP\SQLEXPRESS;Initial Catalog=SaleInventory;Integrated Security=True"
'Example of how your search function might look.
Public Function searchdata(Name As String) As DataTable
Dim dt As New DataTable
Using cn As New SqlConnection()
Using cmd As New SqlCommand("Select * From tblProductInfo Where Name = #Name", cn)
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = Name
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
End Using
Return dt
End Function
Public Function insertdata(Name As String, Description As String, Price As Decimal, Stock As Integer) As Integer
Dim i As Integer
Using cn As New SqlConnection(conString)
Using cmd As New SqlCommand("Insert into tblProductInfo (ProName, ProDesc, ProPrice, ProStock) Values(#Name,#Description, #Price, #Stock", cn)
With cmd.Parameters
.Add("#Name", SqlDbType.VarChar).Value = Name
.Add("#Description", SqlDbType.VarChar).Value = Description
.Add("#Price", SqlDbType.Decimal).Value = Price
.Add("#Stock", SqlDbType.Int).Value = Stock
End With
cn.Open()
i = cmd.ExecuteNonQuery
End Using
End Using
Return i
End Function
End Module
And in the form
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'First check that text boxes for string parameters are filled in
If nametext.Text = "" OrElse descriptiontext.Text = "" Then
MessageBox.Show("Please fill in all text boxes.")
Return
End If
'Next check for valid numeric values
Dim price As Decimal
If Not Decimal.TryParse(pricetext.Text, price) Then
MessageBox.Show("The price must be a number.")
Return
End If
Dim stock As Integer
If Not Integer.TryParse(stocktext.Text, stock) Then
MessageBox.Show("Stock must be a whole number")
Return
End If
Dim retVal As Integer = DBSQLServer.insertdata(nametext.Text, descriptiontext.Text, price, stock)
If retVal = 1 Then
MessageBox.Show("Product successfully added.")
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim dt = DBSQLServer.searchdata(txtSearch.Text)
DataGridView1.DataSource = dt
End Sub

object reference not set to an instance of the object Error when adding data into my database

I am having a problem when i am trying to put this data into my database
I'm using Vstudio 2013 and MS Access as my database
my problem is everytime i click add to add the data in my database this error always popping object reference not set to an instance of the object. even i declared the
Here's my Add button Code
Dim cn As OleDb.OleDbConnection
Dim cmd As OleDb.OleDbCommand
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
Try
If cn.State = ConnectionState.Open Then
cn.Close()
End If
cn.Open()
cmd.Connection = cn
cmd.CommandText = "INSERT INTO gradess ( StudentNo,StudentName,StudentSection,SubjectNo1,SubjectNo2,SubjectNo3,SubjectNo4,SubjectNo5,SubjectNo6,SubjectNo7,SubjectNo8,TotalAverage) " & "Values('" & txtStudentNo.Text & "','" & lblName.Text & "','" & lblSection.Text & "','" & txtSubject1.Text & "','" & txtSubject2.Text & "','" & txtSubject3.Text & "','" & txtSubject4.Text & "','" & txtSubject5.Text & "','" & txtSubject6.Text & "','" & txtSubject7.Text & "','" & txtSubject8.Text & "','" & lblTotalAverage.Text & "')"
cmd.ExecuteNonQuery()
refreshlist()
disablebutton()
MsgBox("Successfully Added!!", vbInformation, "Successful")
clear()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
When you declare a variable like Dim cn As OleDb.OleDbConnection you are just telling the compiler what type it is not creating an object of that type.
When you use the New keyword OleDb.OleDbConnection is not just the name of a class (the data type) but it is an actual method. It is calling the constructor of the class which returns an instance of the object.
In C# you are required to put the parenthesis after like OleDb.OleDbConnection() which shows you are calling a method. You can add the parenthesis in vb.net but it is not required but I think it is a good reminder of the difference between setting a data type and creating an object.
Your declaration should be : Dim cn As New OleDb.OleDbConnection Dim cmd As New OleDb.OleDbCommand
– F0r3v3r-A-N00b 20 mins ago

how to save all record show in datagridview to the database

i have this code that will save only the top row of the datagridview,
can someone help me to modify this code so that it will save all the row in datagridview. im using vb 2010 and my database is ms access. thankyou in advance.
Try
Dim cnn As New OleDbConnection(conString)
query = "Insert into tblreportlog(EmpID,empname,department,empdate,timeinaM,timeoutam,lateam,timeinpm,timeoutpm,latepm,thw) values ('" & dgvReport.Item(0, dgvReport.CurrentRow.Index).Value & "', '" & dgvReport.Item(1, dgvReport.CurrentRow.Index).Value & "', '" & dgvReport.Item(2, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(3, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(4, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(5, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(6, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(7, dgvReport.CurrentRow.Index).Value & "', '" & dgvReport.Item(8, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(9, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(10, dgvReport.CurrentRow.Index).Value & "')"
cmd = New OleDbCommand(query, cnn)
cnn.Open()
cmd.ExecuteNonQuery()
cnn.Close()
Catch ex As Exception
MsgBox("ERROR: " & ErrorToString(), MsgBoxStyle.Critical)
End Try
Working from what is shown and best practices injected, you should be working from a data source such as a DataTable e.g. if when presented the DataGridView to the user there are no rows then create a new DataTable, set the DataTable as the DataSource of the DataGridView then when you are ready to save these rows in the DataGridView cast the DataSource of the DataGridView to a DataTable and use logic similar to the following
Dim dt As DataTable = CType(DataGridView1.DataSource, DataTable)
If dt.Rows.Count > 0 Then
Using cn As New OleDb.OleDbConnection With {.ConnectionString = "Your connection string"}
' part field list done here
Using cmd As New OleDb.OleDbCommand With
{
.Connection = cn,
.CommandText = "Insert into tblreportlog(EmpID,empname,department) values (#EmpID,#empname,#department)"
}
' TODO - field names, field types
cmd.Parameters.AddRange(
{
{New OleDb.OleDbParameter With {.ParameterName = "#EmpID", .DbType = DbType.Int32}},
{New OleDb.OleDbParameter With {.ParameterName = "#empname", .DbType = DbType.Int32}},
{New OleDb.OleDbParameter With {.ParameterName = "#department", .DbType = DbType.String}}
}
)
Dim Affected As Integer = 0
cn.Open()
Try
For Each row As DataRow In dt.Rows
' this should not be a auto-incrementing key
cmd.Parameters("#EmpID").Value = row.Field(Of Integer)("FieldName goes here")
cmd.Parameters("#empname").Value = row.Field(Of Integer)("FieldName goes here")
cmd.Parameters("#department").Value = row.Field(Of String)("FieldName goes here")
Affected = cmd.ExecuteNonQuery
If Affected <> 1 Then
Console.WriteLine("Error message, insert failed")
End If
Next
Catch ex As Exception
'
' handle exception
'
' for now
MessageBox.Show("Failed with: " & ex.Message)
' decide to continue or not
End Try
End Using
End Using
End If
On the other hand, if there are new rows with current rows we cast the data source as above then check for new rows along with validation as needed.
For Each row As DataRow In dt.Rows
If row.RowState = DataRowState.Added Then
If Not String.IsNullOrWhiteSpace(row.Field(Of String)("CompanyName")) Then
Other options, utilize a DataAdapter or setup data via data wizards in the ide where a BindingNavigator is setup with a save button.
If it's important to get the new primary key back the method for all methods can do this too.
The following code sample is from this MSDN code sample that shows how to get a new key back using OleDb connection and command.
Public Function AddNewRow(ByVal CompanyName As String, ByVal ContactName As String, ByVal ContactTitle As String, ByRef Identfier As Integer) As Boolean
Dim Success As Boolean = True
Try
Using cn As New OleDb.OleDbConnection(Builder.ConnectionString)
Using cmd As New OleDb.OleDbCommand("", cn)
cmd.CommandText = "INSERT INTO Customer (CompanyName,ContactName,ContactTitle) Values (#CompanyName,#ContactName,#ContactTitle)"
cmd.Parameters.AddWithValue("#CompanyName", CompanyName.Trim)
cmd.Parameters.AddWithValue("#ContactName", ContactName.Trim)
cmd.Parameters.AddWithValue("#ContactTitle", ContactTitle.Trim)
cn.Open()
cmd.ExecuteNonQuery()
cmd.CommandText = "Select ##Identity"
Identfier = CInt(cmd.ExecuteScalar)
End Using
End Using
Catch ex As Exception
Success = False
End Try
Return Success
End Function

How to get the ID of the most recently inserted Access record? [duplicate]

I have the following set of code for a Sub program. It's inserting a row into a MSAccess Database using data provided in the containing form. What I would like to do is grab the ID number of this added record so that it can be set for a property of a window that is invoked when successfully added. I tried looking this up but I get something about ##IDENTITY but it's using an entirely different way of connecting.
Private Sub CreateTournament_Click(sender As System.Object, e As System.EventArgs) Handles CreateTournament.Click
' TODO: Check the form for errors, or blank values.
' Create the tournament in the database, add the values where needed. Close the form when done.
Dim cn As OleDbConnection
Dim cmd As OleDbCommand
Dim dr As OleDbDataReader
Dim icount As Integer
Dim str As String
Try
cn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='C:\Master.mdb'")
cn.Open()
str = "insert into Tournaments (SanctioningID,TournamentName,TournamentVenue,TournamentDateTime,TournamentFirstTable,Game,Format,OrganizerID) values(" _
& CInt(SanctioningIDTxt.Text) & ",'" & Trim(TournamentNameTxt.Text) & "','" & _
"1" & "','" & EventDateTimePck.Value & "','" & TableFirstNumberNo.Value & "','" & GameList.SelectedIndex & "','" & FormatList.SelectedIndex & "','" & Convert.ToInt32(ToIDTxt.Text) & "')"
'string stores the command and CInt is used to convert number to string
cmd = New OleDbCommand(Str, cn)
icount = cmd.ExecuteNonQuery
MessageBox.Show(icount)
'displays number of records inserted
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
Me.Close()
Dim n As New TournamentWindow ' Open a new Tournament window if everything is successful
n.TournID = Counter '<< This should be set to the ID of the most recently inserted row
n.Show(HomeForm)'Invoke the form and assign "HomeForm" as it's parent.
End Sub
Assuming you have an auto increment column in the Tournaments table, you can do a "SELECT ##IDENTITY" to get the id of the last inserted record.
BTW, is the SanctioningIDTxt.Text unique? If so, can't you use that?

VB.NET SQL Server Insert - ExecuteNonQuery: Connection property has not been initialized

In the form load event, I connect to the SQL Server database:
Private Sub AddBook_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myConnection = New SqlConnection("server=.\SQLEXPRESS;uid=sa;pwd=123;database=CIEDC")
myConnection.Open()
End Sub
Here in the Insert event, I use the following code:
Private Sub cmdAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAdd.Click
Try
myConnection.Open()
myCommand = New SqlCommand("INSERT INTO tblBook(BookCode, BookTitle, Author, PublishingYear, Price, EnterDate, CatID, RackID, Amount) VALUES('" & txtBookCode.Text & "','" & txtTitle.Text & "','" & txtAuthor.Text & "','" & txtPublishYear.Text & "','" & txtPrice.Text & "', #" & txtEnterDate.Text & "#, " & txtCategory.Text & "," & txtRack.Text & "," & txtAmount.Text & ")")
myCommand.ExecuteNonQuery()
MsgBox("The book named '" & txtTitle.Text & "' has been inseted successfully")
ClearBox()
Catch ex As Exception
MsgBox(ex.Message())
End Try
myConnection.Close()
End Sub
And It produces the following error:
ExecuteNonQuery: Connection property has not been initialized
Connection Assignment - You aren't setting the connection property of the SQLCommand. You can do this without adding a line of code. This is the cause of your error.
myCommand = New SqlCommand("INSERT INTO tblBook(BookCode, BookTitle, Author, PublishingYear, Price, EnterDate, CatID, RackID, Amount) VALUES('" & txtBookCode.Text & "','" & txtTitle.Text & "','" & txtAuthor.Text & "','" & txtPublishYear.Text & "','" & txtPrice.Text & "', #" & txtEnterDate.Text & "#, " & txtCategory.Text & "," & txtRack.Text & "," & txtAmount.Text & ")", MyConnection)
Connection Handling - You also need to remove `MyConnection.Open' from your Load Handler. Just open it and close it in your Click Handler, as you are currently doing. This is not causing the error.
Parameterized SQL - You need to utilize SQL Parameters, despite the fact that you are not using a Stored Procedure. This is not the cause of your error. As Conrad reminded me, your original code dumps values straight from the user into a SQL Statement. Malicious users will steal your data unless you use SQL Parameters.
Dim CMD As New SqlCommand("Select * from MyTable where BookID = #BookID")
CMD.Parameters.Add("#BookID", SqlDbType.Int).Value = CInt(TXT_BookdID.Text)
You need to set the Connection property on the command:
myCommand.Connection = myConnection
Pretty much what the error message implies - the Connection property of the SqlCommand object hasn't been assigned to the connection you opened (in this case you called it myConnection).
Also, a word of advice here. Do some reading on sql parameters - doing sql concatenation from user input without any sanity checks is the way SQL injection attacks happen.
This is one way to do it:
Private Sub cmdAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAdd.Click
Try
myConnection.Open()
myCommand = New SqlCommand( _
"INSERT INTO tblBook(BookCode, BookTitle, Author, PublishingYear, Price, " & _
" EnterDate, CatID, RackID, Amount) " & _
"VALUES(#bookCode, #bookTitle, #author, #publishingYear, #price, #enterDate, " & _
" #catId, #rackId, #amount)")
myCommand.Connection = myConnection
with myCommand.Parameters
.AddWithValue("bookCode", txtBookCode.Text)
.AddWithValue("bookTitle", txtTitle.Text)
.AddWithValue("author", txtAuthor.Text)
.AddWithValue("publishingYear", txtPublishYear.Text)
.AddWithValue("price", txtPrice.Text)
.AddWithValue("enterDate", txtEnterDate.Text)
.AddWithValue("catId", txtCategory.Text)
.AddWithValue("rackId", txtRack.Text)
.AddWithValue("amount", txtAmount.Text)
end with
myCommand.ExecuteNonQuery()
MsgBox("The book named '" & txtTitle.Text & "' has been inseted successfully")
ClearBox()
Catch ex As Exception
MsgBox(ex.Message())
End Try
myConnection.Close()
End Sub
Module Module1
Public con As System.Data.SqlClient.SqlConnection
Public com As System.Data.SqlClient.SqlCommand
Public ds As System.Data.SqlClient.SqlDataReader
Dim sqlstr As String
Public Sub main()
con = New SqlConnection("Data Source=.....;Initial Catalog=.....;Integrated Security=True;")
con.Open()
frmopen.Show()
'sqlstr = "select * from name1"
'com = New SqlCommand(sqlstr, con)
Try
com.ExecuteNonQuery()
'MsgBox("success", MsgBoxStyle.Information)
Catch ex As Exception
MsgBox(ex.Message())
End Try
'con.Close()
'MsgBox("ok", MsgBoxStyle.Information, )
End Sub
End Module
Please try to wrap the use of your connections (including just opening) inside a USING block. Assuming the use of web.config for connection strings:
Dim connection As New SqlConnection(ConfigurationManager.ConnectionStrings("web.config_connectionstring").ConnectionString)
Dim query As New String = "select * from Table1"
Dim command as New SqlCommand(query, connection)
Using connection
connection.Open()
command.ExecuteNonQuery()
End Using
And PARAMETERIZE anything user-entered.. please!