Компоненты для работы с БД TTable и TQuery

–PAGE_BREAK–Связь этих компонентов друг с другом и с базой данных можно представить схемой приведенной ниже:
 
 

Схема взаимодействия компонентов Delphi с базой данных

3. Наборы данных

Под набором данных (НД) понимается группа записей из одной или нескольких таблиц БД, доступная для компонентов-наборов TTable, TQueryили TStoredProc. Эти компоненты порождены от общего родительского класса TDBDataSetи наследуют все его свойства, методы и события.

Класс TDataSet

         TDataSet класс — один из наиболее важных объектов БД. Чтобы         начать работать с ним, нужно взглянуть на следующую иерархию:
TDataSet

       |

   TDBDataSet

       |

       |– TTable

       |– TQuery  

       |– TStoredProc
TDataSet содержит абстрактные методы там, где должно быть непосредственное управление данными. TDBDataSet знает, как обращаться с паролями и то, что нужно сделать, чтобы подключиться к определенной таблице. TTable знает (т.е. уже все абстрактные методы переписаны), как обращаться с таблицей, ее индексами и т.д.

    TDataSet — инструмент, который используется например для открытия таблицы, и перемещения по ней. Конечно, не нужно непосредственно создавать объект типа TDataSet. Вместо этого, нужно использовать TTable, TQuery или других потомков TDataSet (например, TQBE). На наиболее фундаментальном уровне, Dataset это просто набор записей, как изображено на рис.1

Рис.1: Любой dataset состоит из ряда записей (каждая содержит N полей) и указатель на текущую запись.
В большинстве случаев DataSet будет иметь прямое, один к одному, соответствие с физической таблицей, которая существует на диске. Однако, в других случаях можно исполнять запрос или другое действие, возвращающие dataset, который содержит либо любое подмножество записей одной таблицы, либо объединение (join) между несколькими таблицами.
3.1 Основные приемы работы с
TDataSet

Открытие и закрытие DataSet

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

Table1.Open;

Или  можно установить свойство Active равное True:

Table1.Active := True;

Нет никакого различия между результатом производимым этими двумя операциями. Метод Open, однако, сам заканчивается установкой свойства Active в True, так что может быть даже чуть более эффективно использовать свойство Active напрямую.

Также, как имеются два способа открыть a таблицу, так и есть два способа закрыть ее. Самый простой способ просто вызывать Close:

Table1.Close;

Или можно написать:  Table1.Active := False;
Навигация (Перемещение по записям)

Большой набор методов и свойства TDataSet обеспечивает все, что нужно для доступа к любой конкретной записи внутри таблицы:

Обзор их функциональных возможностей описан ниже в таблице методов класса TDadaSet.

TDataSet.BOF — read-only Boolean свойство, используется для проверки, находится ли курсор в начале таблицы. Свойства BOF возвращает true в трех случаях:

·        После того, как файл был открыт;

·        После того, как вызвался метод TDataSet.First;

·        После того, как не выполнился вызов метода TDataSet.Prior.

Первые два пункта — очевидны. Когда открывается таблица, Delphi помещает курсор на первую запись; когда вызывается метод First, Delphi также перемещает курсор в начало таблицы. Третий пункт, однако, требует небольшого пояснения: после того, как вызывался метод Prior несколько раз, курсор мог добраться до начала таблицы, и следующий вызов Prior будет неудачным — после  этого BOF и будет возвращать True.

Следующий код показывает самый общий пример использования Prior, когда курсор попадает к первой записи:

while not Table.Bof do

  Table1.Prior;

end;

Цикл будет продолжаться до тех пор, пока вызов Table1.Prior не сможет больше перемещать курсор на предыдущую запись в таблице. В этот момент BOF вернет True и программа выйдет из цикла.

    Все сказанное относительно BOF также  применимо и к EOF. Другими словами, код, приведенный ниже показывает простой способ пробежать по всем записям в a dataset:

Table1.First;

while not Table1.EOF do

  Table1.Next;

end;

EOF возвращает True в следующих трех случаях:

·        После того, как файл был открыт;;

·        После того, как вызвался метод TDataSet.Last;

·        После того, как не выполнился вызов метода TDataSet.Next

Единственная навигационная процедура, которая еще не упоминалась — MoveBy, которая позволяет переместиться на N записей  вперед или назад в таблице. Если необходимо переместиться на две записи вперед, то следует написать следующий оператор:

MoveBy(2);

или

MoveBy(-2);

Prior и Next — это простые функции, которые вызывают MoveBy.

При использовании этой функции необходимо всегда помнить, что DataSet — это изменяющиеся объекты, и запись, которая была пятой по счету в предыдущий момент, теперь может быть четвертой или шестой или вообще может быть удалена…                                                           

Поля

В большинстве случаев, когда нужно получить доступ из программы к индивидуальные полям записи, можно использовать одно из следующих свойств или методов, каждый из которых принадлежат TDataSet:
property Fields[Index: Integer];

