2013-03-27 2 views
1

У меня есть эта функция, работающая наполовину справа. Часть, которая работает правильно, я могу выбрать строку в DataGridView, вызвать эту функцию с помощью кнопки «Удалить строку», а затем она удалит строку из DataGridView .... Однако она не удаляет строку в базе данных.Удалить строку из базы данных с помощью OleDb

Может ли кто-нибудь помочь мне с удалением строки из БД с помощью OleDb?

Function DeleteTableRow() 
    Dim TaxConnStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ConfigurationManager.AppSettings("Database") 
    Dim dbConnection = New OleDbConnection(TaxConnStr) 

    Try 
     Dim dbCommand As OleDbCommand = New OleDbCommand 
     Dim rdr2 As OleDbDataReader 

     Dim selectedRow = DataGridView1.SelectedRows 

     dbCommand.CommandText = "DELETE FROM UserCriteria WHERE RowID =" & selectedRow 
     If dbConnection.State = ConnectionState.Closed Then 
      dbConnection.Open() 
     End If 

     dbCommand.Connection = dbConnection 
     rdr2 = dbCommand.ExecuteReader 
     dbCommand.ExecuteNonQuery() 


     rdr2.Close() 

     '''Must select entire row to delete 
     'DataGridView1.Rows.Remove(DataGridView1.Rows(DataGridView1.SelectedCells.Item(0).RowIndex)) 

     '''allows you to select on cell in the row to delete entire row 
     For Each oneCell As DataGridViewCell In DataGridView1.SelectedCells 
      If oneCell.Selected Then 
       DataGridView1.Rows.RemoveAt(oneCell.RowIndex) 
      End If 
     Next 



    Catch ex As Exception 
     MsgBox(ex.Message) 
    Finally 
     dbConnection.Close() 
    End Try 
End Function 

ответ

2

DataGridView.SelectedRows представляет собой сборник DataGridViewRow, вы не можете использовать коллекцию в качестве параметра для удаления определенного и конкретную запись в таблице базы данных , (У вас есть OPTION STRICT set tot OFF?)

Вам нужно зациклиться на коллекции, получить правильное значение ID из каждой строки и использовать это значение как параметр для вашего запроса на удаление.

If dbConnection.State = ConnectionState.Closed Then 
    dbConnection.Open() 
End If 

' Creating the command and its parameter here before entering the loop to avoid a continue' 
' create and destroy pattern for the OleDbCommand' 
Dim dbCommand As OleDbCommand = New OleDbCommand 
dbCommand.CommandText = "DELETE FROM UserCriteria WHERE ID =?" 
dbCommand.Connection = dbConnection 
dbCommand.Parameters.AddWithValue("@row", 0) 
Dim rows = DataGridView1.SelectedRows 
For Each row in rows 
    dbCommand.Parameters("@row").Value = row.Cells("ID").Value) 
    dbCommand.Connection = dbConnection 
    dbCommand.ExecuteNonQuery() 
Next 

Обратите внимание на то, чтобы не использовать конкатенацию строк для создания команд sql. Эта привычка приводит к цельной банке червя под названием Sql Injection

Конечно, OleDbDataReader здесь не нужен. (Ничего не читать)

+0

Исправления --- имя столбца в базе данных - это просто «ID». Кроме того, в DataGridView у меня этот столбец (столбец «ID») установлен в скрытый. это проблема? – MaylorTaylor

+0

Нет, просто измените код, чтобы отразить этот факт. Я обновлю ответ – Steve

+0

Ваш цикл For кажется неправильным. У меня есть «Для каждого selectedRow в Datagridview1.selectedrows» ... – MaylorTaylor

1

Вам не нужен читатель, чтобы удалить строку. никакие данные не будут возвращены

rdr2 = dbCommand.ExecuteReader 
    dbCommand.ExecuteNonQuery() 


    rdr2.Close() 

должно быть просто

dbCommand.ExecuteNonQuery() 
0

Проблема в том, что ваш DataGridView1.SelectedRows вернет SelectedRowCollection (извините, я сделал это предположение, это приложение WinForms). И это не даст вам правильный результат при передаче в ваш CommandText, потому что вы, вероятно, получите ToString() SelectedRowCollection, а не идентификатор, который вы после

Что вы на самом деле хотите сделать, это цикл сбор (если пользователь имеет возможность выбрать более одной строки) и удалить каждую строку, которая была выбрана, что-то вроде:

For Each selectedRow in DataGridView1.SelectedRows 
    '1. Get the DatabaseId of the selected row 
    '2. Modify dbCommand.CommandText to use the selected row from 1 
    '3. execute command like you are doing with ExecuteNonQuery 
Next 

каждый selectedRow в выше будет иметь this типа ... который имеет Cells свойство, к которому вы можете получить доступ, чтобы получить требуемый идентификатор (я не уверен, в какой ячейке он будет находиться, но вы должны быть в состоянии сказать из своего кода).

Смежные вопросы