Форум программистов, компьютерный форум, киберфорум
Наши страницы
C#: Базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.92/53: Рейтинг темы: голосов - 53, средняя оценка - 4.92
wWolf
10 / 10 / 0
Регистрация: 23.05.2009
Сообщений: 9
1

Обновление БД

11.06.2009, 18:29. Просмотров 10898. Ответов 18
Метки нет (Все метки)

Не могу разобраться как обновить данные в бд... Загрузка происходит следующим образом:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        OleDbDataAdapter adapter;
        DataSet dataSet;
        BindingSource bindingSource;
 
        private void button2_Click(object sender, EventArgs e)
        {
            string mytablename = "matr";
            string mybdpath = "C:\\db1.mdb";
            string conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+mybdpath;
            OleDbConnection connection = new OleDbConnection(conStr);
            adapter = new OleDbDataAdapter();
 
            connection.Open();
            OleDbCommand command = new OleDbCommand("SELECT * FROM "+mytablename, connection);
            connection.Close();
 
            adapter.SelectCommand = command;
            dataSet = new DataSet();
            adapter.Fill(dataSet);
            dataGridView1.DataSource = dataSet.Tables[0];
            adapter.Update(dataSet);            
        }
После внесенных изменений в dataGridView1 необходимо обновить данные:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        private void button4_Click(object sender, EventArgs e)
        {
            this.dataGridView1.EndEdit();
            if (dataSet.HasChanges())
                try
                {
                    adapter.Update(dataSet);
                    dataSet.AcceptChanges();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Неудачное обновление", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            else MessageBox.Show("Нет измененных записей!", "Изменение записей", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
В строке
C#
1
adapter.Update(dataSet);
возникает ошибка: "Для обновления требуется действительный UpdateCommand при передаче коллекции DataRow с измененными строками."
Нигде ничего вразумительного не нашел Помогите разобраться!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.06.2009, 18:29
Ответы с готовыми решениями:

Обновление связанных сущностей (каскадное обновление)
Доброго времени суток. У меня возникла проблема с обновлением сущности и связанной с ней...

Не могу установить обновление KB2670838 (Обновление платформы для Windows 7)
Не могу установить обновление KB2670838(Обновление платформы для Windows 7). Запускаю .msu файл,...

Обновление базы и ошибка: Обновление невозможно. База данных или объект доступны только для чтения.
Помогите пожалуйста! asp не может обновить базу. Про ошибку говорит Microsoft OLE DB Provider for...

Обновление свойств компонентов на обновление состояния родителя
Компонент Clock отрисовывается 500 раз. Внутри тикает таймер и когда компонент один - все ОК....

Обновление релиза и обновление Типовой конфигураци
Господа, подскажите, в чем разница между обновлением Релиза и обновлением Типовой конфигурации. Как...

18
Sagara
19 / 19 / 4
Регистрация: 30.04.2009
Сообщений: 142
11.06.2009, 20:12 2
Для обновления требуется действительный UpdateCommand
Вы же указали select-команду для выборки записей:
C#
1
adapter.SelectCommand = command;
А где для обновления?
т.е. нужно добавить UpdateCommand в adapter, как мне кажется
0
nio
5969 / 3375 / 335
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
15.06.2009, 00:52 3
необходимо прописать все команды : updatecommand, deletecommand, insertcommand
Если используется простой SELECT выбирающий данные только из одной таблицы, то сделать это можно автоматически при помощи CommandBuilder (если не ошибаюсь).
Раньше я так делал. Сейчас использую встроенные компоненты студии (DataSet, TableAdapter), так на много быстрее (все запросы создаются автоматом), если нужно реализовать что-то не сильно сложное.
0
kernel
27 / 27 / 7
Регистрация: 12.06.2009
Сообщений: 71
17.06.2009, 09:48 4
Испробовал твой код для сохранения изменений в бд, все работает. НО использовал не OleDbDataAdapter, а sqlDataAdapter, думаю большого различия нет. Еще одна небольшая коректировка: экземпляр класса DataSet создал как public
C#
1
2
public DataSet ds = new DataSet();
        private void button3_Click(object sender, EventArgs e)
0
17.06.2009, 09:48
nio
5969 / 3375 / 335
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
18.06.2009, 17:58 5
проблема в том, что ты открываешь соединение, создаешь экземпляр command и закрываешь соединение. А потом уже делаешь адаптер и датасет. Фактически методы Fill и Update обращаются к БД, а у тебя они пытаются это сделать после того как соединение закрыто. Так что переставь connection.Close() в конец метода и все должно заработать.
И еще. DataSet может содержать несколько таблиц, поэтому, кода выполняшь Fill и Update, также нужно указывать имя или номер таблицы, для которой ты это делаешь, иначе эти действия будут производится со всеми таблицами, что негативно сказывается на объемах трафика.
0
MAcK
Комбайнёр
1578 / 676 / 77
Регистрация: 27.05.2008
Сообщений: 2,535
18.06.2009, 19:11 6
Люди, пользуйтесь дизайнером для подключения и создания адаптеров, датасетов и датасоурсов (хсд схемы) или пользуйтесь LINQ и тогда у Вас не будет никаких проблем, как и что.
0
Green
1919 / 424 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
Завершенные тесты: 2
19.06.2009, 04:19 7
Цитата Сообщение от nio Посмотреть сообщение
проблема в том, что ты открываешь соединение, создаешь экземпляр command и закрываешь соединение. А потом уже делаешь адаптер и датасет. Фактически методы Fill и Update обращаются к БД, а у тебя они пытаются это сделать после того как соединение закрыто.
Адаптеру не нужно открытое подключение. Он сам откроет его если нужно, и закроет после заполнения, если оно было закрыто

Добавлено через 5 минут 5 секунд
Цитата Сообщение от nio Посмотреть сообщение
DataSet может содержать несколько таблиц, поэтому, кода выполняшь Fill и Update, также нужно указывать имя или номер таблицы, для которой ты это делаешь, иначе эти действия будут производится со всеми таблицами, что негативно сказывается на объемах трафика.
Никаких негативных объемов трафика. Если в адаптера сказано брать из таблицы Product, то он и возьмет один раз из таблицы Product. И сохранит в DataSet в таблицу с именем Product. А указание имени таблицы в DataSet необходимо, если таблица для заполнения имеет имя отличное от того, которое генерирует адаптер.
0
avers_inc
0 / 0 / 0
Регистрация: 15.06.2009
Сообщений: 15
30.06.2009, 16:44 8
а если мне нужно изменить какую-то определенную строку (определяется по ключевому полю "Id") в таблице "mytable", где мне нужно это указывать? - в запросе "Select * FROM mytable where id= " & i (где i - какая-то переменная, определяющая строку), в выражении "Update ... where id= " & i или сначала надо выбрать все записи из таблицы, а потом проверять значения каждую строки DataTable.Rows.Items("Id")?
0
Green
1919 / 424 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
Завершенные тесты: 2
01.07.2009, 03:05 9
Нужно в заполненной таблице изменить нужную строку и вызвать у адаптера Update. При этом у адаптера должен быть реализован UpdateCommand с запросом типа update (update...where...). Адаптер сам найдет измененную строку и обновит ее значение в БД на новое.
1
avers_inc
0 / 0 / 0
Регистрация: 15.06.2009
Сообщений: 15
01.07.2009, 11:42 10
Green,
т.е. насколько я понимаю, я сначала выбираю все записи из таблицы SelectCommand= ("Select * FROM mytable",connection), заполняю таблицу из датаадаптера, потом в таблице ищу нужную запись, изменяю ее, потом добавляю к датаадаптеру UpdateCommand=(Update ... where id= " & i, connection) и делаю Update. Так?
0
Green
1919 / 424 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
Завершенные тесты: 2
02.07.2009, 02:19 11
Да. Также для запросов insert и delete.
0
wWolf
10 / 10 / 0
Регистрация: 23.05.2009
Сообщений: 9
06.07.2009, 17:43  [ТС] 12
Я примерно разобрался...
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
        private void button4_Click(object sender, EventArgs e)
        {
            this.dataGridView1.EndEdit();
            if (dataSet.HasChanges())
                try
                {
                    initUID();//вот здесь происходит инициализация UPDATE,INSERT,DELETE
                    adapter.Update(dataSet);
                    dataSet.AcceptChanges();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Неудачное обновление", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            else MessageBox.Show("Нет измененных записей!", "Изменение записей", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
 
        private void initUID()
        {
            string mytablename = "matr";
            string command="";
            //UpdateCommand - ОБНОВЛЕНИЕ ДАННЫХ
            adapter1.UpdateCommand = new OleDbCommand();
            command = "UPDATE " + mytablename + " SET ";
            for (int i = 1; i < d1.ColumnCount; i++)
            {
                command += d1.Columns[i].HeaderText + "=@" + d1.Columns[i].HeaderText;
                adapter1.UpdateCommand.Parameters.Add("@" + d1.Columns[i].HeaderText, OleDbType.Integer, 10, d1.Columns[i].HeaderText);
                if (i >= d1.ColumnCount - 1) break;
                command += ",";
            }
            command += " WHERE " + d1.Columns[0].HeaderText + "=@" + d1.Columns[0].HeaderText;
            adapter1.UpdateCommand.CommandText = command;
            adapter1.UpdateCommand.Parameters.Add("@" + d1.Columns[0].HeaderText, OleDbType.Integer, 10, d1.Columns[0].HeaderText);
 
            //InsertCommand - ДОБАВЛЕНИЕ ДАННЫХ
            adapter1.InsertCommand = new OleDbCommand();           
            command = "UPDATE " + mytablename + " SET ";
            command = "INSERT INTO " + mytablename + " (";
            for (int i = 0; i < d1.ColumnCount; i++)
            {
                command += d1.Columns[i].HeaderText;
                adapter1.InsertCommand.Parameters.Add("@" + d1.Columns[i].HeaderText, OleDbType.Integer, 10, d1.Columns[i].HeaderText);
                if (i >= d1.ColumnCount - 1) break;
                command += ",";
            }
            command += ") VALUES (";
 
            for (int i = 0; i < d1.ColumnCount; i++)
            {
                command += "@" + d1.Columns[i].HeaderText;
                if (i >= d1.ColumnCount - 1) break;
                command += ",";
            }
            command += ")";
 
            adapter1.InsertCommand.CommandText = command;
 
            //DeleteCommand - УДАЛЕНИЕ ДАННЫХ
            adapter1.DeleteCommand = new OleDbCommand();
            adapter1.DeleteCommand.CommandText = "Delete from " + mytablename + " where " + d1.Columns[0].HeaderText + "=@" + d1.Columns[0].HeaderText;
            adapter1.DeleteCommand.Parameters.Add("@" + d1.Columns[0].HeaderText, OleDbType.Integer, 10, d1.Columns[0].HeaderText);
 
            adapter1.InsertCommand.Connection = adapter1.SelectCommand.Connection;
            adapter1.UpdateCommand.Connection = adapter1.SelectCommand.Connection;
            adapter1.DeleteCommand.Connection = adapter1.SelectCommand.Connection;
 
        }
но, по неизвестным мне причинам ячейка 0-й строки последнего столбца(ячейка[0,n-1]) в базе данных не обновляется
1
Green
1919 / 424 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
Завершенные тесты: 2
07.07.2009, 05:38 13
кажется здесь
Код
for (int i = 1; i < d1.ColumnCount; i++)
начинать с нуля
0
avers_inc
0 / 0 / 0
Регистрация: 15.06.2009
Сообщений: 15
09.07.2009, 23:31 14
интересный код
a что это за объект d1?
0
Green
1919 / 424 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
Завершенные тесты: 2
10.07.2009, 02:54 15
avers_inc, насколько я понял это DataGridView
0
avers_inc
0 / 0 / 0
Регистрация: 15.06.2009
Сообщений: 15
10.07.2009, 12:11 16
насколько я понимаю, то этот код может обрабатывать любую таблицу, заданную переменной mytablename... только ключевым полем в этой таблице должно быть первое поле. А как сделать так чтоб в коде определить какое из полей является ключевым? тогда можно было б совсем любую таблицу подставлять
0
Green
1919 / 424 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
Завершенные тесты: 2
13.07.2009, 03:24 17
Нет, не любую. На таком автомате получишь исключение, при попытке изменить поля только на чтение. Также при удалении строк, связанных с связями с дочерними таблицами.
Это скорее частный случай, чем универсальный выход.
0
avers_inc
0 / 0 / 0
Регистрация: 15.06.2009
Сообщений: 15
13.07.2009, 18:31 18
та да - это я уже понял...
просто очень хотелось бы сделать такую универсальную штуку, типа собственного CommandBuilder'а с открытым кодом...
но что-то пока не получается...
0
CyberIslam
12 / 7 / 3
Регистрация: 21.02.2013
Сообщений: 560
25.08.2016, 07:35 19
Народ, я сделал соединение с помощью DataSoource.. Form1_Load содержит лишь строку
C#
1
this.таблицаTableadapter.Fill(this.database11DataSet.Таблица);
Скопировал эту строку в button и вместо Fill написал Update, якобы для обновления базы. Но обновления не поступили. И ошибок никаких. Помогите разобраться
0
25.08.2016, 07:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.08.2016, 07:35

Обновление
Обновился я до 8.1, теперь постоянно шумит кулер ноутбука. В обычной восьмерке ноутбук работал...

Обновление бп на 3.0
Возникла такая проблема. Решил обновить типовую бухгалтерию релиза 2.0.54.13 на последний релиз 3.0...

Обновление ПО
Здравствуйте! Меня интересует принцип действия обновления ПО... как это вообще? Тобишь к примеру...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru