- Подробности
-
Опубликовано 24.12.2015 20:39
-
Просмотров: 1382
Продолжаем писать библиотеку быстрого доступа для новых программ под SQLite. В первых двух частях (здесь и здесь) были описаны операции SELECT и INSERT. Сегодня, на ваш суд, я представляю код для операции DELETE. Операция жесткая… Пользоваться аккуратно. Можно остаться без данных, а может и без пальцев ;) , смотря какие данные завалить.
Исходя из нашей философии написания этого класса, мудрить сильно не будем. Я представлю вам реализацию трех методов, которые удаляют данные. Два из них простых, один немного сложнее, но интереснее.
Реализация
Все три метода будут называться одинаково, но принимать различные аргументы:
1 |
public int Delete( string tablename) |
2 |
public int Delete( string tablename, string where) |
3 |
public int Delete( string tablename, string column, object [] collection) |
Первые два метода похожи. Отличие только в том, что второй принимает условие, наряду с названием таблицы. Вот часть кода, которая отвечает за выполнение запроса:
1 |
string sql = string .Format( "DELETE FROM {0} {1}" , tablename, where); |
3 |
SQLiteCommand command = new SQLiteCommand(sql, connect); |
4 |
command.ExecuteNonQuery(); |
Здесь, как мы видим все просто. Но существуют такие ситуации, когда записей, которых необходимо удалить, много. И они находятся в разных местах таблицы. Каждый раз посылать запрос на удаление одной записи нелогично, т.к. это занимает много времени. Каждый раз происходит подключение и отключение от базы, а это требует времени. Рассмотрим код, который работает нерационально, используя наш второй метод:
1 |
foreach (DataGridViewRow row in grdMain.SelectedRows) |
3 |
db.Delete( "test" , "WHERE id = " + row.Cells[0].Value; |
В цикле мы проходим по всем выделенным строкам и каждую удаляем. Если 2-3 строки, то работает незаметно, но если их хотя бы 100 и больше – появляются задержки.
Решение проблемы лежит в одном запросе, который содержит условия для всех удаляемых строк. В блоке условий WHEREперечисляем все наши условия разделяя их оператором OR. Тогда запрос выглядит следующим образом:
1 |
DELETE FROM test WHERE id = 1 OR id = 2 OR id = 100 |
Думаю, что с этим все понятно. Теперь сам метод, в котором описана методика построения строки запроса:
1 |
public int Delete( string tablename, string column, object [] collection) |
3 |
ConnectionState previousConnectionState = ConnectionState.Closed; |
4 |
using (SQLiteConnection connect = new SQLiteConnection(ConnectionString)) |
8 |
previousConnectionState = connect.State; |
9 |
if (connect.State == ConnectionState.Closed) |
13 |
#region Создаем строку условий |
15 |
string where = string .Empty; |
16 |
foreach ( object item in collection) |
20 |
where = "WHERE " + column + " = '" + item + "'" ; |
25 |
where += " OR " + column + " = '" + item + "'" ; |
30 |
string sql = string .Format( "DELETE FROM {0} {1}" , tablename, where); |
31 |
SQLiteCommand command = new SQLiteCommand(sql,connect); |
32 |
command.ExecuteNonQuery(); |
34 |
catch (Exception error) |
36 |
System.Windows.Forms.MessageBox.Show(error.Message, "Ошибка при удалении данных из таблицы " + tablename, MessageBoxButtons.OK, MessageBoxIcon.Error); |
41 |
if (previousConnectionState == ConnectionState.Closed) |
Этот метод принимает имя таблицы, имя поля, по которому идет проверка условий, и массив самих условий. В цикле foreach проходим по всем объектам и строим строку, разделяя ее оператором OR. Таким образом в сам метод можно передавать любой массив. Примеры вызова этого метода:
1 |
dbFacade db = new dbFacade(); |
2 |
db.Delete( "test" , "id" , new string [] { "1" , "2" , "100" , "200" }); |
3 |
db.Delete( "test" , "id" , new int [] {1,2,100,200}); |
4 |
ArrayList list = new ArrayList(); |
8 |
db.Delete( "test" , "id" , list.ToArray()); |
Исходя из этого мы можем передавать любой массив объектов, каждый элемент которого можно представить в виде строки. Все три метода возвращают целое число. Если операция удаления прошла успешно, возвращается 0. В остальных случаях код ошибки, который вы можете придумать сами.
Заключение
Вот и разобрали операцию DELETE. Если у вас появятся, какие-либо полезные идеи, пишите мне.
Как обычно вы можете скачать тестовый проект
Прямая ссылка на текущую версию dbFacade.