Информационные технологииStfw.Ru 🔍

Средства Delphi 7 для доступа к данным

🕛 04.03.2008, 15:47
Рассмотрим наборы компонентов, которые присутствуют в библиотеке компонентов delphi 7, предназначенных для работы с базами данных. Вы узнаете, что такое набор данных, источник данных и познакомитесь с другими понятиями, связанными с базами данных.

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

Новые возможности delphi 7 по работе с базами данных

Каждая из версий delphi приносит какие-либо новшества в работу с базами данных. Так, в delphi 5 ярким примером такой новации может являться поддержка технологии ado. В delphi 6 также были включены многие новые возможности, в том числе и для работы с базами данных. А именно:

в delphi 6 добавлен принципиально новый механизм доступа к данным, называющийся dbexpress. Он обеспечивает исключительно быстрый и простой доступ к серверам баз данных;
наборы данных в delphi 6 стали поддерживать два новых типа полей: tfmtbcdfield и tsqltimestampfield;
добавлено несколько новых компонентов для упрощения работы с клиентскими наборами данных, а также с двухъярусными и многоярусными приложениями баз данных.
Рассмотрим перечисленные выше особенности delphi 6 более подробно.

dbexpress представляет собой совокупность небольших по размеру драйверов, которые обеспечивают быстрый доступ к серверам баз данных, поддерживающих язык sql. Список допустимых типов баз данных вы можете найти в табл. 3.1. Для каждой из баз данных dbexpress предоставляет определенный драйвер. Таким образом, если вы планируете распространять свое приложение, то в него нужно будет включить дополнительный файл драйвера, который представляет собой обычную библиотеку динамической компоновки (dll).

Разберемся, какой из файлов библиотек вы должны будете включить в комплект поставки вашей программы. В таблице 3.1 перечислены типы баз данных и библиотеки динамической компоновки, необходимые для работы с ними.

Таблица 3.1. Типы поддерживаемых баз данных

Тип базы данных Имя файла
interbase dbexpint.dll
db2 dbexpdb2.dll
oracle dbexpora.dll
mysql dbexpmys.dll


Новый тип поля tfmtbcdfield обеспечивает истинный двоично-десятичный формат поля. Напомним, что в delphi 5 использовался тип tbcdfield, который хранил двоично-десятичные данные в формате currency. Данный тип переводил данные формата currency в bcd (binary-coded decimal) и наоборот.

ПРИМЕЧАНИЕ. Для поддержки нового типа поля процедуры currtobcd и bcdtocurr были перемещены из модуля db в модуль fmtbcd.

Другой новый тип поля tsqltimestampfield предназначен для поддержки времени и даты в формате, требуемом драйверам dbexpress.

Были добавлены три новых клиентских набора данных:

tbdeclientdataset;
tsqlclientdataset;
tibclientdataset.
Эти компоненты предназначены для простых приложений и объединяют в себе поставщик данных и набор данных. Если создаваемое приложение требует многократного обновления данных с сервера или использует отношение «главный-подчиненный» между таблицами, то лучше всего использовать вместо указанных клиентских наборов данных внешний поставщик данных и отдельный клиентский набор данных.

Компонент tclientdataset в delphi 6 обладает тремя новыми свойствами:

connectionbroker - применяется в случае, когда у вас в приложении имеется несколько наборов данных, которые задействуют одно и то же соединение с сервером базы данных. Данное свойство позволяет централизованно, с помощью изменения только одного значения, изменять значения свойства у всех наборов данных, использующих данное соединение;
disablestringtrim - позволяет контролировать ввод символов пробела в значениях, которые заносят пользователи в поля таблиц. Данное свойство имеет булевый тип. Если значение свойства - true, то данные сохраняются в поле таблицы в том виде, как их вводит пользователь, в ином случае все пробелы, вводимые пользователем, будут отсечены;
xmldata - позволяет получить доступ из клиентского набора данных к xml-данным.
Новый набор компонентов позволяет вам работать с xml-документами. Мы их рассмотрим в последующем.

Кроме того, в delphi 6 была реорганизована палитра компонентов. Компоненты, которые основаны на bde (borland database engine, процессор баз данных borland), перемещены на отдельную закладку bde. Добавлены новые закладки: interbase admin, dbexpress и datasnap. Об этих закладках и их компонентах читайте далее в этой главе.

