Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие СУБД 2011.pdf
Скачиваний:
68
Добавлен:
10.06.2015
Размер:
2.75 Mб
Скачать

117

SQL.Clear;

SQL.Add('SELECT * FROM Country'); SQL.Add('WHERE Population>='+IntToStr(X)); Open;

end; end;

Пользователь вводит число жителей в строку ввода Edit1. Мы динамически обновляем условие отбора данных в момент события OnChange().

Параметры окажут неоценимую помощь в запросах, в которых ограничения на отбор данных могут меняться, или в командах модифицирующих данные в таблицах. Продолжим эксперименты с таблицей Country, хранящей данные о названии страны (поле Name) имя столицы (поле Capital) и количество жителей в стране (поле Population). Пример универсальной команды SQL, позволяющий использовать её неоднократно для вставки данных в таблицу предложен ниже:

With ADOQuery1 Do

Begin

SQL.Clear;

SQL.Add('INSERT INTO Country (Name, Capital, Population)'); SQL.Add('VALUES (:Name, :Capital, :Population)');

End;

Данная процедура вызывается только один раз, например при старте приложения. Обратите внимание на строку:

SQL.Add('VALUES (:Name, :Capital, :Population)');

Символ двоеточия признак того, что следующее за ним слово является именем параметра. Теперь, для вставки в таблицу новой записи достаточно передать в текст запроса соответствующие значения. Для хранения параметров в запрос инкапсулировано специальное свойство:

property Parameters: TParameters;

Для обращения к параметру надо указать его индекс от 0 до ParamCount-1. О количестве параметров нас информирует свойство:

property ParamCount: Word; //только для чтение

Procedure InsertTown(Name, Capital :String; Population :Cardinal);

Begin

ADOQuery1.Parameters [0].AsString := Name; ADOQuery1.Parameters [1].AsString := Capital; ADOQuery1.Parameters[2].AsInteger := Population; ADOQuery1.ExecSQL;

End;

При передаче значений параметров главное не перепутать их индекс. Если же Вы не знаете очерёдности параметров, то вместо порядкового номера параметра целесообразнее применять метод:

function ParamByName(const Value: String): TParam;

Функция возвращает параметр с именем Value:

ADOQuery1.Parameters.ParamByName('Population').AsInteger:= Population;

Хранимая процедура TADOStoredProc

В отличие от своих коллег (таблицы TADOTable и запроса TADOQuery), компонент TADOStoredProc не предназначен для прямого обращения к набору данных (таблице или

© 2011 г. Д.Л. Осипов

118

объединению таблиц). TADOStoredProc предназначен для вызова описанной на SQL сервере хранимой процедуры (stored procedure). В виду этой особенности TADOStoredProc не найдёт применения в приложениях, работающих с локальными данными (например такими как Access), так как драйверы этих баз данных не поддерживают такой вид объекта. Но, в клиентских приложениях, обслуживаемых SQL-сервером, компонент чувствует себя превосходно.

Соединение с хранимой процедурой

Для подключения TStoredProc к размещённой на сервере процедуре программист должен описать два свойства. В первую очередь в с помощью свойства Connection следует подсоединиться к компоненту TADOConnection. Затем, в свойстве:

property StoredProcName: String;

указывается имя хранимой процедуры, которую станет вызывать компонент. Кроме того, если хранимая процедура обладает параметрами, то необходимо проверить список параметров в свойстве:

property Parameters: TParameters;

Как правило, список параметров заполняется автоматически после подключения компонента к расположенной на сервере процедуре.

Выполнение хранимой процедуры

Для выполнения хранимой процедуры TADOStoredProc может воспользоваться двумя методами:

procedure Open; procedure ExecProc;

Процедура Open() используется только в тех случаях, когда хранимая процедура возвращает набор данных (процедура построена на основе команды SELECT). Во всех остальных случаях нам нужен метод ExecProc().

ADOStoredProc1.Parameters.Params[0].AsString := Edit1.Text; //передача значения

ADOStoredProc1.ExecProc;

//выполнение процедуры

Result:= ADOStoredProc1.Params[1].Value;

//получение результатов

При работе с SQL-серверами Sybase и Microsoft SQL пригодится метод: procedure GetResults;

Этот метод возвращает выходные параметры хранимой процедуры в клиентское приложение.

Транзакции и их изоляция

При разработке БД нацеленных на обслуживание более чем одного пользователя одновременно необходимо досконально разбираться в процессах выполнения транзакций и блокировок.

Стоит выделить 4-ре основные принципа транзакций:

1.Целостность. Транзакция может быть завершённой или нет. Транзакция не может быть выполнена частично.

2.Согласованность. После выполнения (или после отката) транзакции система должна находиться в некотором известном состоянии.

3.Изолированность. Транзакции должны быть автономными и не должны воздействовать на другие транзакции, а также зависеть от них.

4.Устойчивость. После завершения транзакции её цель считается достигнутой, и отменить её уже нельзя.

©2011 г. Д.Л. Осипов

119

