如何在 Using 语句中关闭 sqldatareader?

How to close the sqldatareader within Using statement?

我想在将数据保存到数据库之前使用此代码验证是否发生重复。我应该如何关闭 sqldatareader? (正如错误显示的那样)

con.ConnectionString = "Data Source=PC85AAIEw\SQLEXPRESS;Initial Catalog=Student;Integrated Security=True"
cmd.Connection = con

con.Open()

Dim theQuery As String = "SELECT * FROM Profile WHERE RollNo=@RollNo AND Name=@Name"
Dim cmd1 As SqlCommand = New SqlCommand(theQuery, con)
cmd1.Parameters.AddWithValue("@RollNo", TextBox1.Text)
cmd1.Parameters.AddWithValue("@Name", TextBox2.Text)

Using reader As SqlDataReader = cmd1.ExecuteReader()
    If reader.HasRows Then
        MessageBox.Show("User already registered! Please try again.", "Error", MessageBoxButtons.OK)
    Else
        cmd.CommandText = "INSERT INTO Profile VALUES ('" & rollno & "' , '" & name & "' , '" & gender & "' , '" & address & "' , '" & phoneno & "' , '" & datereg & "' , '" & faculty & "' , '" & course & "' , '" & semester & "')"
        MessageBox.Show("Profile has been successfully registered!", "Thank you", MessageBoxButtons.OK)
        i = cmd.ExecuteNonQuery()
    End If
End Using
con.Close()

所指的错误是因为您必须先完成数据的执行 reader,然后才能尝试在同一连接上执行另一个命令。

此外,您的代码还存在一些问题:

  • 强烈建议您使用 SqlConnections,然后在使用它们时处理它们,不要尝试在您的应用程序中全局重用它们。 ado.net SQL 服务器客户端库将默认为您处理连接池。
  • 您需要像在 select 上一样在插入中使用参数。
  • Do not to use AddWithValue 添加参数时,使用构造函数并指定 sql 数据类型。如果 RollNo 是一个数字(如整数),那么您应该将该值作为整数传递给您的参数。我假设它是一个存储在 varchar.
  • 中的字符串
  • Using 语句中包装所有实现IDisposable 的类型,以确保始终释放资源。 (如果有人想吹毛求疵,不,在这种情况下 SqlCommand 不需要 。)
Dim recordExists As Boolean
Using con As SqlConnection = New SqlConnection("Data Source=PC85AAIEw\SQLEXPRESS;Initial Catalog=Student;Integrated Security=True")
Using cmd As SqlCommand = New SqlCommand("SELECT RollNo FROM Profile WHERE RollNo=@RollNo AND Name=@Name", con)
    cmd.Parameters.Add("@RollNo", SqlDbType.VarChar).Value = TextBox1.Text
    cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = TextBox2.Text

    con.Open()
    Using reader As SqlDataReader = cmd.ExecuteReader()
        recordExists = reader.HasRows
    End Using
End Using
End Using

If recordExists Then
    MessageBox.Show("User already registered! Please try again.", "Error", MessageBoxButtons.OK)
Else
    Using con As SqlConnection = New SqlConnection("Data Source=PC85AAIEw\SQLEXPRESS;Initial Catalog=Student;Integrated Security=True")
    Using cmd As SqlCommand = New SqlCommand("INSERT INTO Profile (RollNo, Name) VALUES (@RollNo, @Name)", con)
        cmd.Parameters.Add("@RollNo", SqlDbType.VarChar).Value = TextBox1.Text
        cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = TextBox2.Text
        con.Open()
        cmd.ExecuteNonQuery()
        MessageBox.Show("Profile has been successfully registered!", "Thank you", MessageBoxButtons.OK)
    End Using
    End Using
End If

如果您正在使用 using 则不需要关闭。因为它在内部关闭了所有连接。代码会像这样

 using(var con=new Sqlconnection("Data Source=PC85AAIEw\SQLEXPRESS;Initial Catalog=Student;Integrated Security=True")){
cmd.Connection = con

con.Open()

Dim theQuery As String = "SELECT * FROM Profile WHERE RollNo=@RollNo AND Name=@Name"
Dim cmd1 As SqlCommand = New SqlCommand(theQuery, con)
cmd1.Parameters.AddWithValue("@RollNo", TextBox1.Text)
cmd1.Parameters.AddWithValue("@Name", TextBox2.Text)

Using reader As SqlDataReader = cmd1.ExecuteReader()
    If reader.HasRows Then
        MessageBox.Show("User already registered! Please try again.", "Error", MessageBoxButtons.OK)
    Else
        cmd.CommandText = "INSERT INTO Profile VALUES ('" & rollno & "' , '" & name & "' , '" & gender & "' , '" & address & "' , '" & phoneno & "' , '" & datereg & "' , '" & faculty & "' , '" & course & "' , '" & semester & "')"
        MessageBox.Show("Profile has been successfully registered!", "Thank you", MessageBoxButtons.OK)
        i = cmd.ExecuteNonQuery()
    End If
End Using
con.Close()}