Среда delphi 7 также привнесла изменения в работу с базами данных:

Драйверы dbexpress теперь стали поддерживать in formix se, oracle 9i, db2 7.2, interbase 6.5 и mysql 3.23.49. Кроме того, был добавлен новый драйвер для microsoft sql 2000.
Корпорация borland решила отказаться от использования sql links. Начиная с 2002 года sql links не будет развиваться и включаться в состав delphi. Для реализации доступа к серверам баз данных sql корпорация borland рекомендует использовать механизм dbexpress.
Файл borland database engine (bdeinst.cab) больше не имеет цифровую подпись. Этот файл включается в поставку delphi лишь для обеспечения совместимости программ, созданных в ранних версиях delphi.
Произошли изменения в некоторых компонентах для работы с базами данных и были добавлены новые:
в свойстве defaultrowsetsize компонента tsqldataset (вкладка dbexpress) теперь установлено значение по умолчанию, равное 20;
вместо компонента tsqlclientdataset введен новый компонент tsimpledataset, находящийся на вкладке dbexpress палитры компонентов.
Наборы данных

Среда delphi работает с таблицами баз данных, которые физически располагаются на диске. Поэтому такие таблицы мы будем называть физическими. Для доступа к данным, содержащимся в физических таблицах, применяются наборы данных.

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

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

Итак, из всего вышесказанного можно сделать вывод, что нам при создании приложений баз данных придется работать в основном с наборами данных (или логическими таблицами).

ВНИМАНИЕ. Во многих других системах управления базами данных вместо термина набор данных используются выборка или таблица.

Среда delphi имеет несколько стандартных компонентов для работы с наборами данных. К их числу относятся такие компоненты, как table, query, storedproc и другие. Работа со всеми этими компонентами будет подробно описана далее.

Доступ к данным в delphi обеспечивает класс tdataset, который представляет наборы данных в виде совокупности строк и столбцов. Строки являются записями, а столбцы - полями таблицы базы данных. Класс tdataset обеспечивает возможность редактирования набора данных, а также предоставляет средства для перемещения (навигации) по записям. Многие из свойств, событий и методов класса tdataset являются абстрактными. Они называются абстрактными, так как не могут быть использованы непосредственно классом tdataset, а лишь в его классах-потомках.

Прямым потомком класса tdataset является класс tbdedataset. Этот класс инкапсулирует в себе функциональные возможности borland database engine (bde) - процессора баз данных фирмы borland. bde - это совокупность файлов динамических библиотек (dll) и драйверов, которые отвечают за доступ к данным. Для более подробного знакомства с bde обратитесь к занятию 4.

Класс tbdedataset имеет класс-потомок tdbdataset, в котором определены дополнительные свойства и методы, обеспечивающие возможность связывания набора данных с физическими таблицами базы данных.

Далее мы рассмотрим два компонента table и query, которые являются потомками класса tdbdataset. Мы изучим их общие свойства на примерах операций с наборами данных. Эти компоненты расположены на закладке bde палитры компонентов delphi 7.

Общие свойства компонентов table и query

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

table1.active:=false; // Закрывает набор данных, задаваемых
// компонентом table1
query1.active:=true; // Открывает набор данных, задаваемых
// компонентом query1

Более подробно о свойстве active рассказывается ниже.

Свойство databasename имеет тип string и задает полный путь к каталогу базы данных, например: ‘c:\database\mydbf’. В значении этого свойства можно указать вместо пути к каталогу базы данных ее псевдоним.

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

Более подробно о работе с псевдонимами мы расскажем на четвертом занятии.

Все существующие псевдонимы для баз данных будут показаны в окне инспектора объектов при щелчке левой кнопкой мыши на поле со списком напротив свойства databasename.

СОВЕТ. Старайтесь всегда использовать псевдонимы, так как это позволит вам легко изменять местоположение файлов базы данных, не меняя кода программы. После изменения местоположения файлов достаточно будет изменить название каталога, на который ссылается псевдоним базы данных.

Для компонента table допустимо применение только свойства databasename при задании пути к базе данных. Компонент query имеет дополнительную возможность: в запросе sql можно задать путь доступа к любой из таблиц базы данных.

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