Существуют ограничения, которые нельзя выполнить с помощью транзакций. Это операции которые нельзя отменить без существенного влияния на компоненты системы. В частности внутри транзакции нельзя использовать команды на создание (CREATE), удаление (DROP) и реконфигурацию (ALTER) объектов БД.

При построении многопользовательских БД разработчик программы должен предусмотреть поведение программного обеспечения в случае одновременного доступа к одним и тем же данным нескольких пользователей. Ведь нельзя исключить ситуацию, когда пара пользователей попытается отредактировать одну и ту же строку в таблице. Что окажется в ней после их работы? Способ защиты информации многопользовательских БД называется уровнем изоляции транзакций. В MS SQL существует 4-ре уровня изоляции:

1.Уровень Read Uncommitted. Транзакции разрешено читать данные, в настоящий момент обрабатываемые другими транзакциями. Говоря о таком процессе, часто применяют термин грязное чтение.

2.Уровень Read Committed. Транзакция может читать только завершённые изменения других транзакций.

3.Уровень Repeatable Read (повторяющееся чтение). Уровень изоляции гарантирует, что на просматриваемые пользователем данные не повлияют транзакции, выполняемые другими транзакциями. Недостаток уровня в том, что Ваша транзакция захватывает данные в монопольное пользование и не разрешает обращение к ним из других транзакциям, а это полный запрет на параллельную обработку данных.

4.Уровень Serializable. Рекомендуемый уровень изоляции. Он поддерживает все ограничения уровня Repeatable Read, но в тоже время предотвращает чтение фиктивных данных.

Управление транзакциями и компонент TADOConnection

Для запуска новой транзакции предназначена функция:

function BeginTrans: Integer;

Метод возвращает целочисленное значение, соответствующее уровню вложения транзакции. Если запуск новой транзакции осуществился без заминок, то это приведёт к установке в true свойства:

property InTransaction: Boolean;

Значение true свидетельствует о том, что TADOConnection инициировал транзакцию и эта транзакция находится в стадии выполнения. С окончанием транзакции свойство вернётся в состояние false. Сразу после успешного запуска новой транзакции происходит событие:

property OnBeginTransComplete: TBeginTransCompleteEvent; TBeginTransCompleteEvent = procedure(Connection: TADOConnection;

TransactionLevel: Integer; const Error: Error; var EventStatus: TEventStatus) of object;

Параметр EventStatus информирует нас, насколько успешно прошёл процесс запуска транзакции. Если операция выполнилась корректно, то в параметре окажется значение esOK.

Для сохранения результатов выполнения транзакции программист вызывает процедуру:

procedure CommitTrans;

Сразу после сохранения транзакции возникает событие:

property OnCommitTransComplete: TConnectErrorEvent;

TConnectErrorEvent = procedure(Connection: TADOConnection; Error: Error; var EventStatus: TEventStatus) of object;

© 2011 г. Д.Л. Осипов

120

Если в процесс выполнения транзакции вкралась ошибка, то для её отмены воспользуйтесь методом:

procedure RollbackTrans;

Откат транзакции сопровождается событием:

property OnRollbackTransComplete: TConnectErrorEvent;

Если разрабатываемая база данных подлежит эксплуатации в многопользовательском режиме, то особое внимание стоит уделить вопросам обеспечения параллельной обработки данных. Накал борьбы клиентских приложений за записи таблиц можно снизить, установив соответствующий уровень изоляции транзакций:

property IsolationLevel: TIsolationLevel;

Уровень разграничения транзакций определяет возможность одновременного совместного доступа пользователей к одним и тем же данным. В таблице 19.1 приведены допустимые значения уровней изоляции транзакций в ADO. Блокировки упорядочены по степени возрастания пессимистических настроений. Другими словами каждая последующая строка всё более и более затрудняет параллельную работу нескольких пользователей с одними и теми же данными, но зато снижает вероятность появления конфликтов.

Таблица 19.1. Возможные уровни изоляции транзакции ADO – TIsolationLevel

Уровень изоляции

Описание

 

 

ilUnspecified

Сервер может остаться в любом режиме изоляции транзакций, так как

 

приложение не предъявляет к СУБД каких либо особенных требований

ilChaos

Изменения, сделанные транзакцией с более высоким уровнем изоляции,

 

не могут быть переписаны текущей транзакцией.

ilReadUncommitted

Грязное чтение.

или

Допустимо чтение данных незавершённых транзакций.

ilBrowse

 

ilCursorStability

Исключение грязного чтения.

или

Данные доступны только после завершения транзакции.

ilReadCommitted

 

ilRepeatableRead

Повторяющееся чтение.

 

Изменения, произведённые другими транзакциями к предварительно

 

прочитанным данным не видны, пока не будет осуществлено повторное

 

чтение данных.

ilSerializable

Полная изоляция.

или

Максимальная степень изоляции транзакций.

ilIsolated

 

Задание

На основе изученных компонентов разработайте процедуры и функции позволяющие получать, добавлять, редактировать и удалять данные из таблиц вашей БД. Операции, связанные с модификацией данных должны быть заключены в транзакции.

© 2011 г. Д.Л. Осипов