- •Базы данных в Delphi 7. Самоучитель
- •Наборы данных
- •Общие свойства компонентов Table и Query
- •Состояния наборов данных
- •Режимы наборов данных
- •Работа с полями наборов данных
- •Набор данных Table
- •Набор данных Query
- •Источник данных
- •Листинг 3.1. Установка и разрыв связи с наборами данных
- •Что нового мы узнали?
Режимы наборов данных
В примере использования события BeforeClose мы упомянули о режиме набора данных (свойстве State). Остановимся на этом немного подробнее. Наборы данных в разные моменты времени могут находиться в различных режимах, например неактивном, фильтрации данных, вставки, редактирования и т. д. Программист может читать значение свойства State, но изменять его напрямую нельзя. Для того чтобы перевести набор данных в один из режимов, нужно либо вызвать соответствующий метод, либо воспользоваться адекватными визуальными компонентами, речь о которых пойдет ниже.
Перечислим возможные режимы, в которых может находиться набор данных. Их всего тринадцать:
dsInactive — неактивный. В этом режиме набор данных является закрытым и доступ к данным невозможен;
dsBrowse — режим просмотра. Данный режим устанавливается по умолчанию для любого открытого набора данных. В этом режиме данные могут свободно просматриваться, но никаких изменений в них внести нельзя;
dsEdit — режим редактирования. В этом режиме возможно только редактирование текущей (активной) записи набора данных;
dsInsert — режим вставки. В данном состоянии активной является новая запись, которую можно редактировать, а затем либо принять изменения (post) либо отменить их (discard);
dsSetKey — режим поиска, который доступен только для компонентов Table и ClientDataSet. В этом режиме происходит отбор записей, которые соответствуют некоторому критерию. Можно просматривать ограниченный набор данных (соответствующих критерию), но нельзя их редактировать или вставлять новые записи;
dsCalcFields — расчет вычисляемых полей, в процессе которого невычисляемые поля таблицы не могут быть отредактированы и нельзя вставлять новые записи. Этот режим использует событие OnCalcFields;
dsFilter — режим фильтра. В этом режиме показываются только те данные, которые соответствуют фильтру, при этом невозможно редактировать или вставлять записи. Режим использует событие OnFilterRecord;
dsNewValue — режим доступа к свойству NewValue. Данный режим является временным;
dsOldValue — режим доступа к свойству OldValue. Также является временным;
dsCurValue — режим доступа к свойству CurValue. Как и предыдущие, временный режим;
dsBlockRead — режим чтения блока данных. В этом режиме при переходе на следующую запись набора данных (при вызове метода Next) все визуальные компоненты, отображающие данные, не обновляются и не происходят никакие события;
dsInternalCalc — режим внутренних вычислений. Временный режим, в нем значения полей, свойство TField.FieldKind которых установлено в fkInternalCalc, вычисляются;
dsOpening — режим открытия набора данных. Подразумевает состояние еще не завершенного открытия набора данных. Этот режим активируется, когда набор данных открывается для асинхронной выборки.
Работа с полями наборов данных
Поле набора данных представляет собой столбец таблицы. В среде Delphi предусмотрен специальный объект Field для работы с полями. Данный объект имеет тип TField. Наследниками этого объекта являются TIntegerField, TFloatField и т. д. Для того чтобы программист мог работать с отдельными полями набора данных, в Delphi определены специальные методы и свойства, которые мы и рассмотрим.
Свойство FieldCount имеет тип Integer и содержит число полей данного набора данных. Свойство доступно только для чтения. Приведем пример чтения значения свойства FieldCount:
a:=Table1.FieldCount; // a – переменная типа Integer
ВНИМАНИЕ. Количество полей набора данных может не быть равным числу полей физической таблицы базы данных, так как в набор данных могут быть не включены некоторые поля таблицы.
Свойство Fields имеет тип TFields и хранит список всех несоставных полей набора данных. Его можно представить себе в виде массива, который содержит поля набора данных, каждое под своим номером (индексом). Вы можете обращаться к конкретному полю набора данных при помощи указания его индекса (Index). Нумерация индексов начинается с нуля и заканчивается значением FieldCount-1. Если приложению известен тип данных конкретного поля, то его значение можно прочитать с помощью свойства Fields:
Edit1.Text:=Table1.Fields.Fields[1].AsString;
Кроме того, допускается запись значения в нужное поле набора данных:
Table1.Edit; // Переводим набор данных в режим редактирования
Table1.Fields.Fields[1].AsString:=Edit1.Text;
Table1.Post; // Записываем данные в таблицу
Вы, вероятно, обратили внимание на то, что при вставке в поле значения мы применили такое свойство объекта Field, как AsString. Данное свойство позволяет обращаться к содержимому поля как к строковому значению. Кроме рассмотренного свойства, имеются еще несколько: AsInteger — обращение как к целой величине, AsFloat — как к вещественной, AsVariant — как к вариантной, AsCurrency — как к денежной, AsDateTime — как к «дате-времени» и AsBoolean — обращение как к логическому (булевому) значению.
ВНИМАНИЕ. При доступе к полю набора данных нужно всегда четко представлять, какого оно типа. Так как, например, если вы обращаетесь к строковому полю с использованием свойства AsFloat, возникнет исключительная ситуация.
Обращение к полям по их номеру не всегда эффективно, поскольку номер поля — величина не постоянная. Номера полей зависят от многих факторов: от порядка полей в физической таблице базы данных, от состава полей набора данных в настоящий момент времени, от значений свойств визуальных компонентов. Поэтому доступ к полю по его номеру чреват ошибками. На практике для доступа к полям разработчики чаще всего используют методы FindField и FieldByName.
Метод FindField (const FieldName: string): TField; обнаруживает поле по его имени. Если такое поле найдено, то метод возвращает объект типа TField, то есть поле, соответствующее параметру FieldName. В случае отрицательного результата возвращается значение nil. Данный метод похож на рассматриваемый далее метод FieldByName за исключением того, что он возвращает значение nil в случае, когда поле не найдено, а метод FieldByName генерирует исключительную ситуацию.
ВНИМАНИЕ. Параметр FieldName указывает имя поля физической таблицы базы данных, которое было задано при первичном проектировании таблицы.
Метод FieldByName(const FieldName: string): TField; также ищет поле по его имени. В случае успешного поиска возвращается поле, соответствующее параметру FieldName. В противном случае генерируется исключительная ситуация EDatabaseError.
Вы можете выбрать как первый, так и второй метод для работы с полями — это дело вкуса.
Рассмотрим пример кода, в котором заменим значение поля с помощью вызова метода FindField:
Table1.Edit; // Переводим набор данных в режим редактирования
Table1.FindField(‘Number’).AsInteger:=10;
Table1.FindField(‘Name’).AsString:=’Вячеслав’;
Table1.FindField(‘Surname’).AsString:=’Понамарев’;
Table1.Post; // Записываем данные в таблицу
Мы уже немного научились использовать объект поля Field. Теперь остановимся на нем более подробно.
Как уже было сказано ранее, объект Field имеет тип TField, который является абстрактным классом. Поэтому вместо него применяются классы-наследники, перечисленные в табл. 3.2.
Таблица 3.2. Наследники класса TField
Класс-наследник |
Вид поля набора данных |
TADTField |
Поле абстрактного типа данных (Abstract Data Type) может использовать определенные типы, созданные на сервере баз данных. Может содержать массивы, ссылки и другие данные |
TAgregateField |
Составное поле. Позволяет объединять разнородные данные полей набора данных |
TArrayField |
Поле массива. Содержит набор полей одного типа |
TAutoIncField |
Поле, автоматически увеличивающее свое значение (автоинкрементное). Может служить счетчиком записей набора данных. Диапазон значений: от –2 147 483 648 до 2 147 483 647. Этот тип поля чаще всего использу- ется в качестве уникального первичного ключа |
TBCDField |
Двоично-десятичное поле (Binary-Coded Decimal). В основном требуется для хранения денежных величин. Обычно такое поле содержит деся- тичные значения. Так как Delphi ранее не поддерживала собственного типа BCD, для работы с этим полем компилятор использует денежный тип Currency, из-за чего значение этого поля ограничено 20 значащими цифрами |
TBLOBField Large OBjects) |
Данное поле содержит ссылки на большие двоичные объекты (Binary Этот тип поля является прямым предком для двух других типов полей: TGraphicField и TMemoField |
TBooleanField |
Поле логического (булевого) типа. Может иметь значения true или false |
TBytesField |
Последовательность байтов фиксированной длины |
TCurrencyField |
Поле содержит значения денежного типа (положительные или отрица- тельные) от 5,0x10-324 до 1,7x10308 с точностью до 15 знаков после запятой |
TDataSetField |
Поле обеспечивает доступ к вложенному набору данных |
TDateField |
Поле содержит дату |
TDateTimeField |
Поле содержит дату и время |
TFloatField |
Данное поле содержит вещественные значения. Они могут находиться в диапазоне от 5,0x10-324 до 1,7x10308 с точностью до 15 знаков после запятой |
TFMTBCDField |
Данные представлены в истинной двоично-десятичной форме |
TGraphicField |
Графическое поле |
TGUIdField |
Поле предназначено для работы с уникальными глобальными иденти- фикаторами (Globally Unique Identifiers, GUIDs) |
TIDispatchField |
Поле содержит указатели на интерфейсы Idispatch |
TIntegerField |
Поле для хранения целочисленных 32-битных значений со знаком. Может содержать числа в диапазоне от –2 147 483 648 до 2 147 483 647 |
TLargeIntField |
Поле большого целочисленного значения (64-битного) |
TMemoField |
Memo-поле, служит для хранения текста |
TReferenceField |
Поле содержит ссылки или указатели на другие объекты |
TSmallIntField |
Поле маленького целочисленного значения (16-битного). Допускаются числа в диапазоне от –32 768 до 32 767 |
TSQLTimeStampField |
Содержит данные о дате и времени в формате, совместимом с драйве- рами dbExpress |
TStringField |
Строковое поле. Заполняется строками простого текста длиной до 8192 символов |
TTimeField |
Поле времени |
TVarBytesField |
Поле байтов переменного размера. Значение длины содержится в первых двух байтах |
TVariantField |
Поле вариантного типа |
TWideStringField |
Поле длинных строк |
TWordField |
Поле целочисленного 16-битного значения без знака. Диапазон значений от 0 до 65 535 |
В дальнейшем мы будем применять термин TField для обозначения любого из объектов, перечисленных в табл. 3.1.
Для того чтобы проверить, какой тип имеет конкретное поле таблицы, используйте свойство DataType типа TFieldType. Оно может принимать значения, представленные в табл. 3.3.
Таблица 3.3. Значения свойства DataType
Значение |
Описание |
ftUnknown |
Неопределенный тип |
ftString |
Поле символа или строки |
ftSmallInt |
16-битное целое поле |
ftInteger |
32-битное целое поле |
ftWord |
16-битное целое поле без знака |
ftBoolean |
Логическое (булевское) поле |
ftFloat |
Поле вещественных чисел |
FtCurrency |
Поле денежных значений |
FtBCD |
Поле двоично-десятичных значений |
FtDate |
Поле даты |
FtTime |
Поле времени |
FtDateTime |
Поле даты и времени |
FtBytes |
Поле байтовых значений фиксированной длины |
FtVarBytes |
Поле байтовых значений переменной длины |
FtAutoInc |
Поле, автоматически увеличивающее свое значение |
FtBLOB |
BLOB-поле |
FtMemo |
Memo-поле |
ftGraphic |
Графическое поле |
ftFmtMemo |
Memo-поле, содержащее форматированный текст |
ftParadoxOLE |
Поле OLE для таблиц Paradox |
ftDBaseOLE |
Поле OLE для таблиц dBase |
ftTypedBinary |
Двоичное поле |
ftCursor |
Курсор хранимой процедуры Oracle |
ftFixedChar |
Символьное поле фиксированной длины |
ftWideString |
Поле длинной строки |
ftLargeInt |
Поле большого целого числа |
ftADT |
Поле данных абстрактного типа |
ftArray |
Поле массива |
ftReference |
Поле, содержащее ссылки и указатели на объекты |
ftDataSet |
Поле типа TDataSet |
ftOraBLOB |
BLOB-поле в таблице Oracle 8 |
ftOraCLOB |
CLOB-поле в таблице Oracle 8 |
ftVariant |
Данные неизвестного или неопределенного типа |
ftInterface |
Поле ссылок на интерфейсы (IUnknown) |
ftIDispatch |
Поле ссылок на интерфейсы (IDispatch) |
ftGUID |
Поле GUID |
ftTimeStamp |
Поле даты и времени, доступное с помощью средств dbExpress |
ftFMTBCD |
Поле двоично-десятичного значения, являющегося слишком большим для ftBCD |
Теперь мы можем перейти к рассмотрению особенностей наборов данных Table и Query.
