Looks to me like you have a mistake in this line:
If Convert.ToBoolean(d.Cells(3).Value) = True Then
I assume you meant to write this?:
If Convert.ToBoolean(row.Cells(3).Value) = True Then
Apart from that:
1) If you've put Booleans into column 3 of your DataGridView then there are still Booleans in there when you want to read it. So you don't need to convert them - just cast them:
If CBool(row.Cells(3).Value) = True Then
This will prevent unintended conversions from typing mistakes and thus save you from potentially hard to find bugs. Because Convert will convert almost anything to anything else.
2) Don't use string concatenation to build SQL-statements. Use
SqlParameters[
^] instead. Saves you from potential SQL-injection and makes your code more readable (especially for larger SQL-statements).
5) Use your database-objects (Connection, Command, Transaction, DataReader etc) in
using
-blocks and declare them only locally in order to release the resources as soon as possible.
4) Use
Transactions[
^]. With transactions you can let several SQL-statements succeed or fail as a whole. If for whatever reason the first of your delete-statements here succeed and then a following one fails you have an inconsistent database.
5) Don't swallow Exceptions. Meaning: Don't catch them and then do nothing about it. At least notify the user.
This is how I would recommend it (short one point, mentioned below):
Dim connectionString As String = "your connection string"
Try
Using con As New SqlConnection(connectionString)
Using trans As SqlTransaction = con.BeginTransaction(IsolationLevel.Serializable)
Using cmd As New SqlCommand("", con, trans)
Dim sb As New StringBuilder()
Dim parameterIndex As Integer = 0
For Each row As DataGridViewRow In DGV.Rows
If CBool(row.Cells(3).Value) = True Then
Dim parameterName As String = "@p" + parameterIndex
sb.AppendLine([String].Format("DELETE FROM Student WHERE ID = {0};", parameterName))
cmd.Parameters.AddWithValue(parameterName, row.Cells(0).Value)
parameterIndex += 1
End If
Next
cmd.CommandText = sb.ToString()
cmd.ExecuteNonQuery()
trans.Commit()
End Using
End Using
End Using
Catch ex As SqlException
MessageBox.Show("A database error occurred and the attempted deletion of records failed as a whole. Error Detail: " + ex.Message)
End Try
Even better would be to use a
DbProviderFactory[
^] to create the database-vendor-agnostic basetypes DbConnection, DbCommand etc. instead of the SQL-Server-specific versions used here. Because then you have an easy (or easier) time adapting your code to work with a different database system.
(I used a code converter to convert this code from my C#-draft to VB.NET - didn't test-run it.)