Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Плещёв ВУМИП 2012-07-06.doc
Скачиваний:
66
Добавлен:
13.05.2015
Размер:
9.35 Mб
Скачать

3.8. Основные операции с записями

Кроме средств реляционного доступа к базе (SQL), имеются более гибкие средства навигационного доступа к базе, манипулирующие отдельными записями при выполнении программы. Недостатком навигационного доступа является перегрузка сети из‑за копирования таблиц. Поэтому такой доступ лучше применять к локальным базам.

Создание таблицырассмотрим на примере.

Procedure TForm1.Button1Click(Sender: TObject); //кнопка создания

BeginWithTable1do//присоединение имени размещенной таблицыTable1

BeginActive:=False; {закрытие}Databasename:='Stroiki';{имя базы}TableName:='Goroda'; {имя таблицы}TableType:=ttParadox; {тип СУБД}

FieldDefs.Clear;IndexDefs.Clear; //удаление всех полей и индексов

//метод добавления поля Add(‘<имя>’,<тип:TFieldType>,<обязательное>)

FieldDefs.Add('Kg',ftInteger,0,True);//добавление обязательного поляKg

FieldDefs.Add('Ng',ftString,0,True); //добавление обязательного поляNg

IndexDefs.Add('','Kg',[ixPrimary,ixUnique]);//добавление первичного инд.

IndexDefs.Add('IndNg','Ng',[ixCaseInsensitive]);//добав. втор. инд.IndNg

CreateTable;{создание таблицы}IndexName:='IndNg'; {текущий индекс}

Active:=True; {открытие таблицы}end;end;

Удаление таблицыпроизводится методомDeleteTable.

Переименованиетаблицыпроизводится методомRenameTable(S).

Блокировка/разблокировка таблицыустанавливается методом:

LockTable/UnLockTable(ltReadLock|ltWriteLock).

Сортировка таблицыустанавливается текущим индексом через свойстваIndexNameилиIndexFieldName(для первичного ключа, ‘Kz;Ns’).

Перемещение по записямреализуется методами:First(первая),Last(последняя),Next(следующая),Prior(предыдущая),MoveBy(N) (пропуститьNзаписей вперед или назад, еслиN<0). При перемещении учитываются фильтры и ограничения. Установка на запись под номеромNзадается свойством таблицыRecNo:=N.

Использование закладокс адресами записей поясним на примере.

Varzakl:TBookmark//объявление переменной ‑ закладки

Begin Table1.DisabledControls;//откл. визуальных компонентов (п. 3.4.1)

zakl:=Table1.GetBookmark;//создание закладки с адресом текущей записи

IfTable1.BookmarkValid(zakl)Then//проверка наличия закладки

Begin...Table1.GotoBookmark(zakl); //переход на запись по закладке

... Table1.FreeBookmark(zakl);{удаление закладки}

Table1.EnabledControls;{подкл. визуальных компонентов (п. 3.4.1)}...End;

Фильтрация по выражениюреализуется заданием свойстваFilter. Имена полей с пробелами заключаются в квадратные скобки. Если в конце символьной константы указать символ «*», то при сравнении учитываются только первые символы (Ns=’Дом*’). Обработчик событияOnFilterRecordиспользуется, если условие не может быть задано в виде выражения. Для активизации/деактивизации фильтра используется свойствоFiltered. Дополнительные параметры фильтра задаются свойствомFilterOptions:foCaseInsensitive(регистр не учитывается),foNoPartialCompare(полное соответствие строк при сравнении и символы «*» не учитываются).

Фильтрация по диапазону значений индексных полей методомSetRange([<начало>],[<конец>]) обладает большей скоростью. Первому и второму параметру ‑ массиву присваиваются начальные и конечные значения диапазона (для строк учитываются только первые символы). Если полей индекса несколько, то границы перечисляются через запятую. СвойствоKeyExclusive=Trueисключает граничное значение диапазона.

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

procedure TForm1.Button1Click(Sender: TObject);//кнопка фильтрации

begin With Datamodule2.Stroiki do begin //присоединение имени таблицы

Open;{открыть}IndexName:='IndKz';{переход на индекс под именам IndKz}

CancelRange;{отмена фильтрации}SetRange([2],[3]);{фильтрация}End; End;

Примерфильтрации по двум полям индекса: специальности «Токарь» и зарплате:Kadri.SetRange([‘Токарь’,2000],[‘Токарь’,10000])

Поиск записей методами Locate и LookUp

Locate(S,V:Variant,P):Boolean‑ поиск первой записи и установка ее в качестве текущей. Список имен полей и их значений для искомых записей в параметрахS,V. Последний параметр задает режимы:loCaseInsensitive(регистр не учитывается),loPartialKey(частичное совпадение значений). При успешном поиске возвращаетсяTrue.

Примеры:

IfnotDatamodule2.Stroiki.locate('kz',5,[])thenShowMessage('Нет записи');

Datamodule2.Stroiki.Locate('Kz;Kp',VarArrayOf([1,4]),[]); //два поля

