0

*NOTE: I deleted my previous question "Update Database from DataTable and DataAdapter" in place of this one. I have updated the wording and code to be what I am currently testing.

I am trying to update a database with info from a WinForm. I had no issues when using a “normal” SQL update command written by hand (parameters set to the text box values,) but I am trying to clean up and reduce my code and I thought I would bind the controls to a DataTable and use a DataAdapter's update command to achieve the same thing.

I have tried to get various combinations of setting parameters and update commands to work, but the Database is not getting updated from the new DataTable values. I have stepped through the code with each change and can see that the DataTable is getting the new textbox values, but those updates aren’t going to the Database. (This is seen when the Fill_Date block runs and selects all new data from the database.)

Things I’ve tried: Letting the binding get the new values vs. setting the parameters manually. Using the command builder to build the update command, using the .UpdateCommand.ExecuteNonQuery(), command and of course a straight.Update(DataTable) command.

Below is the code that I am using. I am hoping someone can tell me what it is I am doing wrong/missing, or what is the correct path to take. Is there a "best practice" or a better way to do this?

Public Class frmDATA
    Dim dt_Test As New DataTable
    Dim da_Test As New SqlDataAdapter
    Dim SQLcmd As SqlCommand

    Private Sub frmDemog_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        BuildSQL()
        Fill_Data()
        BindControls()
    End Sub

    Private Sub frmDemog_Closed(sender As Object, e As EventArgs) Handles Me.Closed
        If Not IsNothing(dt_Test) Then dt_Test.Dispose()
        If Not IsNothing(da_Test) Then da_Test.Dispose()
        If Not IsNothing(SQLcmd) Then SQLcmd.Dispose()
        Me.Dispose()
    End Sub

    Private Sub btnUpdate_Click(sender As Object, e As EventArgs) Handles btnUpdate.Click
        Update_Me()
    End Sub

    Private Sub BindControls()
        txtLName.DataBindings.Add("Text", dt_Test, "Last_Name")
        txtFName.DataBindings.Add("Text", dt_Test, "First_Name")
        txtAKA.DataBindings.Add("Text", dt_Test, "AKA")
    End Sub

    Public Sub Update_Me(RefreshSearch As Boolean, RefreshView As Boolean)
        Try
            Dim testID As Integer = frmTest.dgvSearch.CurrentRow.Cells(0).Value
            da_Test.UpdateCommand.Parameters("@ID").Value = testID
            da_Test.Update(dt_Test)

            Fill_Data()

        Catch SqlExceptionErr As SqlException
            MsgBox(SqlExceptionErr.Message, vbCritical, "Error")
        Catch ex As Exception
            MsgBox(ex.Message, vbCritical, "Error")
        End Try
    End Sub

    Public Sub Fill_Data()
        Try
            dt_Test.Clear()
            da_Test.SelectCommand.Parameters("@ID").Value = testID
            da_Test.Fill(dt_Test)

        Catch SqlExceptionErr As SqlException
            MsgBox(SqlExceptionErr.Message, vbCritical, "Error")
        Catch ex As Exception
            MsgBox(ex.Message, vbCritical, "Error")
        End Try
    End Sub

    Private Sub BuildSQL()
        '** Build Selection Query
        SQLcmd = New SqlCommand(String.Join(Environment.NewLine,
            "SELECT ",
                "data_Test.[Last_Name], ",
                "data_Test.[First_Name], ",
                "data_Test1.[Last_Name] + ', ' + data_Test1.[First_Name] as [AKA] ",
            "FROM [DB].data_Test ",
                "LEFT JOIN [DB].data_Test as data_Test1 ",
                "ON data_Test.[ID] = data_Test1.[AKA_Demog_ID] ",
            "WHERE data_Test.[ID]=@ID"
            ), Vars.sqlConnDB)

        SQLcmd.Parameters.Add("@ID", SqlDbType.Int)
        da_Test.SelectCommand = SQLcmd

        '** Build Update Query
        SQLcmd = New SqlCommand(String.Join(Environment.NewLine,
            "UPDATE [DB].data_Test SET ",
                "[Last_Name]  = @LName,",
                "[First_Name]  = @FName",
            "WHERE [ID] = @ID"
            ), Vars.sqlConnDB)

        With SQLcmd.Parameters
            .Add("@LName", SqlDbType.NVarChar, 255, "Last_Name") 'Required
            .Add("@FName", SqlDbType.NVarChar, 255, "First_Name") 'Required
            .Add("@ID", SqlDbType.Int, 0, "ID")
        End With

        da_Test.UpdateCommand = SQLcmd
    End Sub
End Class
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Cory
  • 65
  • 7
  • Personally, I would avoid trying to use the DataAdapter to perform all your updates. As you are finding out, it doesn't work out of the box as nice as it is advertised. Your SELECT query has a JOIN in it, which complicates things. See [TableAdapter UpdateCommand on JOINed table](https://stackoverflow.com/q/27743627/719186) – LarsTech Jul 11 '19 at 16:23
  • @LarsTech - I did read that previously that JOIN statements make things complicated, which is why I created my Update command manually. Just as a test I stripped out the JOIN and it still would not update correctly. The link you pointed me to gave me the idea of creating the "@ID" parameter just before updating and to set the `.SourceColumn to "ID" - Maybe I did this incorrectly, but it still did not update nor did it give any errors. Ideas? – Cory Jul 11 '19 at 16:39

0 Answers0