во-первых, необходимо установить свойство active компонента table или query в false (закрыть набор данных);
затем указываем путь к базе данных либо ее псевдоним;
после чего можно открыть набор данных, присвоив свойству active значение true:
table1.active:=false; // Закрываем набор данных
query1.active:=false; // Закрываем набор данных
table1.databasename:=’mydb’; // Задаем местонахождение базы
// данных с помощью псевдонима
query1.databasename:=’c:\database\mydbf’;

Свойство tablename компонента table имеет тип string и содержит имя текущей таблицы базы данных. В терминах delphi каталог - это база данных, а файлы каталога - таблицы. Поэтому после указания пути к базе данных через свойство databasename можно выбрать нужную таблицу из раскрывающегося списка свойства tablename в окне инспектора объектов (там будут отображены все названия файлов таблиц, находящихся в выбранном каталоге). Кроме того, значение этого свойства можно задавать и во время работы приложения, предварительно закрыв набор данных:

table1.active:=false;
table1.databasename:=’c:\database\mydbf’;
table1.tablename:=’mytable’;

Свойство recordcount имеет тип longint и содержит число записей, находящихся в текущий момент времени в наборе данных. Значение данного свойства не отображается в окне инспектора объектов - оно доступно только для чтения во время выполнения приложения.

Строка

edit1.text:=inttostr(table1.recordcount);

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

Свойство recno имеет тип longint и содержит номер текущей записи набора данных. Это свойство также доступно только для чтения во время работы приложения. Для перемещения по записям набора данных используются вызовы соответствующих методов: first, last, next, prior и moveby:

table1.first; // Переход к первой записи набора данных
table1.next; // Переход к следующей записи
table1.last; // Переход на последнюю запись
// набора данных
table1.prior; // Переход на предыдущую запись
table1.moveby (-12); // Переход на 12 записей назад от
// текущей

Если вы используете в своем приложении таблицы paradox, то можно напрямую производить ввод чисел в свойство recno для перехода на нужную запись набора данных:

table1.recno:=15; // Переход на 15-ю запись набора данных

Состояния наборов данных

Как мы уже видели ранее, наборы данных могут принимать два состояния: открытое или закрытое. При установке свойства active в true набор данных будет открыт. Для закрытия набора данных нужно присвоить свойству active значение false.

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

ВНИМАНИЕ. При изменении свойств databasename или tablename необходимо обязательно закрыть набор данных, чтобы избежать исключительной ситуации.

Кроме того, вы можете открыть набор данных с помощью вызова метода open и закрыть с помощью метода close:

table1.close; // Закрываем набор данных
query1.open; // Открываем набор данных

Вызов этих методов имеет смысл, если вы хотите выполнить какие-либо действия перед открытием или после открытия набора данных, а также перед закрытием или после закрытия.

Итак, метод open открывает набор данных. При вызове данного метода генерируются события beforeopen и afteropen. Вы можете написать программы-обработчики этих событий. Это очень полезно, если вы хотите не открывать набор данных до тех пор, пока не выполнились какие-либо условия. Ниже представлен пример такого обработчика:

procedure t form1.table1beforeopen(dataset: tdataset);
begin
if a<>true then abort;
end;

В данном примере, если переменная a не имеет значение true, открытие набора данных table1 будет прервано. Это достигается вызовом процедуры abort, в результате работы которой генерируется исключительная ситуация и операция открытия данных отменяется. При этом на экран не будет выведено никаких сведений об ошибках. Естественно, вы можете добавить команды вывода сведений для пользователя о том, что данные недоступны.

Примером использования события afteropen может служить приведенный ниже листинг:

procedure t form1.table1afteropen(dataset: tdataset);
begin
showmessage(“Таблица “+table1.tablename+” готова к работе’);
end;

Здесь после открытия набора данных выводится текстовое сообщение о готовности таблицы к работе. Имя таблицы содержится в свойстве tablename.

Метод close закрывает набор данных. При его вызове генерируются события beforeclose и afterclose.

ВНИМАНИЕ. При закрытии набора данных необходимо принудительно сохранять сделанные изменения в текущей записи с помощью вызова метода post, так как метод close автоматически не сохраняет данные текущей записи.

Можно использовать обработчик события beforeclose для вызова метода post:

procedure t form1.table1beforeclose(dataset: tdataset);
begin
if (table1.state=dsinsert) or (table1.state=dsedit) then
table1.post;
end;