LookUp(S,V:Variant,S2):Variant‑ поиск первой записи и считывание значений полей, перечисленных вS2; возвращение их значения в массиве типаVariant, не перемещая указатель текущей записи. При отсутствии записи возвращается пустое значение (функцияVarIsNull() (п. 1.1.7)).

Примерпоиска по трем полям:

Var R:Variant; ... Begin ...

R:=Datamodule2.Stroiki.LookUp('Kz;Kp',VarArrayOf([1,1]),'Ns;Kz;Kp');

If not VarIsNull(R){не пустое значение (п.1.1.7)} Then Label1.Caption:=R[0];

Поиск записей по индексным полям текущего индекса

FindKey(KeyValues: array of const):Booleanточный поиск записи по значениям индексных полей (массивKeyValues).

Примерпоиска записи по индексу с полямиKz=2,Kp=1:

Procedure TForm1.Button1Click(Sender: TObject);//обработчик поиска

Begin Datamodule2.Stroiki.Active:=True; With Datamodule2.Stroiki do

Begin IndexFieldNames:='Kz;Kp'; //установка текущего индекса

If FindKey([2,1]) Then Label1.Caption:=FieldValues['Ns']; End; End;

FindNearest - приближенный поиск, аналогичный предыдущему, но при отсутствии записи делает текущей запись, ближайшую к отсутствующей.

Свойство KeyFieldCountуказывает число первых полей индекса, участвующих в поиске.

Изменение таблицы (включение, удаление и изменение записей). Возможность изменения таблицы или запроса из одной исходной таблицы задается свойствамиReadOnly=False,RequestLive=True. Для проверки возможности изменения таблицы можно использовать свойствоCanModify(True). Можно запретить изменения отдельных полей. Для изменения таблицы визуальными компонентами (DBEdit,DBGRid) нужно указать свойствоAutoEdit=Trueдля источника данныхDateSource. Для учета изменений в окнах форм следует периодически выполнять методRefresh.

Редактирование текущей записипроизводится в последо­ва­тель­ности: проверить свойствоCanModify=Trueи выполнить методEdit(IfTable1.CanModifyThenTable1.Edit); изменить значения нужных полей; подтвердить или отменить изменения методамиPostилиCancel. При переходе к другой записи подтверждение выполняется автоматически. При невозможности подтверждения генерируется исключительное состояниеOnPostError. МетодSetFields (Values:Arrayofconst) позволяет заменить значения поля элементами массиваValue. Если указать значениеNil, то соответствующее поле сохранит текущее значение. Порядок и типы элементов массива должны соответствовать порядку и типам полей записи (Table1.SetFields([Nil,’Химмаш’,Nil,1234]). После выполнения метода таблица возвращается в режим просмотра.

Добавление записейпроизводится в последо­ва­тель­ности: проверить свойствоCanModifyи выполнить один из методовInsert,InsertRecord,Append,AppendRecord; отредактировать новую добавленную текущую запись. МетодInsertдобавляет пустую запись перед текущей записью. МетодInsertRecordобъединяет методыInsertиSetFields. МетодыAppendиAppendRecordаналогичны методамInsertиInsertRecord, но вставляют запись в конец таблицы.

Физическое удаление текущей записипроизводится методомDelete, и после удаления текущей записью будет следующая запись после удаленной. При возникновении ошибки при удалении генерируется исключительная ситуацияOnDeleteError.

Работа со связанными таблицамиимеет следующие особенности.

  1. Поля связи должны быть индексированными.

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

  3. При удалении записи родительской таблицы нужно удалить все соответствующие записи в дочерних таблицах (каскадное удаление)

  4. При добавлении записи в дочернюю таблицу поля связи формируются автоматически по значению поля связи родительской таблицы.

При разработке приложения следует обеспечить организацию связи между таблицами, каскадное удаление записей и редактирование полей связи. Для организации связи в дочерней таблице используются свойства: MasterSource(источник данных родительской таблицы, например:SourceStroiki),IndexName(текущий индекс дочерней таблицы),IndexFieldNames(поле или имя связи текущего индекса дочерней таблицы,Kp),MasterFields(поле или имя связи индекса родительской таблицы,Kp).

Механизм транзакцийпозволяет перевести базу для клиент‑сер­вер­ной СУБД (п. 3.14) из одного целостного состояние в другое целостное состояние. МетодStartTransactionначинает транзакцию, и все изменения будут накапливаться в оперативной памяти без вывода их в базу. МетодCommitзавершает транзакцию, и все изменения выводятся в базу. При возникновении исключительной ситуации методомRollBackможно отменить транзакцию и сохранить исходное состояние базы на начало транзакции. До выполнения методаCommitсохраняется исходное сос­тояние базы. Указанные методы относятся к компонентуDataBase(п. 3.14).

Примерная схема использования транзакций для объекта DataBase1:

Database1.Starttransaction;//начало транзакции для базы (объектDataBase1)

Try<включение, удаление или редактирование записей>Database1.Commit

Exception Database1.Rollback;{отмена транзакции при ошибках} End.