SqlDataAdapter#Fill:`SelectCommand.connection` 属性尚未初始化

Posted

技术标签:

【中文标题】SqlDataAdapter#Fill:`SelectCommand.connection` 属性尚未初始化【英文标题】:SqlDataAdapter#Fill: `SelectCommand.connection` property has not been initilized 【发布时间】:2019-01-18 14:36:21 【问题描述】:

我正在为我们的论文制作一个学生管理系统。当我输入用户名和密码后单击登录按钮时,da.Fill(dt) 中出现此错误:

InvalidOperationException 未处理

Fill:SelectCommand.connection 属性尚未初始化。

这是我在登录按钮中的代码

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

    cs = "Data Source=.\SQLEXPRESS;Initial Catalog=demo;Integrated Security=True"
    con = New SqlConnection(cs)
    Dim username As String = TextBox1.Text
    Dim password As String = TextBox2.Text

    cmd = New SqlCommand("select username,password from login where 
    username='" + TextBox1.Text + "'and password'" + TextBox2.Text + "' ")
    da = New SqlDataAdapter(cmd)
    dt = New DataTable()
    da.Fill(dt)

    If (dt.Rows.Count > 0) Then
        name = TextBox1.Text
        MessageBox.Show("Login Successful", "success!", 
    MessageBoxButtons.OK, MessageBoxIcon.Information)
        content.Show()

    Else
        MsgBox("Invalid Login Information!", MessageBoxButtons.OK, 
    MessageBoxIcon.Error)

    End If

    End Sub
End Class

当我点击登录按钮时,我应该会进入主页。

这是登录:

这就是家:

【问题讨论】:

欢迎来到 ***。我编辑了您的问题以将错误消息引用为文本。同样在标题中,我放置了更详细的错误消息。重要的是按字面输入文本而不是显示文本图像,因此它们是可搜索和可访问的。我还嵌入了图像,尽管最后两个对于那些调查你的问题的人来说不是那么有用。 谢谢。抱歉,这是我第一次在这里提问。 【参考方案1】:

您必须在命令中指定要使用的连接。

cmd = New SqlCommand("select username,password from login where 
username='" + TextBox1.Text + "'and password'" + TextBox2.Text + "' ", con)

请注意,您正在连接字符串来构建您的 SQL 查询。这是非常不安全的。这会导致 SQL 注入!请至少在字符串变量中使用双引号,并检查变量的 int 变量。但我强烈建议您使用参数化变量(参见 sp_executeSql)。

cmd = New SqlCommand("select username,password from login where 
username='" + TextBox1.Text.replace("'", "''") + "'and password'" + TextBox2.Text.replace("'", "''") + "' ", con)

【讨论】:

【参考方案2】:

在线评论和解释。

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Dim cs = "Data Source=.\SQLEXPRESS;Initial Catalog=demo;Integrated Security=True"
    Dim Exists As Boolean
    'The Using block ensures that your database objects are closed and disposed
    'even if there is an error.
    Using con = New SqlConnection(cs)
        'All you need to know is if the record exists. You do not need to return
        'the values you just entered.
        'Pass the connection to the constructor of the command
        Using cmd = New SqlCommand("If Exists (Select username, password From login Where 
username=@User and password = @Password;", con)
            'Use parameters. It not only helps protect your database against SQL Injection but
            'simplifies your SQL statement
            cmd.Parameters.Add("@User", SqlDbType.VarChar).Value = TextBox1.Text
            cmd.Parameters.Add("@Password", SqlDbType.VarChar).Value = TextBox2.Text
            'You do not need a data adapter or data table for this
            'Use execute scalar when you are returning a single value
            con.Open()
            Exists = CBool(cmd.ExecuteScalar)
        End Using
    End Using
    If Exists Then
        Name = TextBox1.Text
        MessageBox.Show("Login Successful", "success!", MessageBoxButtons.OK, MessageBoxIcon.Information)
        content.Show()
    Else
        MessageBox.Show("Invalid Login Information!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End If
End Sub

编辑

永远不要将密码存储为纯文本。

【讨论】:

以上是关于SqlDataAdapter#Fill:`SelectCommand.connection` 属性尚未初始化的主要内容,如果未能解决你的问题,请参考以下文章

SqlDataAdapter.Fill(DataGridView.DataSource) 复制所有行

SqlClient.SqlDataAdapter.Fill(DataSet) 结果如果不选择查询

SqlDataAdapter.Fill 方法慢

SqlDataAdapter.Fill 方法慢

SqlDataAdapter#Fill:`SelectCommand.connection` 属性尚未初始化

SqlDataAdapter使用Fill方法填充DataSet