I'm new to vb.net. Please bear with me. I would like to learn how to insert, update, delete data in a Datagridview
. So far I learned the best approach to this is to bind the DatagridView
to a DataTable
? The requirement is to use stored procedures. I'm not allowed to directly access database tables.
My public variables:
Public intDisbursementID As Long
Dim CS As String = ConfigurationManager.ConnectionStrings("SimpleAccounting.My.MySettings.SimpleAcctgConnectionString").ConnectionString
Dim cb As SqlCommandBuilder = Nothing
Dim da As SqlDataAdapter = Nothing
Dim ds As DataSet = Nothing
Dim dv As DataView
Dim dt As DataTable
Dim bs As BindingSource
Dim isDataLoaded As Boolean
My code below for from Load:
Private Sub LoadDetailsData(ByVal mDisbursementID As Long)
Using con As SqlConnection = New SqlConnection(CS)
Try
da = New SqlDataAdapter("sp_NET_tblDisbursementDetails_CompanyID_DisbursementID", CS)
da.SelectCommand.CommandType = CommandType.StoredProcedure
da.SelectCommand.Parameters.AddWithValue("@CompanyID", CInt(ConfigurationManager.AppSettings("CompanyID")))
da.SelectCommand.Parameters.AddWithValue("@DisbursementID", CLng(mDisbursementID))
cb = New SqlCommandBuilder(da)
''======== I have no idea how to make this work ===============
'da.InsertCommand = SqlCommand.GetInsertCommand()
'da.UpdateCommand = SqlCommand.GetUpdateCommand()
'da.DeleteCommand = SqlCommand.GetDeleteCommand()
'==============================================================
dt = New DataTable
bs = New BindingSource
da.Fill(dt)
bs.DataSource = dt
dgvDisbursementDetails.DataSource = bs
'dgvDisbursementDetails.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Using
End Sub
My button save code:
da.Update(dt)
Question: I can't figure out a way how to make the SqlCommandBuilder
to work. Is there a way for me to override the SqlCommandBuilder
and use my existing insert, update, delete stored procedures?
I think I found a solution: (but I really don't understand the side effects on the database side.) Since SQLCommandBuilder made the insert, update, delete commands for me, does it mean I no longer need my existing insert, update, delete stored procedures? Direct table access is not allowed in my company I work.
Below my updated code:
Private Sub LoadDetailsData(ByVal mDisbursementID As Long)
Using con As SqlConnection = New SqlConnection(CS)
Try
'con.Open()
da = New SqlDataAdapter("sp_NET_tblDisbursementDetails_CompanyID_DisbursementID", CS)
da.SelectCommand.CommandType = CommandType.StoredProcedure
da.SelectCommand.Parameters.AddWithValue("@CompanyID", CInt(ConfigurationManager.AppSettings("CompanyID")))
da.SelectCommand.Parameters.AddWithValue("@DisbursementID", CLng(mDisbursementID))
ds = New DataSet
da.Fill(ds)
ds.Tables(0).TableName = "Disbursements"
dgvDisbursementDetails.DataSource = ds.Tables("Disbursements")
Catch ex As Exception
Throw ex
'MessageBox.Show(ex.Message)
End Try
End Using
End Sub
cmdSaveDetails_Click Code:
cb = New SqlCommandBuilder(da)
da.Update(ds, "Disbursements")
I'm trying to duplicate the SQLCOMMANDBUILDER by creating my own insert, update, delete commands using storedprocedures. I'm stuck with this error on buttonSave_Click: sqladapter.Update(dtable) ERROR: "Concurrency violation: the UpdateCommand affected 0 of the expected 1 records"
Below my updated code:
Global Variables:
Public intDisbursementID as Long
Dim CS As String = ConfigurationManager.ConnectionStrings("SimpleAccounting.My.MySettings.SimpleAcctgConnectionString").ConnectionString
Dim sqladapter As SqlDataAdapter
Dim dset As DataSet
Dim dtable As DataTable
Form Load Code:
LoadDisbursementDetails(intDisbursementID)
myownSqlCommandBuilder(intDisbursementID)
LoadDisbursementDetails Sub Code:
Private Sub LoadDisbursementDetails(ByVal mDisbursementID As Long)
Using con As SqlConnection = New SqlConnection(CS)
Try
sqladapter = New SqlDataAdapter("sproc_DisbursementDetailsSelectByDisbursementID", con)
sqladapter.SelectCommand.CommandType = CommandType.StoredProcedure
sqladapter.SelectCommand.Parameters.AddWithValue("@DisbursementID", CLng(mDisbursementID))
dset = New DataSet
dtable = New DataTable
sqladapter.Fill(dset)
sqladapter.Fill(dtable)
dgvDisbursementDetails.DataSource = dtable
Catch ex As Exception
Throw ex
End Try
End Using
End Sub
myownSqlCommandBuilder Sub Code:
Private Sub myownSqlCommandBuilderCode(ByVal mDisbursementID As Long)
Using con As SqlConnection = New SqlConnection(CS)
Dim delete As New SqlCommand("sproc_DisbursementDetailsDelete", con)
delete.CommandType = CommandType.StoredProcedure
delete.Parameters.Add("@DisbursementDetailsID", SqlDbType.BigInt, 8, "DisbursementDetailsID")
Dim insert As New SqlCommand("sproc_DisbursementDetailsInsert", con)
insert.CommandType = CommandType.StoredProcedure
insert.Parameters.Add("@DisbursementID", SqlDbType.BigInt, 8, "DisbursementID")
insert.Parameters.Add("@CompanyID", SqlDbType.BigInt, 8, "CompanyID")
insert.Parameters.Add("@DatePosted", SqlDbType.DateTime, 8, "DatePostedID")
insert.Parameters.Add("@SLID", SqlDbType.BigInt, 8, "SLID")
insert.Parameters.Add("@Amount", SqlDbType.BigInt, 8, "Amount")
insert.Parameters.Add("@UserID", SqlDbType.BigInt, 8, "UserID")
Dim update As New SqlCommand("sproc_DisbursementDetailsUpdate", con)
update.CommandType = CommandType.StoredProcedure
update.Parameters.Add("@DisbursementID", SqlDbType.BigInt, 8, "DisbursementID")
update.Parameters.Add("@CompanyID", SqlDbType.BigInt, 8, "CompanyID")
update.Parameters.Add("@DatePosted", SqlDbType.DateTime, 8, "DatePostedID")
update.Parameters.Add("@SLID", SqlDbType.BigInt, 8, "SLID")
update.Parameters.Add("@Amount", SqlDbType.BigInt, 8, "Amount")
update.Parameters.Add("@UserID", SqlDbType.BigInt, 8, "UserID")
update.Parameters.Add("@DisbursementDetailsID", SqlDbType.BigInt, 8, "DisbursementDetailsID")
'==== Error: object reference not set to an instance of an object ====
sqladapter.DeleteCommand = delete
sqladapter.InsertCommand = insert
sqladapter.UpdateCommand = update
'======================================================================
sqladapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
End Using
End Sub
Button Save Code:
sqladapter.Update(dtable)
Please help. I'm stuck. Thanks.
Sure you can use the existing stored procedure.
Use code something like this (this is C# - but should be a breeze to convert to VB.NET):
// create a new SqlCommand as your "insert" command
da.InsertCommand = new SqlCommand("dbo.YourInsertStoredProcNameHere", con);
// define it to be a stored procedure
da.InsertCommand.CommandType = CommandType.StoredProcedure;
// add any parameters needed...
da.InsertCommand.Parameters.AddWithValue(....);
Do the same thing for the UpateCommand
and DeleteCommand
.
Side note: you should not use the sp_
prefix for your stored procedures. Microsoft has reserved that prefix for its own use (see Naming Stored Procedures), and you do run the risk of a name clash sometime in the future. It's also bad for your stored procedure performance. It's best to just simply avoid sp_
and use something else as a prefix - or no prefix at all!