0

For some reason I cannot get my record to update. Here goes:

I have a Windows form, that will upon loading display the current status of an aircraft. If that status changes I can select the value from a combobox (cboServ). When I click the Exit button from that form the status should update, so upon loading the form again the new value appears. However it doesn't.

This is what I have currently as the code:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim updateQuery As String = "UPDATE dbo.aircraft SET dbo.aircraft.condition = @OE_status WHERE aircraft.avNum = 'ab201'"

    Dim updateCmd As New SqlCommand(updateQuery, con)
    updateCmd.Parameters.Add("@OE_status", cboServ.SelectedValue)
    MessageBox.Show("it worked")
    con.Close()
    Me.Close()
    Form1.Show()
End Sub

The error I get back is - which I don't fully understand:

System.InvalidCastException: 'Conversion from type 'DataRowView' to type 'String' is not valid.'

This comes from the line reading cboServ.SelectedValue.

halfer
  • 19,824
  • 17
  • 99
  • 186
gherkin12
  • 9
  • 1
  • 3
  • Which line produces the error? I wonder if you're expecting `cboServ.SelectedValue` to resolve as a string, and it is giving you a `DataRowView` instead. – halfer May 05 '18 at 16:32
  • @halfer my apolgies, it is the line containing theh [code]cboServ.SelectedValue[/code] – gherkin12 May 05 '18 at 16:41
  • OK, so use your autocomplete to get a value out of that object. Maybe it is `cboServ.SelectedValue.Something` where `Something` is the bit you have to work out using autocomplete. – halfer May 05 '18 at 16:42
  • (As you can see, BBCode does not work here. Use backticks in comments to render small pieces of code). – halfer May 05 '18 at 16:43
  • 2
    That error on the line you specify (updateCmd.Parameters.ADD…..) looks very odd indeed. However ignoring that the code you show here sets up the command to update the row but never actually executes it. I would be completely surprised if the code shown here ever did anything to the database. – simon at rcl May 05 '18 at 16:44
  • @gherkin12 What code did you use to put the values into cboServ? That will affect how you get the values back out of it. – Andrew Morton May 05 '18 at 21:00
  • @Andrew Morton. The code for the combobox is: `Dim cboItem As SqlDataAdapter = New SqlDataAdapter("select condition from dbo.aircraft WHERE dbo.aircraft.avNum = 'ZZ201'", connection) _ Dim cbox As New DataTable _ cboItem.Fill(cbox) _ With cboServ .DisplayMember = "condition" .DataSource = cbox End With` - the initial value of the combobox is filled by calling the that statement. The remaining values which appear on dropdown are from using the statement `SELECT condition FROM dbo.status`. Where the underscores are that implies is on a new line – gherkin12 May 06 '18 at 11:33

2 Answers2

0

There is more than one problem with the code as shown.

First, you should use Option Strict On to make sure that the types of all the variables used match up properly.

You can isolate the problem more easily by separating the things being done in the button click handler out into other methods. For example, we could put the database interaction into its own method:

Sub UpdateAircraftCondition(avNum As String, condition As String)
    Dim connStr = "YOUR CONNECTION STRING HERE"
    Dim updateQuery As String = "UPDATE dbo.aircraft SET dbo.aircraft.condition = @OE_status WHERE aircraft.avNum = @AvNum"

    Using conn As New SqlConnection(connStr)
        Using cmd As New SqlCommand(updateQuery, conn)
            cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@AvNum", .SqlDbType = SqlDbType.NVarChar, .Size = 16, .Value = avNum})
            cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@OE_Status", .SqlDbType = SqlDbType.NVarChar, .Size = 16, .Value = condition})
            conn.Open()
            cmd.ExecuteNonQuery()
            conn.Close()

        End Using
    End Using

End Sub

(You will need to make the Size (for string data) and SqlDbType match up to the columns in the database.)

Notice how the connection only exists where it is needed - the Using construct takes care of disposing of unmanaged resources (like the SqlConnection) to keep memory tidied up and not leaking.

Instead of putting the actual connection string in everywhere, which makes it a lot of hassle to change it, it is normal to put it in some settings file, for example by using My.Settings.

According to the error message, cboServ.SelectedValue is a DataRowView, not a String. Which makes me wonder if cboServ is not a ComboBox. But we can get a useful error message by trying the following code for the button click event handler:

Private Sub bnUpdateCondition_Click(sender As Object, e As EventArgs) Handles bnUpdateCondition.Click

    If cboServ.SelectedIndex >= 0 Then
        Dim aircraftCondition = cboServ.SelectedItem.ToString()
        Dim avNum = "ab201"
        UpdateAircraftCondition(avNum, aircraftCondition)

        ' more code may go here

    End If

End Sub

Please note that I tried to give the button a meaningful name: doing that will make it much easier for you in the future than trying to figure out what "Button337" is for.

Andrew Morton
  • 24,203
  • 9
  • 60
  • 84
  • Thank you very much for the above, makes my code considerable neater!! Unfortuantly i'm now getting another error (one i've not had before) `The UPDATE statement conflicted with the FOREIGN KEY constraint "condition1". The conflict occurred in database "status", table "dbo.status", column 'condition'.` I thought it may have been to do with On Update Cascade which I altered the FK to, however that didn't appear to have any effect. – gherkin12 May 06 '18 at 11:36
  • @gherkin12 At least it is progress :) That's a different question, but perhaps one of the answers or comments in [Sql error on update : The UPDATE statement conflicted with the FOREIGN KEY constraint](https://stackoverflow.com/q/23856420/1115360) will help. – Andrew Morton May 06 '18 at 14:52
  • @gherkin12 - that error is a database problem, not vb – Ess Kay May 07 '18 at 13:40
-1

Change the row:

updateCmd.Parameters.Add("@OE_status", cboServ.SelectedValue)

to:

updateCmd.Parameters.AddWithValue("@OE_status", cboServ.SelectedValue.ToString())

or you can use a explicit cast:

var dataRowView = cboServ.SelectedValue as DataRowView;
var row = dataRowView.row As MyDataTableDefinition;
updateCmd.Parameters.AddWithValue("@OE_status", row[“OE_status”].ToString())
Linefinc
  • 375
  • 2
  • 9
  • 1
    This should be vb.net. Looks like C# to me. – Mary May 05 '18 at 20:21
  • Please never ever suggest using AddWithValue: [Can we stop using AddWithValue() already?](https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/) – Andrew Morton May 05 '18 at 20:28