function FieldByName(const FieldName: string): TField;

property FieldCount;
Свойство FieldCount возвращает число полей в текущей структуре записи. Если необходимо программным путем прочитать имена полей, то используется свойство Fields для доступа к ним:
var

  S: String;

begin

  S := Fields[0].FieldName;

end;

Короче говоря, индекс передаваемый в Fields (начинающийся с нуля), и определяет номер поля к которому Вы получите доступ, т.е. первое поле — ноль, второе один, и так далее.

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

  S := Fields[0].AsString;

Предположим, что первое поле в записи содержит номер заказчика, тогда код, показанный выше, возвратил бы строку типа “1021”, “1031” или “2058”. Если нужно получить доступ к этот переменный, как к числовой величине, тогда надо использовать AsInteger вместо AsString. Аналогично, свойство Fields включают AsBoolean, AsFloat и AsDate.

Можно использовать функцию FieldsByName вместо свойства Fields:

  S := FieldsByName(‘CustNo’).AsString;

Как показано в примерах выше, и FieldsByName, и Fields возвращают те же самые данные. Два различных синтаксиса используются исключительно для того, чтобы обеспечить программистов гибким и удобным набором инструментов для программного доступа к содержимому DataSet.

Свойство Fields позволяет выбрать тип результата Вот список доступных методов который можно найти в описании класса TField:

property AsBoolean

property AsFloat

property AsInteger

property AsString

property AsDateTime   

Всякий раз (когда это имеет смысл), Delphi сможет сделать преобразования. Например, Delphi может преобразовывать поле Boolean к Integer или Float, или поле Integer к String. Но не будет преобразовывать String к Integer, хотя и может преобразовывать Float к Integer.

    продолжение
–PAGE_BREAK–Основные свойства, методы и события НД Свойства

Свойство Описание
property  Active: Boolean;

Открывает/закрывает НД
property AutoCalcFields: Boolean;
Разрешает/запрещает возникновение события OnCalcFields
Type TBookmarksStr: String;
property BookMark: TBookMarkStr;

Определяет закладку на текущей записи. К помеченной записи можно быстро перейти методом GotoBookMark
property CanModify: Boolean;
Указывает, может ли пользователь изменять НД  
property Database: TDatabase;
Определяет компонент TDatabase, связанный с данным НД
property DatabaseName: String;
Содержи псевдоним базы данных
property DataSource: TDataSource;
Используется в потомках для указания детального НД, в связи один ко многим
property EOF: Boolean;
Содержит True, если курсор НД сместился за последнюю запись 
property FieldCount: Integer;
Содержит количество полей в НД
property Fields: TFields;
Позволяет обратиться к полям по их индексу. Первое поле НД имеет индекс 0
property FieldValues[const FieldName: String]: Variant;
Позволяет обратиться к значениям полей по имени поля
property Filter: String;
Задает фильтрующее выражение
property Filtered: Boolean;
Разрешает/запрещает фильтрацию записей НД
type TFilterOption = (foCaseInsensitive, foNoPartialCompare); TFilterOptions = set of TFilterOption;
Определяет условия фильтрации в текстовых полях: foCaseInsensitive –учитывать регистр букв; foNoPartialCompare – поиск на точное соответствие образцу
property Modifed: Boolean;
Содержит True, если текущая запись НД была изменена
property RecNo: LongInt;
Определяет номер текущей записи
property RecordCount: LongInt;
Содержит количество записей в текущем НД
type TDataSetState = (dsInactive, dsBrowse, dsEdit, dsInsert, dsSetKey, dsCalcFields, dsFilter, dsNewValue, dsOldValue, dsCurValue, dsBlockRead, dsInternalCalc)
property State: TDataSetState;
УказываетсостояниеНД: dsInactive-закрыт, dsBrowse-просмотр, dsEdit-редактирование, dsInsert-вставка, dsSetKey-поискзаписи, dsCalcFields-установкавычисляемыхполей, dsFilter-фильтрациязаписей, dsNewValue-обновление, dsOldValue-обновление, dsCurValue-обновление, dsBlockRead-чтениеблоказаписей, dsInternalCalc-обновление

Методы:

procedure Append;

Добавляет пустую запись в конец НД

procedure AppendRecord(const Values: Array of const);

Добавляет новую запись, заполняет ее поля значениями Values и отсылает ее в БД

procedure ApplyUpdates;

Записывает кэш обновления в таблицы БД

procedureCancel;

Отменяет все изменения текущей записи, которые не были сохранены в БД

procedure CancelUpdates;

Очищаеткэшобновления

procedureCheckBrowseMode;

Если НД находился в состоянии редактирования или вставки, вызывает метод Post для записи изменений в БД

procedureClearFields;

Очищает все поля текущей записи

procedure Close;