В данном примере сначала осуществляется проверка, в каком режиме находится набор данных table1, при помощи значения свойства state. Если он находится в режиме вставки новой записи (dsinsert) или редактирования текущей записи (dsedit), то перед закрытием набора данных все внесенные изменения сохраняются.

ВНИМАНИЕ. При выходе из приложения несохраненные данные теряются, и обработчик события beforeclose не вызывается.

К обработке события afterclose можно прибегать для выдачи пользователю сообщения о закрытии набора данных.

Режимы наборов данных

В примере использования события beforeclose мы упомянули о режиме набора данных (свойстве state). Остановимся на этом немного подробнее. Наборы данных в разные моменты времени могут находиться в различных режимах, например неактивном, фильтрации данных, вставки, редактирования и т. д. Программист может читать значение свойства state, но изменять его напрямую нельзя. Для того чтобы перевести набор данных в один из режимов, нужно либо вызвать соответствующий метод, либо воспользоваться адекватными визуальными компонентами, речь о которых пойдет ниже.

Перечислим возможные режимы, в которых может находиться набор данных. Их всего тринадцать:

dsinactive - неактивный. В этом режиме набор данных является закрытым и доступ к данным невозможен;
dsbrowse - режим просмотра. Данный режим устанавливается по умолчанию для любого открытого набора данных. В этом режиме данные могут свободно просматриваться, но никаких изменений в них внести нельзя;
dsedit - режим редактирования. В этом режиме возможно только редактирование текущей (активной) записи набора данных;
dsinsert - режим вставки. В данном состоянии активной является новая запись, которую можно редактировать, а затем либо принять изменения (post) либо отменить их (discard);
dssetkey - режим поиска, который доступен только для компонентов table и clientdataset. В этом режиме происходит отбор записей, которые соответствуют некоторому критерию. Можно просматривать ограниченный набор данных (соответствующих критерию), но нельзя их редактировать или вставлять новые записи;
dscalcfields - расчет вычисляемых полей, в процессе которого невычисляемые поля таблицы не могут быть отредактированы и нельзя вставлять новые записи. Этот режим использует событие oncalcfields;
dsfilter - режим фильтра. В этом режиме показываются только те данные, которые соответствуют фильтру, при этом невозможно редактировать или вставлять записи. Режим использует событие onfilterrecord;
dsnew value - режим доступа к свойству new value. Данный режим является временным;
dsold value - режим доступа к свойству old value. Также является временным;
dscur value - режим доступа к свойству cur value. Как и предыдущие, временный режим;
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.

Набор данных table

Набор данных table представлен в delphi компонентом table. Этот набор данных в каждый момент времени может быть связан только с одной таблицей базы данных.

Компонент table рекомендуется применять при работе с локальными базами данных, такими как paradox или dbase.

Рассмотрим основные свойства набора данных table. В таблице 3.4. приведены все свойства, которые отображаются в окне инспектора объектов.

Таблица 3.4. Свойства компонента table

