3.7 Использование транзакций и импорт базы данных из SQLфайла. Транзакция - минимальная логически осмысленная операция, которая имеет смысл и может быть совершена только полностью (или полностью отменена). Используем транзакции в нашем приложении при импорте базы данных из sql-файла. Это позволит при ошибке в какой-либо из содержащихся в нем sql-команд автоматически полностью отменить (откатить) все изменения, сделанные этим sql-скриптом ранее. 1. Добавим в панель меню главного окна приложения пункт «Файл», и в нем пункт «Импортировать базу данных...»: Name: mi_imp_db; Text: Импортировать базу данных... 2. Двойным щелчком на созданном пункте меню перейдем к редактированию кода обработчика события нажатия на этот пункт, вставим в него следующий код: String trans_code = ""; OpenFileDialog ofDialog = new OpenFileDialog(); ofDialog.Filter = "SQL-Queries files|*.sql"; ofDialog.Title = "Выберите файл, содержащий базу данных:"; if (ofDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { System.IO.StreamReader sr = new System.IO.StreamReader(ofDialog.FileName); //MessageBox.Show(sr.ReadToEnd()); trans_code = sr.ReadToEnd(); trans_code = "BEGIN TRANSACTION\n\n" + trans_code; trans_code = trans_code + "\nIF @@ERROR<>0 ROLLBACK TRANSACTION\nELSE COMMIT TRANSACTION\n"; string result = Program.data_module.execute_string_query(trans_code); if (result == "OK") { MessageBox.Show("Импорт базы данных успешно завершен!"); } else { MessageBox.Show("Ошибка при импортировании данных из файла в базу данных: " + result); } sr.Close(); } ofDialog.Dispose(); 3. Перейдем к редактированию кода модуля работы с базой данных «data_source.cs». Добавим в него функцию: public string execute_string_query(string query) { try { SqlCommand com = this._conn.CreateCommand(); com.CommandText = query; com.ExecuteNonQuery(); com.Dispose(); } catch (Exception ex) { return "ERROR" + ex.Message + " " + ex.Data; } return "OK"; } 4. Создадим тестовой файл «good_script.sql» и добавим в него следующий код: insert into ARTIST (ArtistName, Birthdate, DeceasedDate, Nationality) values ('painter1', 1807, 1900, 'Russian'); select * from ARTIST; 5. Создадим тестовый файл «bad_script.sql» и добавим в него следующий код: insert into ARTIST (ArtistName, Birthdate, DeceasedDate, Nationality) values ('painter2', 1807, 1900, 'Russian'); insert into ARTIST (ArtistName, Birthdate, DeceasedDate, Nationality) values ('painter2', 1807, 'error_year', 'Russian'); Теперь запустим приложение и, подключившись к базе данных и нажав «Файл» - «Импортировать базу данных» выберем созданный ранее файл «good_script.sql». Если все сделано правильно, до будет выдано сообщение о том что импорт базы данных завершен успешно. Снова подключившись к базе данных и открыв раздел «Художники» можно будет увидеть добавленного в процессе выполнения транзакции художника «painter1». Теперь попробуем аналогичным образом выполнить скрипт «bad_script.sql», что в результате выдаст ошибку, т.к. СУБД не сможет добавить (или провести неявное преобразование) данных типа VARCHAR к типу NUMERIC. В итоге, вновь подключившись к базе данных и открыв раздел «Художники» можно заметить, что художники «painter2» и «painter3» не были добавлены в базу данных, при том, что ошибка произошла только при добавлении художника «painter3», когда художник «painter2» был уже добавлен. Это объясняется использованием транзакций, которая в случае ошибки позволяет отменить (откатить) все изменения, сделанные после момента ее запуска.