
- •Практический раздел содержание
- •Лабораторная работа №1
- •Основные понятия диаграмм классов uml
- •Классы, атрибуты, операции
- •Категории связей. Связь-зависимость
- •Связи-обобщения и механизм наследования классов в uml
- •Связи-ассоциации: роли, кратность, агрегация
- •Получение схемы реляционной базы данных из диаграммы классов uml
- •Лабораторная работа №2
- •Лабораторная работа №3
- •Лабораторная работа №4
- •Лабораторная работа №5
- •Лабораторная работа №6
- •3Апрос 6-2-1
- •3Апрос 6-2-2
- •Лабораторная работа №7
- •Лабораторная работа №8
- •Создание макроса
- •Сведения о построителе макросов
- •Создание изолированного макроса
- •Создание группы макросов
- •Создание внедренного макроса
- •Изменение макроса
- •Использование условий для контроля за действиями макроса
- •Примеры условных выражений в макросах
- •Лабораторная работа №9
- •Описание
- •Порядок обработки элементов оператора select:
- •Конструкция where
- •Конструкция group by
- •Конструкция having
- •Конструкция order by
- •Seller (Продавцы)
- •Sale (Продажи)
- •Supplier (Поставщики)
- •Goods (Товары)
- •Model (Модели)
- •Custom (Заказ)
- •Простые запросы
- •Агрегатные функции
- •Лабораторная работа №10
- •Многотабличные запросы
- •Примеры многотабличных запросов
- •Подзапросы и многотабличные запросы
- •Лабораторная работа №11
- •Операторы манипулирования данными
- •Лабораторная работа №12
- •Лабораторная работа №13
- •Примеры
- •Синтаксис
- •Примеры
- •Лабораторная работа №14
- •Лабораторная работа №15
- •Лабораторная работа №16
- •Лабораторная работа №17
- •Лабораторная работа №18
- •Лабораторная работа №19
- •Работа с данными
- •Состояния и режимы набора данных
- •Поля и класс tField
- •Типы полей и типы данных
- •Сортировка
- •Навигация
- •Фильтрация
- •Редактирование
- •Добавление и удаление
- •Лабораторная работа №20
- •Лабораторная работа №21
- •Лабораторная работа №22
- •Лабораторная работа №23
- •Компонент dbCtrlGrid
- •Лабораторная работа №24
- •Импорт информации из Delphi в Word
- •1. Как определить установлен ли Excel
- •2. Как определить запущен ли Excel
- •3. Как вывести данные в Excel
- •Лабораторная работа №25
- •Поиск и фильтрация данных в Delphi
- •Общие положения
- •Поиск данных
- •Лабораторная работа №26
- •Лабораторная работа №27
- •Отчеты в Delphi
- •Лабораторная работа №28
- •Лабораторная работа №29
- •Лабораторная работа №30
- •Лабораторная работа №31
- •Лабораторная работа №32
- •Стандартные функции php для работы с MySql
- •Пример простейшей поисковой системы на php
- •Сортировка таблиц
- •Лабораторная работа №33
- •Работа с соединениями
- •Постоянные соединения с базами данных
- •Лабораторная работа №34
- •Создание бд и таблиц
- •Создание бд и таблиц с помощью php
- •Создание бд и таблиц с использованием phpMyAdmin
- •Лабораторная работа №35
- •Лабораторная работа №36
- •Применение информации о структуре таблицы
- •Лабораторная работа №37
- •Лабораторная работа №39
- •Роль сервера приложений: Настройка сервера приложений
- •Предварительная подготовка
- •Настройка сервера приложений
- •Параметры сервера приложений
- •Сводка выбранных параметров
- •Завершение работы мастера настройки сервера
- •Удаление роли сервера приложений
- •Дальнейшие действия: выполнение дополнительных задач
- •Подготовка данных для сервера приложений
- •Создание сервера приложений
- •Лабораторная работа №40
- •Создание локального клиентского приложения (на том же пк, что и сервер)
- •Удаленный клиент с использованием olEnterprise
- •Об удаленном клиенте с использованием dcom
- •Удаленный клиент с использованием ActiveForm
Лабораторная работа №16
Тема: Работа с транзакциями в специфицирующих режимах.
Цель работы: Изучить создание и работу с транзакциями в различных режимах.
Время работы: 2 учебных часа.
Правила по ТБ: Общие.
Оборудование рабочего места: Практикум, ПК.
Программное обеспечение: Windows, MS Office, InterBase, Delphi.
Вопросы входного контроля:
Дайте определение понятию индекс.
Напишите синтаксис создания индексов.
Дайте определение понятию исключение
Напишите синтаксис создания исключения.
Дайте определение понятию триггер.
Расскажите, для чего используются триггеры.
Напишите синтаксис создания триггера.
Дайте определение понятию хранимая процедура.
Расскажите, для чего используются хранимые процедуры.
КРАТКИЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
Работа с транзакциями и их использование
Довольно часто использование механизма транзакций при работе множества пользователей с базами данных, поддерживаемыми системами управления базами данных InterBase или Firebird (да и другими серверами баз данных), вызывает немалые затруднения. Как правило, программисты используют только уровень изоляции READ COMMITTED, независимо от конкретных условий выполнения задачи.
Мы получаем немало писем с просьбой подробнее рассказать о транзакциях и использовании их характеристик при работе с компонентами FIBPlus.
Помимо документации по InterBase Language Reference, Embedded SQL Guide и API Guide, книги Helen Borrie The Firebird Book: A Reference for Database Developers (в издательстве БХВ-Петербург выходит перевод — «Firebird: справочник для разработчиков базы данных», перевод мой, научный редактор Дмитрий Кузьменко) и книги Алексея Ковязина и Сергея Вострикова «Мир InterBase», где, в принципе, содержится полное описание транзакций, существует множество статей, посвященных транзакциям. Мы решили не повторять этих описаний, а дать возможность «потрогать руками» основные характеристики транзакций и посмотреть, каким образом эти характеристики влияют на многопользовательскую работу с базой данных.
Для этого было написано несколько небольших программ, с которыми удобно проводить эксперименты. Для работы с базой данных мы, естественно, использовали компоненты FIBPlus. Результаты таких действий описываются в данной статье. Мы подробно рассмотрим компонент TpFIBTransaction — задаваемые параметры транзакции и их соответствие элементам языка SQL, используемым для описания характеристик транзакций.
Используемая база данных
Для экспериментов создадим базу данных FIBTRANSACT.FDB, поддерживаемую сервером баз данных Firebird 1.5. В базе данных создадим две таблицы: REFCOUNTRY, являющуюся справочником стран, и REFREGION, содержащую список регионов некоторых стран. Это фрагмент реально используемой базы данных. Вначале создадим домены:
CREATE DOMAIN DCodCtr AS CHAR(3); CREATE DOMAIN DName30 AS VARCHAR(30) COLLATE PXW_CYRL; CREATE DOMAIN DName60 AS VARCHAR(60) COLLATE PXW_CYRL; CREATE DOMAIN DDescr AS BLOB SUB_TYPE 1 SEGMENT SIZE 400; |
Фрагмент скрипта создания таблиц:
/*** Справочник стран REFCOUNTRY ***/
CREATE TABLE REFCOUNTRY ( Name DName30, /* Краткое название страны */ FullName DName60, /* Полное название страны */ CodCtr DCodCtr NOT NULL, /* Код страны */ Capital DName30, /* Столица */ Region DName30, /* Название региона */ Description DDescr, /* Дополнительные сведения */ CONSTRAINT "Country_PRIMARY_KEY" PRIMARY KEY (CodCtr) ); COMMIT; |
/*** Справочник регионов REFREGION ***/
CREATE TABLE REFREGION ( CodCtr DCodCtr NOT NULL, /* Код страны */ CodReg DCodCtr NOT NULL, /* Код региона */ Center DName30, /* Название центра региона */ RegName DName60, /* Название региона */ Description DDescr, /* Дополнительные сведения */ CONSTRAINT "Region_PRIMARY_KEY" PRIMARY KEY (CodCtr, CodReg), CONSTRAINT "Region_FOREIGN_KEY" FOREIGN KEY (CodCtr) REFERENCES REFCOUNTRY (CodCtr) ON DELETE CASCADE ON UPDATE CASCADE ); COMMIT; |
Заполним таблицы данными по странам и по регионам стран USA и ENGLAND.
Экспериментальная программа
Создадим в IDE Delphi или C++Builder новое приложение. Создадим на форме панель инструментов с кнопками TButton, положим два компонента TDBDrid: DBGridCountry и DBGridRegion. Добавим два компонента TDataSource: DataSourceCountry и DataSourceRegion.
С закладки FIBPlus поместим на форму следующие компоненты: Database1 типа TpFIBDatabase, Transaction1 типа TpFIBTransaction, два компонента типа TpFIBDataSet: DataSetCountry и DataSetRegion. Поместим также компонент ErrorHandler:
Рисунок 16.1 – Главная форма экспериментальной программы
Для объекта базы данных зададим необходимые значения.
Имя базы данных (свойство DBName) — FIBTRANSACT.FDB (базу данных следует поместить в тот же каталог, что и сам проект).
Зададим имя пользователя (UserName) SYSDBA,
пароль (Password) masterkey,
набор символов (CharSet) WIN1251,
установим диалект базы данных (SQLDialect) равным 3.
В качестве транзакции по умолчанию (DefaultTransaction) и транзакции для изменений выберем Transaction1:
Рисунок 16.2 – Свойства компонента базы данных
Для компонента транзакции Transaction1 установим следующие значения.
Выберем из выпадающего списка имени базы данных (DefaultDatabase) Database1.
Для уровня изоляции транзакции TPBMode из выпадающего списка выберем значение tpbDefault — только в этом случае мы сможем изменять содержимое буфера параметров транзакции (transaction parameter buffer, TPB); при выборе значения tpbReadCommitted или tpbRepeatableRead в момент запуска транзакции в буфер параметров будут помещаться соответствующие константы, и изменить эту ситуацию никакими силами нельзя.
Рисунок 16.3 – Свойства компонента транзакции
Для компонента набора данных DataSetCountry большинство свойств можно оставить в том виде, как они задаются по умолчанию. Установим следующие значения.
База данных (Database) — Database1.
Транзакция (Transaction) и транзакция для изменений (UpdateTransaction) — Transaction1.
В списке режимов (Option) для подсвойства poStartTransaction установим значение False. Это важно, поскольку мы собираемся явно управлять запуском и подтверждением (или откатом) транзакций. Подсвойство poKeepSorting установим в True. Для целей исследования поведения транзакций это особой роли не играет, однако бывает полезным для сохранения упорядоченности набора данных в случае внесения изменений в столбцы, по которым осуществляется упорядочивание набора данных (предложение ORDER BY).
В списке PrepareOptions можно (в нашем случае необязательно) установить psAskRecordCount в True. Это бывает полезным, если вам после открытия набора данных нужно в строке состояния указать количество полученных записей.
Вызовем генератор SQL (щелчок правой кнопкой мыши на компоненте и выбор в контекстном меню строки SQL Generator). В списке таблиц выберем REFCOUNTRY и дважды щелкнем мышью по этой строке. Будет сгенерирован оператор SELECT. В конец оператора добавим предложение ORDER BY NAME, чтобы упорядочить получаемый набор данных по именам стран.
Рисунок
16.4 – Генерация оператора SELECT
Перейдем на закладку Generate Modify SQLs и щелкнем мышью по кнопке Generate
SQLs. Будут сгенерированы операторы для добавления (Insert), изменения (Update), удаления (Delete) и повторного чтения текущей строки (Refresh).
Рисунок
16.5 – Генерация модифицирующих операторов
Компонент DataSourceCountry свяжем с набором данных DataSetCountry (свойство DataSet).
Аналогичные действия нужно выполнить и с компонентом DataSetRegion. Помимо этого, поскольку этот компонент является детальным (дочерним, подчиненным) набором данных в связке master-detail, нужно установить его свойство DataSource в DataSourceCountry, а в свойстве DetailConditions следует установить в True подсвойства dcForceOpen и dcWaitEndMasterScroll. При генерации оператора SELECT в генераторе SQL нужно скорректировать оператор следующим образом:
SELECT CODCTR, CODREG, CENTER, REGNAME, DESCRIPTION FROM REFREGION WHERE CODCTR = ?CODCTR ORDER BY CENTER |
Здесь предложение WHERE CODCTR = ?CODCTR задает выборку только тех строк таблицы регионов, которые относятся к текущей стране. Более подробно про связь главная-подчиненная и ее реализацию при помощи компонентов FIBPlus читайте в соответствующей статье на сайте www.devrace.com.
Далее создадим еще две формы: одна, Transaction's Characteristics, будет использоваться для формирования списка параметров транзакции TRParams, другая, Transaction's Parameters, позволит отображать содержимое буфера параметров транзакции (TPB).
Рисунок 16.6 – Форма Transaction's Characteristics
Форма Transaction's Characteristics нам понадобится для создания списка характеристик транзакции. Левому компоненту ListBox присвоим имя AllParameters, правому — SelectedParameters. Напишем следующие обработчики событий щелчка по кнопкам. При щелчке по кнопке «>» выполняется перемещение выбранных строк из левого компонента ListBox в правый:
procedure TFormTrans.Button1Click(Sender: TObject); var I: Integer; begin I := 0; while (I <= AllParameters.Items.Count - 1) do begin if AllParameters.Selected[I] then begin SelectedParameters.Items.Add(AllParameters.Items[I]); AllParameters.Items.Delete(I); I := I - 1; end; I := I + 1; end; end; |
Замечание. Здесь не приводится программный текст для C++Builder, так как в принципе очень просто осуществить «перевод» с языка Delphi на C++.
В любом компоненте ListBox можно выбрать несколько строк, удерживая нажатой клавишу Ctrl и щелкая мышью по нужным строкам.
При щелчке по кнопке «>>» выполняется перемещение всех строк из левого компонента ListBox в правый. По правде сказать, эта функция для наших целей не нужна и приводится здесь для сохранения принятого порядка.
procedure TFormTrans.Button2Click(Sender: TObject); var I: Integer; begin for I := 0 to AllParameters.Items.Count - 1 do SelectedParameters.Items.Add(AllParameters.Items[I]); AllParameters.Items.Clear; end; |
При щелчке по кнопке «<» выполняется перемещение выбранных строк из правого компонента ListBox в левый:
procedure TFormTrans.Button4Click(Sender: TObject); var I: Integer; begin I := 0; while (I <= SelectedParameters.Items.Count - 1) do begin if SelectedParameters.Selected[I] then begin AllParameters.Items.Add(SelectedParameters.Items[I]); SelectedParameters.Items.Delete(I); I := I - 1; end; I := I + 1; end; end; |
При щелчке по кнопке «<<» выполняется перемещение всех строк из правого компонента ListBox в левый:
procedure TFormTrans.Button3Click(Sender: TObject); var I: Integer; begin for I := 0 to SelectedParameters.Items.Count - 1 do AllParameters.Items.Add(SelectedParameters.Items[I]); SelectedParameters.Items.Clear; end; |
Рисунок 16.7 – Форма Transaction's Parameters
Форма Transaction's Parameters позволяет отобразить содержимое списка параметров транзакции (TRParams) и вектора буфера параметров транзакции (TPB). При вызове формы в поле Memo отображается список параметров и числовые значения из TPB.
procedure TFormTransactionParam.FormShow(Sender: TObject); var I: Integer; begin Memo1.Clear; for I := 0 to FormMain.Transaction1.TRParams.Count - 1 do Memo1.Lines.Add(FormMain.Transaction1.TRParams.Strings[I]); Memo1.Lines.Add('============================'); for I := 0 to FormMain.Transaction1.TPBLength - 1 do Memo1.Lines.Add(IntToStr(Integer(FormMain.Transaction1.TPB[I]))); end; |
Вернемся в главный модуль. Напишем обработчики событий формы. В событии формы OnShow выполним подключение к базе данных, в событии OnClose отключимся от базы данных. Соответственно, это будут операторы:
Database1.Open; |
и
Database1.Close; |
Щелчок по кнопке Open DataSet приводит к открытию набора данных DataSetCountry. При этом автоматически открывается и набор данных DataSetRegion.
procedure TFormMain.BOpenDataSetClick(Sender: TObject); begin DataSetCountry.Open; end; |
Щелчок по кнопке Close DataSet закрывает оба набора данных:
DataSetCountry.Close; |
Щелчок по кнопкам BStartTransaction и BStopTransaction приводит, соответственно, к запуску и останову транзакции:
Transaction1.StartTransaction; Transaction1.Active := False; |
Обработка события щелчка по кнопке BCommit подтверждает транзакцию. После подтверждения транзакции она запускается заново, после чего открывается набор данных (он автоматически будет закрыт при завершении транзакции — по COMMIT или ROLL BACK):
procedure TFormMain.BCommitClick(Sender: TObject); begin Transaction1.Commit; Transaction1.StartTransaction; DataSetCountry.Open; end; |
Похожим образом обрабатывается событие щелчка по кнопке BRollBack.
procedure TFormMain.BRollBackClick(Sender: TObject); begin Transaction1.Rollback; Transaction1.StartTransaction; DataSetCountry.Open; end; |
Щелчок по кнопке Characteristics приводит к обращению к форме Transaction's Characteristics для формирования пользователем списка характеристик транзакции.
procedure TFormMain.BCharactTransactClick(Sender: TObject); var I: Integer; begin if FormTrans.ShowModal <> IDOK then exit; if Transaction1.Active then Transaction1.Active := False; Transaction1.TRParams.Clear; for I := 0 to FormTrans.SelectedParameters.Items.Count - 1 do Transaction1.TRParams.Add( FormTrans.SelectedParameters.Items[I]); end; |
Щелчок по кнопке ParamTransact приводит к вызову формы Transaction's Parameters, которая отобразит текущие характеристики транзакции.
И, наконец, напишем обработчик ошибок базы данных. Это позволит нам в случае ошибок увидеть не только сообщение сервера базы данных, но и значения кодов SQLCODE и GDSCODE. Для этих целей используем событие OnFIBErrorEvent компонента ErrorHandler:
procedure TFormMain.ErrorHandler1FIBErrorEvent(Sender: TObject; ErrorValue: EFIBError; KindIBError: TKindIBError; var DoRaise: Boolean); var S: String; begin S := S + 'SQLCode = ' + IntToStr(ErrorValue.SQLCode) + #10#13; S := S + 'IBErrorCode = ' + IntToStr(ErrorValue.IBErrorCode) + #10#13; S := S + 'IBMessage = ' + ErrorValue.IBMessage + #10#13; Application.MessageBox(PAnsiChar(S), 'Database Error', MB_OK + MB_ICONSTOP); DoRaise := False; end; |
При этом в список используемых модулей программы (предложение uses) необходимо добавить fib.
Замечание. Этот обработчик ошибок только выдает сообщение и не выполняет никаких других действий. Вам нужно вручную остановить транзакцию, заново ее запустить и открыть набор данных, чтобы продолжить работу. В реальной жизни вы, конечно же, проведете в программе грамотный анализ ошибки и выполните все необходимые действия по ее нейтрализации и восстановлению работоспособности программы.
СОДЕРЖАНИЕ И ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ
Изучить теоретические сведения.
Создать поэтапно проект, как расписано в теоретическом материале.
Проверить работу всего проекта.
Продемонстрировать преподавателю работу разработанного образца проекта.
Получить от преподавателя индивидуальное задание и создать проект (по аналогии) для выполнения индивидуального задания.
Подготовиться к защите лабораторной работы, которая включает в себя демонстрацию индивидуального варианта, защиту по контрольным вопросам теоретической части работы.
Вопросы выходного контроля:
Дайте определение понятию индекс.
Напишите синтаксис создания индексов.
Дайте определение понятию триггер.
Расскажите, для чего используются триггеры.
Напишите синтаксис создания триггера.
Дайте определение понятию хранимая процедура.
Расскажите, для чего используются хранимые процедуры.
Дайте определение понятию транзакция.
Перечислите, какие бывают транзакции.