0
Private Sub txt_sname_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles txt_sname.GotFocus
        Dim fcs As String
        fcs = "select fname,dept from nstudent where stid = '" & txt_sid.Text & "'"
        scmd1 = New SqlCommand(fcs, con)
        dr1 = scmd1.ExecuteReader
        If dr1.HasRows Then
            Do While (dr1.Read)
                txt_sname.Text = dr1.Item(0)
                cmb_dept.Text = dr1.Item(1)
            Loop
        Else
            MsgBox("Not Found")
        End If
        scmd1.Dispose()
        If Not dr1.IsClosed Then dr1.Close()
End Sub

上記のデータベースからのデータのコードとテキストボックスへのパス。プログラムを実行して、データベースに既に存在するデータをチェックすると、正常に動作します。しかし、他のデータ(dbに存在しない)をチェックすると、エラーが発生して終了します。

エラー: 「このコマンドに関連付けられた開いている DataReader が既に存在します。これを最初に閉じる必要があります。」

助けてください..

4

1 に答える 1

1

いくつかの観察:

グローバル コマンド オブジェクトを使用する代わりに、ローカル コマンド オブジェクトを使用します。特に、とにかく新しいコマンドを作成しているためです。そして、これはdr1にも当てはまるようです。

SQL インジェクションを防いでいるわけではないため、誰かがtxt_sidデータを削除したり、テーブルをドロップしたり、データベース内の他のデータにアクセスしたりすることで、セキュリティ上の問題を引き起こすテキストを入力することができます。

同じ変数を複数回ループして設定しています。レコードが 1 つしかない場合は、わざわざループしないでください。

全体を try/catch でラップする

Private Sub txt_sname_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles txt_sname.GotFocus
    Dim cmd1 As SqlCommand = New SqlCommand(fcs, "select fname,dept from nstudent where stid = @stid")
    cmd1.Parameters.Parameters.AddWithValue("@stid", txt_sid.Text)

    Dim studentReader as SqlDataReader

    Try
        studentReader = scmd1.ExecuteReader
        If studentReader.Read Then
            txt_sname.Text = studentReader.Item(0)
            cmb_dept.Text = studentReader.Item(1)
        Else
            MsgBox("Not Found")
        End If
    Finally
        studentReader.Close()
        cmd1.Dispose()
    End Try
End Sub

最後に、txt_sname がフォーカスを取得したときではなく、txt_sid が変更されたときに実際にこれを行うことをお勧めします。

于 2013-03-17T21:07:30.637 に答える