В верхней части файла с исходным кодом вставьте приведенную ниже строку кода для импорта пространства имен SqlClient.
Imports System.Data.SqlClient
В теле определения класса для формы frmArchive включите код из листинга 4.10.
Листинг 4.10. Код архивирования данных в новой таблице
Private Sub frmArchive_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
lstYears.Items.Add("1995")
lstYears.Items.Add("1996")
lstYears.Items.Add("1997")
lstYears.Items.Add("1998")
lstYears.Items.Add("1999")
lstYears.Items.Add("2000")
lstYears.Items.Add("2001")
lstYears.Items.Add("2002")
' Указание значения по умолчанию.
lstYears.SelectedIndex = 0
End Sub
Private Sub btnCancel_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnCancel.Click
Me.Close()
End Sub
Private Sub btnOK_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnOK.Click
Dim sql As String
Dim result As Integer
Dim records As Integer
Dim SelectedYear As String
' Создание экземпляров объектов Connection и Command.
Dim cnn As SqlConnection = New SqlConnection( _
"server=localhost;uid=sa;database=novelty")
Dim cmd As New SqlCommand()
Dim trans As SqlTransaction
' Получение значения года.
SelectedYear = lstYears.SelectedItem.ToString
' Размещение кода внутри блока Try-Catch для
' обработки исключительных ситуаций.
Try
' Открытие объекта Connection и запуск транзакции.
cnn.Open()
trans = cnn.BeginTransaction
' Включение команды в транзакцию.
cmd.Connection = cnn
cmd.Transaction = trans
' Указание команды SQL для вставки соответствующих
' записей в архивную таблицу.
sql = "SELECT * INTO tblOrder" & SelectedYear & _
FROM tblOrder WHERE year (OrderDate) = " & SelectedYear
' Передача текста команды SQL в транзакцию.
cmd.CommandText = sql
result = cmd.ExecuteNonQuery()
' Отображение результатов вставки записей в архивную таблицу.
If result > 0 Then
records = result MessageBox.Show(records & _
" records inserted successfully into tblOrder" & SelectedYear)
Else
MessageBox.Show( _
"No records inserted into tblOrder" & SelectedYear)
' При отсутствии записей созданная таблица
' не нужна и транзакцию нужно откатить.
trans.Rollback()
End If
If records > 0 Then
' Команда SQL для удаления соответствующих
' записей из текущей таблицы.
sql = "delete FROM tblOrder WHERE year (OrderDate) = " _
& SelectedYear
' Эта команда находится в той же транзакции.
cmd.CommandText = sql
result = cmd.ExecuteNonQuery()
' Показать результаты удаления записей.
If result = records Then
MessageBox.Show(records & _
" records deleted successfully")
' Все действия успешно выполнены, можно фиксировать транзакцию.
trans.Commit()
Else
MessageBox.Show("No records deleted!")
End If
Else
' Никаких действий.
End If
Catch ex As Exception
' Какие-то действия не выполнены, поэтому нужно
' отменить (откатить) всю транзакцию.
Try
' Отображение сообщения об ошибке.
MessageBox.Show(ex.Message & _
ControlChars.CrLf & ControlChars.CrLf & _
"Transaction Failed!")
trans.Rollback()
Catch ex2 As Exception
End Try
Finally
cnn.Close()
End Try
End Sub
Подпрограмма frmArchive_Load инициализирует список lstYears значениями, из которых можно выбрать год архивирования, и выбирает используемый по умолчанию год. Конечно, эту подпрограмму можно было бы усовершенствовать так, чтобы в списке отображались только те годы, для которых существуют записи о заказах. Однако для демонстрации принципов работы транзакций достаточно и такой подпрограммы.
Подпрограмма btnCancel_Click обработки щелчков мышью на кнопке Cancel просто закрывает форму, что в данном случае приводит к закрытию программы. Все необходимые действия выполняются обработчиком щелчков мышью на кнопке OK. После объявлений переменных следует получить выбранный год из списка lstYears и сохранить его для дальнейшего использования. Для гарантированной отмены транзакции в случае возникновения любой исключительной ситуации следует окружить активный код блоком Try-Catch-Finally.
Поскольку транзакции определяются на уровне подключения, то сначала нужно открыть подключение, а затем создать объект Transaction с помощью вызова метода BeginTransaction для открытого подключения. Объекты Connection и Transaction присваиваются объекту Command, который будет использоваться для выполнения команд по отношению к базе данных.
Первые два этапа создания архивной таблицы и копирования выбранных строк выполняются с помощью одной команды SELECT, которая содержит предложение INTO имя_таблицы. Указанная таким образом таблица создается автоматически, а если такая таблица уже существует, то генерируется исключительная ситуация. Выбранное значение года добавляется к имени таблицы tblOrder для создания имени новой архивной таблицы.
Читать дальше