0
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim n As Integer = 0
    str = "select Vote from vote where party='Green'"
    cmd = New SqlCommand(str, con)
    con.Open()
    dr = cmd.ExecuteReader()
    if dr.HasRows Then
      dr.Read()
      n = dr("Vote").ToString()
      n = n + 1
      Label8.Text = n.ToString()
    End If

    str = "update Vote set vote='" + n.ToString() + "' where party='Green'"
    cmd = New SqlCommand(str, con)
    cmd.ExecuteNonQuery()
    dr.Read()
    cmd.Dispose()
    con.Close()

End Sub
4

3 に答える 3

1

メッセージはかなり明確なようです。別の操作に接続を使用する前に、DataReader を閉じる必要があります

MSDNによると

SqlDataReader が使用されている間、関連付けられた SqlConnection は SqlDataReader を提供するためにビジーであり、SqlConnection を閉じる以外の操作は実行できません。これは、SqlDataReader の Close メソッドが呼び出されるまでのケースです。たとえば、Close を呼び出すまで、出力パラメーターを取得することはできません。

....
dr.Close()
str = "update Vote set vote='" + n.ToString() + "' where party='Green'"
cmd = New SqlCommand(str, con)
cmd.ExecuteNonQuery()
' ??? dr.Read()
cmd.Dispose()
con.Close()

ところで、ExecuteScalar を使用して最後の投票値を取得し、DataReader をダンプすることで、コード全体を簡素化できます。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim n As Integer = 0
    str = "select Vote from vote where party='Green'"
    Using cmd = New SqlCommand(str, con)
        con.Open()
        Dim n as Integer
        Dim result = cmd.ExecuteScalar()
        if result IsNot Nothing Then
            n = Convert.ToInt32(result) + 1
        else
            n = 1
        End If
        Label8.Text = n.ToString()
        str = "update Vote set vote='" + n.ToString() + "' where party='Green'"
        cmd.CommandText = str
        cmd.ExecuteNonQuery()
        con.Close()
    End Using
End Sub

このシナリオでは、グローバル接続オブジェクトを使用しますが、これは避ける必要があります。接続を使用する必要がある場合は、接続を作成し、開き、使用し、破棄することをお勧めします。SqlClient クラスは、接続のような貴重なリソースの管理に大いに役立つ接続プールインフラストラクチャを使用できます。

于 2013-09-26T08:51:49.200 に答える