ЗакрываетНД

procedure CloseDatabase(Database:TDatabase);

Закрывает базу данных Database

procedureCommitUpdates;

Очищает кэш после успешного обновления данных в БД

function ControlsDisabled: Boolean;

Возвращает True, если показ данных в визуальных компонентах временно запрещен методом DisableControls

procedureDelete;

Удаляет текущую запись

functionDisableControls;

В целях улучшения производительности при навигации по НД временно запрещает смену данных в визуальных компонентах

procedureEdit;

Редактирует текущую запись

procedure EnableCointrols;

ОтменяетдействиеметодаDisableControls

function FieldByName(const FieldName: String):TField;

Обеспечивает доступ к полю по его имени FieldName

function FindField(const FieldName: String):TField;

Ищет поле FieldName в НД и возвращает ссылку на поле или NIL, если поле не найдено

function FindFirst: Boolean;

Пытается установить курсор на первую запись НД и возвращает True в случае успеха

function FindLast: Boolean;

Пытается установить курсор на последнюю запись НД и возвращает True в случае успеха

function FindNext: Boolean;

Пытается установить курсор на следующую запись НД и возвращает True в случае успеха

function FindPrior: Boolean;

Пытается установить курсор на предыдущую запись НД и возвращает True в случае успеха

function First: Boolean;

Устанавливает курсор на первую запись в НД

procedure FreeBookMark(BookMark: TBookMark); virtual;

Освобождает память связанную с закладкой BookMark

function GetBookMark: TBookMark; virtual;

Создает закладку на текущей записи и возвращает указатель на нее

procedure GotoBookMark(BookMark: TBookMark);

Обеспечивает возврат к записи, связанной с закладкой BookMark

procedureInsert;

Переводит НД в режим вставки записей

procedure InsertRecord(const Values: array of const);

Создает пустую запись, наполняет ее поля значениями Values и вставляет ее в НД

function isEmpty: Boolean;

Возвращает True, если в НД нет записей

procedureLast;

Устанавливает курсор на последнюю запись

function Locate(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean;

Ищет в полях перечисленных в параметре KeyFields, значения, указанные в KeyValues при условиях, заданных параметром Options. Если запись найдена, делает ее текущей и возвращает True 

function LookUp(const KeyFields: String; const KeyValues: Variant; const ResultFields: String): Variant;

Используется в детальных НД для поиска в полях KeyFields значений KeyValues. При успехе возвращает значение полей ResultFields

function MoveBy(Distance: Integer):Integer;

Перемещает курсор на Distance записей вверх или вниз относительно текущей записи

procedureNext;

Перемещает курсор к следующей записи

procedure Open;

ОткрываетНД

procedure Post; virtual;

Сохраняет вставленную или отредактированную запись в таблице БД

procedurePrior;

Перемещает курсор к предыдущей записи

procedureRefresh;

Обновляет НД данными из БД

procedure SetFields (const Values: array of const);

Устанавливает значения Values во все поля текущей записи

 

События:

type TDataSetNotifyEvent = procedure (DataSet: TDataSet) of object

property AfterCancel: TDataSetNotifyEvent;

Возникает сразу после отмены изменений в текущей записи

property AfterClose: TDataSetNotifyEvent;

Возникает сразу после закрытия НД

property AfterDelete: TDataSetNotifyEvent;

Возникает сразу после удаления текущей записи

property AfterEdit: TDataSetNotifyEvent;

Возникает сразу после перехода НД в режим редактирования

property AfterInsert: TDataSetNotifyEvent;

Возникает сразу после вставки записи

property AfterOpen: TDataSetNotifyEvent;

Возникает сразу после  открытия НД

property AfterPost: TDataSetNotifyEvent;

Возникает сразу после выполнения метода Post

property AfterScroll: TDataSetNotifyEvent;

Возникает сразу после перехода к другой записи

property BeforeCancel: TDataSetNotifyEvent;   

propertyBeforeClose: TDataSetNotifyEvent;

Возникает непосредственно перед отменой

изменений в текущей записи

Возникает непосредственно перед закрытием НД

property BeforeDelete: TDataSetNotifyEvent;

Возникает непосредственно перед удалением текущей записи

property BeforeEdit: TDataSetNotifyEvent;

Возникает непосредственно перед переходом НД в режим редактирования

property BeforeInsert: TDataSetNotifyEvent;

Возникает непосредственно перед в режим вставки

property BeforeOpen: TDataSetNotifyEvent;

Возникает непосредственно перед открытием НД

property BeforePost: TDataSetNotifyEvent;

Возникает непосредственно перед выполнением метода Post

property BeforeScroll: TDataSetNotifyEvent;

Возникает непосредственно перед к новой записи

property OnCalcFields: TDataSetNotifyEvent;

Возникает при необходимости переопределения вычисляемых полей

 

    продолжение
–PAGE_BREAK–