Question

I was doing a bit of refactoring today and suddenly my code to insert/update a database table which has been working for as long as I can remember, is not longer working and is throwing the following error:

InvalidOperationException: Update requires a valid InsertCommand when passed DataRow collection with new rows.

The code is as follows:

' Update a field if it exists or insert a new row
' (should be an insert 99.99% of the time but not guaranteed)
Public Sub InsertOrUpdateValues(... multiple parameters ...)
    Dim da As New SqlDataAdapter
    Dim dt As New DataTable()
    Dim dr As DataRow

    Dim commandText As String = "select * from Table_Name where Col_Name1 = '" & value1 & "' AND Col_Name2 = '" & value2 & "'"
    Dim sqlCommand As New SqlCommand(commandText, connection)

    da.SelectCommand = sqlCommand
    da.Fill(dt)

    If dt.Rows.Count = 0 Then
        dr = dt.NewRow()
        dt.Rows.Add(dr)
    Else
        dr = dt.Rows(0)
    End If

    dr("Col_Name3") = value3
    ' ... more of these assignments ...
    dr("Col_NameN") = valueN

    da.Update(dt)
End Sub

I'm not sure what happened to break the code. I've looked at this MSDN link but I'm not sure how to apply it to the way I have things done with the DataTable. Is there a "best practice" way to do this?

Était-ce utile?

La solution

I guess I should have done a little more searching first as I found an answer using CommandBuilder

Dim commandBuilder As New SqlCommandBuilder(da)
If dt.Rows.Count = 0 Then
    dr = dt.NewRow()
    dt.Rows.Add(dr)
    da.InsertCommand = commandBuilder.GetInsertCommand(True)
Else
    dr = dt.Rows(0)
    da.UpdateCommand = commandBuilder.GetUpdateCommand(True)
End If

I've also added constants for my Table/Column names for easier maintenance and am now using queries with parameters.

Const commandText As String = "select * from " & Table.Name & " where " & Table.Column1 & " = @Value1 AND " & Table.Column2 & " = @Value2"
Dim sqlCommand As New SqlCommand(commandText, _connection)
sqlCommand.Parameters.Add("@Value1", SqlDbType.Type).Value = value1
sqlCommand.Parameters.Add("@Value2", SqlDbType.Type).Value = value2

This should be a bit better but I'm still open to more suggestions if you still want to comment.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top