Название Тип свойства Описание свойства
active boolean Определяет, является ли набор данных открытым. Если свойство имеет значение false, то набор данных закрыт и с данными ничего не может сделать ни пользователь, ни программа. Если данное свойство установлено в true, то с данными можно осуществлять произвольные действия (изменять, добавлять, удалять и т. д.)
autocalcfields boolean Определяет, как будет осуществляться работа с автомати- чески вычисляемыми полями. Если свойство установлено в true, то значения таких полей будут автоматически вычис- ляться в случае открытия набора данных, перевода набора данных в режим редактирования (dsedit), передачи фокуса с одного визуального компонента на другой или из одной колонки визуального компонента в другую
autorefresh boolean Определяет порядок обновления на сервере базы данных визуальных компонентов для отображаемых полей. Если значение свойства - false (по умолчанию), то автоматиче- ское обновление будет отсутствовать. Для обновления данных в этом случае программист должен предусмотреть вызов процедуры refresh. Если значение свойства - true, то обновления будут осуществляться автоматически
cachedupdates boolean Установка значения свойства в true позволяет кэшировать изменения, сделанные в базе данных. При этом данные хранятся в оперативной памяти, и для их переноса в базу данных применяется метод applyupdates. Для отмены сде- ланных изменений вызывается метод cancelupdates. Для очистки содержимого кэша используется метод commitupdates
constraints tcheckconstraints Определяет ограничения целостности на уровне записи, накладываемые на значения отдельных полей набора данных
databasename string Определяет имя базы данных, связанной с набором данных
defaultindex boolean Определяет, будут ли данные в таблице отсортированы по полю первичного ключа или главного индекса. Значение свойства по умолчанию - true
exclusive boolean Если значение свойства - true, то другие приложения не смогут обратиться к уже открытому набору данных (приме- нимо только к таблицам paradox и dbase). Необходимо обя- зательно закрывать открытую таблицу при смене значения данного свойства
fielddefs tfielddefs Задает набор полей, которые определяют набор данных. Позволяет программно, во время выполнения приложения создавать таблицы и их поля
filter string Содержит текст текущего фильтра для набора данных. В визуальных компонентах будут отображаться только те данные, которые соответствуют условиям данного фильтра
filtered boolean Определяет, будет ли учитываться значение свойства filter при отображении данных в визуальных компонентах. В случае true данные будут фильтроваться в соответствии со свой- ством filter, иначе - фильтр игнорируется
filter options tfilter options Содержит два подчиненных свойства, которые определяют, является ли фильтр чувствительным к регистру букв и разрешается ли в фильтре использование символа «*» в качестве указателя на любое количество любых символов. По умолчанию эти два свойства имеют значения false
indexdefs tindexdefs Содержит информацию об индексах таблицы
indexfieldnames string Содержит список столбцов таблицы, которые выбраны в качестве индексных
indexfiles tstrings Содержит название одного или нескольких индексных файлов для таблицы формата dbase
indexname string Определяет альтернативные индексы для таблицы
masterfields string Определяет одно или несколько полей главной таблицы (master table) для установления связи с соответствующими полями подчиненной таблицы, то есть для установления связи «master-detail»
mastersource tdatasource Задает имя компонента источника данных, свойство dataset которого определяет набор данных, используемый в качестве главной (master) таблицы при установлении связи «master- detail»
name tcomponentname Определяет имя компонента набора данных. По умолчанию присваиваются имена table1, table2, ј, tablen
objectview boolean Указывает, как хранятся объекты полей в свойстве fields: иерархически или последовательно (дочерние поля размещены после родительских)
readonly boolean Фиксирует, можно ли изменять данные в таблице, или они доступны только для чтения. Если значение свойства - false (по умолчанию), то изменение данных разрешено, иначе - данные из таблицы доступны только для чтения
sessionname string Определяет имя компонента session, связанного с данной таблицей
storedefs boolean Указывает, где сохраняются определения полей и индексов. Если значение данного свойства - true, то определения полей и индексов будут сохраняться в модуле данных или в форме. В случае false (по умолчанию), информация сохраня- ется в файлах базы данных
tablename tfilename Определяет имя файла таблицы базы данных, которую инкапсулирует объект. Условием установки этого свойства является присвоение значения false свойству active
tabletype ttabletype Определяет структуру используемой таблицы базы данных и может принимать следующие значения: ttdefault - тип таблицы определяется по ее расширению (*.db - paradox, *.dbf - dbase, *.txt - ascii); ttparadox - таблица paradox; ttdbase - таблица dbase; ttfoxpro - таблица foxpro; ttascii - таблица в текстовом формате с данными, разде- ленными запятыми
tag longint Не имеет специального назначения. Применяется для хранения целого числа, связанного с компонентом. Может применяться по усмотрению программиста
updatemode tupdatemode Определяет критерии поиска обновляемой записи базы данных sql в bde (какие поля учитываются). Может принимать одно из трех значений: upwhereall - все поля; upwherechanged - только ключевые поля и поля, значения которых были изме- нены; upwherekeyonly - только ключевые поля
updateobject tdatasetupdateobject Определяет объект типа tdatasetupdateobject, который используется для обновления записи


Набор данных query

Набор данных query представлен в delphi компонентом query. Особенностью компонента query является то, что его записи формируются после выполнения sql-запроса.

В отличие от набора данных table, компонент query может содержать записи сразу нескольких таблиц.

Данный компонент удобно использовать при работе с удаленными базами данных.

Многие свойства компонента query несут ту же нагрузку, что и соответствующие свойства компонента table. В таблице 3.5 мы приведем лишь те из них, которые являются специфичными для компонента query.

