You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET连接MySQL报错‘Connection must be valid and open’求助

求助:MySQL与Visual Studio连接报错 "Connection must be valid and open"

尝试通过MySQL和Visual Studio连接数据库时,遇到**"Connection must be valid and open"错误,试过各种办法都解决不了。补充:在第一个Try块前添加conexionBD.Open()时,又出现"connection property is not set or null"**错误,本人是VB新手,求帮忙看下代码哪里出问题了。

我的代码:

Imports MySql.Data.MySqlClient

Public Class Login

Friend conexionBD = New MySqlConnection
Friend sServidor As String = "localhost"
Friend susuario As String = "root"
Friend sclave As String = ""
Friend sBaseDatos As String = "bd_usuarios"
Friend cmdUsuarios As MySqlCommand
'Friend dtUsuarios As New DataTable
Friend sSqlusuario, slogin, sNombres, sApellidos, scontrasena As String
Private Property sNombre As Object

Private Sub btn_aceptar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_aceptar.Click
    'Dim cmdUsuarios As MySqlConnection
    'Dim dtUsuarios As New DataTable
    slogin = ""
    sclave = ""
    If txt_usuario.Text = "" Then
        MsgBox("El login no puede estar en blanco")
        txt_usuario.Focus()
    ElseIf txt_clave.Text = "" Then
        MsgBox("La clave no puede estar en blanco")
        txt_clave.Focus()
    Else
        ' conexion a la base de datos bd_usuarios()
        Try
            sSqlusuario = "SELECT * FROM usuario WHERE usuario = '" & txt_usuario.Text & "';"
            cmdUsuarios = New MySqlCommand()
            cmdUsuarios.Connection = conexionBD
            cmdUsuarios.CommandType = CommandType.Text
            Dim ConsultaSQL As System.Data.IDataReader
            ConsultaSQL = cmdUsuarios.ExecuteReader()
            While ConsultaSQL.Read
                'Ejecuto la consulta y asigno el resultado
                slogin = ConsultaSQL("Usuario")
                sclave = ConsultaSQL("clave")
            End While

            If slogin = txt_usuario.Text Then
                If sclave = txt_clave.Text Then
                    MessageBox.Show("Bienvenido al Sistema", "Sistema")
                Else
                    MsgBox("clave errada o no encontrada")
                    txt_clave.Focus()
                    ConsultaSQL.Close()
                    conexionBD.Close()
                End If
            Else
                MessageBox.Show("Usuario no existe")
                txt_usuario.Focus()
                ConsultaSQL.Close()
                conexionBD.Close()
            End If
        Catch ex As Exception
            conexionBD.Close()
            MsgBox("Error" & vbCrLf & ex.Message.ToString)
        End Try
    End If
End Sub
Private Sub btn_cancelar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_cancelar.Click
    conexionBD.Close()
    Application.Exit()
End Sub
Public Function bd_usuario()
    Try
        'Dim conexion = New MySqlConnection()
        conexionBD.ConnectionString = "server=" & sServidor & ";" & "user id=" & susuario & ";" & "password=" & sclave & "; database= " & sBaseDatos & "; port=3306;"
        conexionBD.Open()
        Return True
    Catch ex As Exception
        MessageBox.Show("No se puede conectar con la base de datos")
        End
    End Try
End Function

Private Sub Frm_login_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

End Sub
End Class

问题分析与修复方案

你的代码主要有几个核心问题:

  1. 未调用连接初始化函数:你写了bd_usuario()函数用来设置连接字符串并打开连接,但在点击事件里完全没调用它,导致conexionBD始终是未配置状态,直接调用ExecuteReader肯定报错。

  2. 变量名冲突:你在模块级定义了sclave(数据库密码),但在点击事件里又重新赋值sclave = "",这会覆盖掉原来的数据库密码,导致连接字符串里的密码变成空(如果你的root密码本来就空还好,但逻辑上是错误的)。

  3. SQL注入风险:直接拼接用户输入到SQL语句里,很容易被注入攻击,必须用参数化查询。

  4. 资源未正确释放:DataReader和Connection没有用Using语句自动释放,容易导致资源泄漏。

修复后的代码如下:

Imports MySql.Data.MySqlClient

Public Class Login

    Friend conexionBD As MySqlConnection
    Friend sServidor As String = "localhost"
    Friend susuario As String = "root"
    Friend sDBPassword As String = "" ' 重命名避免和输入的密码变量冲突
    Friend sBaseDatos As String = "bd_usuarios"

    Private Sub btn_aceptar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_aceptar.Click
        Dim inputLogin As String = txt_usuario.Text.Trim()
        Dim inputClave As String = txt_clave.Text.Trim()

        If String.IsNullOrEmpty(inputLogin) Then
            MsgBox("El login no puede estar en blanco")
            txt_usuario.Focus()
            Return
        End If

        If String.IsNullOrEmpty(inputClave) Then
            MsgBox("La clave no puede estar en blanco")
            txt_clave.Focus()
            Return
        End If

        ' 使用Using语句自动释放连接和命令对象
        Using conexionBD = New MySqlConnection($"server={sServidor};user id={susuario};password={sDBPassword};database={sBaseDatos};port=3306;")
            Try
                conexionBD.Open()
                ' 参数化查询,避免SQL注入
                Dim sSqlusuario As String = "SELECT usuario, clave FROM usuario WHERE usuario = @Usuario;"
                Using cmdUsuarios As New MySqlCommand(sSqlusuario, conexionBD)
                    cmdUsuarios.Parameters.AddWithValue("@Usuario", inputLogin)
                    Using ConsultaSQL As MySqlDataReader = cmdUsuarios.ExecuteReader()
                        Dim dbLogin As String = ""
                        Dim dbClave As String = ""

                        If ConsultaSQL.Read() Then
                            dbLogin = ConsultaSQL("usuario").ToString()
                            dbClave = ConsultaSQL("clave").ToString()
                        End If

                        If dbLogin = inputLogin Then
                            If dbClave = inputClave Then
                                MessageBox.Show("Bienvenido al Sistema", "Sistema")
                            Else
                                MsgBox("clave errada o no encontrada")
                                txt_clave.Focus()
                            End If
                        Else
                            MessageBox.Show("Usuario no existe")
                            txt_usuario.Focus()
                        End If
                    End Using ' 自动关闭DataReader
                End Using ' 自动释放Command
            Catch ex As Exception
                MsgBox($"Error: {ex.Message}")
            End Try
            ' 连接会在Using块结束时自动关闭,不用手动Close
        End Using
    End Sub

    Private Sub btn_cancelar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_cancelar.Click
        Application.Exit()
    End Sub

    Private Sub Frm_login_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        ' 可以在这里提前测试连接,或者啥都不做
    End Sub
End Class

关键修复点说明:

  • 去掉了冗余的bd_usuario()函数,直接在Using块里创建并配置连接,更简洁安全。
  • 用Using语句包裹Connection、Command、DataReader,确保资源自动释放,不会出现未关闭的连接。
  • 使用参数化查询@Usuario,彻底避免SQL注入风险。
  • 重命名了数据库密码变量sDBPassword,避免和用户输入的密码变量冲突。
  • 简化了逻辑,去掉了不必要的模块级变量,减少错误可能性。

内容的提问来源于stack exchange,提问作者arjunagil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 04:15:35