2

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.

cool water
  • 25
  • 2
  • 7
  • got it removed the using statement myownSqlCommandBuilderCode and revised my update storedproc to solve the concurrency problem. – cool water Oct 31 '13 at 08:22

2 Answers2

1

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!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Tnx for the help and advice. I will rename my storedprocs. How can I pass the datagridview values to the da.Parameters? da.insertcommand.parameters.addwithvalue(?) – cool water Oct 28 '13 at 16:43
  • do i need to loop the datagridview? – cool water Oct 28 '13 at 17:03
  • is this correct? da.insertcommand.parameters.addwithvalue("@paramName",datagridview.textboxColumn)? I'm having an error on my Savebutton_click event da.update(dt). Connection string is not initilized. – cool water Oct 28 '13 at 17:17
  • @coolwater: *connection string not initialized* means you haven't properly constructed a `SqlConnection` for that command. Also: no, you don't have to loop the data grid view; the underlying `DataTable` will keep track of what rows have been added, updated, deleted and will use the appropriate commands from the `SqlDataAdapter` to handle the operation as needed. – marc_s Oct 28 '13 at 18:04
  • Question: how can I use datagridview row values for the command parameters collection? – cool water Oct 29 '13 at 04:45
  • I managed to make the sqlcommanbuilder to work. But my aim is to duplicate sqlcommandbuilder in code using storedprocedures . I'm stuck. :-( – cool water Oct 29 '13 at 13:41
  • 1
    I got the step by step solution by reading this vbforums [link](http://www.vbforums.com/showthread.php?469872-Retrieving-and-Saving-Data-in-Databases&highlight=) Thanks to jmcilhinney. – cool water Oct 31 '13 at 08:24
0

You can use following code and Note:String is my procedure name

 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Try
        Dim str As String = "server=.;UID=sa;PWD=123456;database=MYdatabase"
        Dim con As New SqlConnection(str)
        Dim com As String = "proc_Ticket_Details"
        Dim Adpr As New SqlDataAdapter(com, con)
        Dim ds As New DataSet()
        Adpr.Fill(ds)
        DataGridView1.DataSource = ds.Tables(0)
        'MessageBox.Show("View Data here")

    Catch ex As Exception
        MessageBox.Show("ERROR: " & ex.Message)            
    End Try
End Sub