Таблица 3.5. Некоторые свойства компонента query

Название Тип свойства Описание свойства
constrained boolean Задает совместимость ограничений в предложении select с операциями редактирования и вставки записей в таблицах paradox и dbase
datasource tdatasource Указывает имя компонента tdatasource, относящегося к глав- ному набору данных, из которого берется значение ключа; этому значению должны соответствовать записи набора данных
paramcheck boolean Определяет, должно ли свойство params автоматически обнов- ляться при изменении запроса в свойстве sql во время выполнения
params tparams Содержит параметры запроса, находящегося в свойстве sql
requestlive boolean Позволяет попытаться возвратить результат запроса как «живой» набор данных, вместо таблицы «только для чтения»
sql tstrings Содержит текст sql-запроса
unidirectional boolean Определяет доступность двунаправленного курсора borland database engine (bde)


Источник данных

Источник данных (data source) представляет собой промежуточный элемент, который применяется для связи набора данных с визуальными компонентами. Получается как бы цепочка: «набор данных - источник данных - визуальный компонент».

Для этой цели в delphi служит компонент datasource. Указанный компонент имеет пять основных свойств, которые отображаются в окне инспектора объектов. Эти свойства и их краткое описание представлены в табл. 3.6.

Таблица 3.6. Свойства компонента datasource

Название Тип свойства Описание свойства
autoedit boolean Определяет, может ли набор данных автоматически перево- диться в режим модификации при попытке изменения данных пользователем. По умолчанию значение свойства - true, то есть такой перевод разрешен. В случае если вы не хотите допустить случайное изменение данных - установите значение этого свойства в false
dataset tdataset Служит для указания набора данных, с которым связан источник данных. Отметим, что визуальные компоненты для связи с источником данных используют свое свойство datasource
enabled boolean Определяет, будут ли визуальные компоненты, связанные с этим источником данных, отображать данные из набора данных (true - да, false - нет)
name tcomponentname Задает имя источника данных. По умолчанию источники данных получают имена datasource1, datasource2, ј, datasourcen
tag longint Не имеет специального назначения. Применяется для хранения це- лого числа, связанного с компонентом, по усмотрению программиста


ВНИМАНИЕ. Вне зависимости от значения свойства autoedit есть возможность программно изменять данные в наборе данных. Кроме того, независимо от значения этого свойства пользователь может перевести набор данных в режим модификации с помощью нажатия кнопок визуального компонента dbnavigator. Таким образом, значение свойства autoedit влияет лишь на попытку изменения данных пользователем.

При изменении данных в наборе данных происходит генерация события ondatachange, которое имеет тип tdatachangeevent. Этот тип описан в delphi следующим образом:

type tdatachangeevent = procedure (s ender: tobject; field: tfield) of object;

Параметр field определяет, значение какого поля было изменено. Если данные были обновлены в нескольких полях, то параметр будет содержать пустое значение (nil).

ВНИМАНИЕ. Событие ondatachange может произойти также и в случае, когда происходит переход на другую запись набора данных. Оно возникает, если значение текущего поля старой записи отличается от значения того же самого поля новой записи. Кроме того, это событие имеет место при первоначальном открытии набора данных.

Кроме события ondatachange, при изменении значений полей текущей записи возникает событие onupdatedata, которое имеет тип tnotifyevent. Такое событие происходит перед записью данных в базу данных. Таким образом, его можно использовать, например, для подтверждения внесенных изменений или отказа от них.

Связь между набором данных и источником данных обычно устанавливается на этапе проектирования приложения с помощью инспектора объектов. delphi допускает установку или разрыв этой связи и в процессе выполнения приложения. При установлении новой связи визуальные компоненты автоматически подключатся к новому набору данных и будут отображать его значения.

Приведем пример установки и разрыва связи (листинг 3.1).

Листинг 3.1. Установка и разрыв связи с наборами данных

datasource1.dataset := table1; // установка связи с набором
// данных table1
datasource1.dataset := nil; // присвоение пустого
// значения свойству dataset
// разрывает связь с набором
// данных
datasource1.dataset := query1; // установка связи с набором
// данных query1

В листинге 3.1 можно было опустить

Pascal и Delphi   Теги:

Читать IT-новости в Telegram
Информационные технологии
Мы в соцсетях ✉