Delphi для профессионалов

         

Процессор баз данных Borland Database



Процессор баз данных Borland Database Engine

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

 поиск местоположения базы данных;  поиск таблицы, ее открытие и чтение служебной информации;  чтение данных в соответствии с форматом хранения данных и т. д. Очевидно, что если все стандартные функции доступа к данным реализовать в виде специальной программы, сервиса или динамической библиотеки, то это существенно упростит разработку приложений баз данных, которым для выполнения той или иной операции достаточно будет вызвать готовую процедуру.
Одним из традиционных способов взаимодействия приложения, созданного в среде разработки Delphi, и базы данных является использование процессора баз данных Borland Database Engine 5. Он представляет собой набор динамических библиотек, функции которых позволяют не только обращаться к данным, но и эффективно управлять ими на стороне приложения.
Для работы с источниками данных при посредстве BDE в Delphi имеется специальный набор компонентов, расположенных на странице BDE Палитры компонентов. Эти компоненты для работы с базами данных используют возможности BDE, обращаясь к его функциям и процедурам. Механизм доступа к BDE инкапсулирован в базовом классе TBDEDataSet. (Подробно базовые классы компонентов доступа к данным рассмотрены далее в этой части.) Поэтому в процессе программирования у вас не будет необходимости использовать функции BDE напрямую. Почти все, что можно сделать путем прямого обращения, можно сделать и через компоненты — это проще и надежнее.
Тем не менее внутреннюю организацию механизма доступа к данным всегда полезно знать. Кроме этого, всегда полезно знать и уметь использовать дополнительные возможности, которые BDE может предоставить разработчику.
BDE взаимодействует с базами данных при посредстве драйверов. Для особенно распространенных локальных СУБД разработан набор стандартных драйверов. Работа с наиболее распространенными серверами БД осуществляется при помощи драйверов системы SQL Links. Кроме этого, если для базы данных существует драйвер ODBC, то можно использовать и его. Достаточно зарегистрировать этот драйвер в BDE.



Однако BDE не претендует на всеобъемлющую универсальность и имеет некоторые недостатки. Это, например, снижение скорости работы приложения, недостатки реализации некоторых драйверов и т. д. В документации к Delphi 7 содержится предупреждение, что после 2002 года фирма Borland перестанет поддерживать BDE и рекомендует использовать технологию dbExpress, которая также рассматривается в настоящей книге.
В этой главе обсуждаются следующие вопросы.
 архитектура и составные части BDE;  что такое псевдонимы БД и настройка драйверов BDE;  использование утилиты BDE Administrator;  способы прямого использования функций API BDE;  компоненты доступа к данным BDE.
 

Архитектура и функции BDE


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

В составе BDE поставляются стандартные драйверы, обеспечивающие доступ к СУБД Paradox, dBASE, FoxPro и текстовым файлам. Локальные драйверы (рис. 16.1) устанавливаются автоматически совместно с ядром процессора. Один из них можно выбрать в качестве стандартного драйвера, который имеет дополнительные настройки, влияющие на функционирование процессора БД.

Рис. 16.1. Структура процессора баз данных ВОЕ

Доступ к данным серверов SQL обеспечивает отдельная система драйверов — SQL Links. С их помощью в Delphi можно без особых проблем разрабатывать приложения для серверов Oracle 8, Informix, Sybase, DB2 и, естественно, InterBase. Эти драйверы необходимо устанавливать дополнительно.

Помимо этого, в BDE имеется очень простой механизм подключения любых драйверов ODBC (к примеру, Microsoft Access) и создания на их основе сокетов ODBC.

Примечание 

С точки зрения пользователя процесс подключения локального драйвера и драйвера SQL Links практически не отличается, за исключением деталей настройки. Настройка драйверов и собственных параметров BDE осуществляется при помощи специальной утилиты — BDE Administrator и рассматривается далее в этой главе.

В состав BDE входят следующие функциональные подсистемы.

 Администратор системных ресурсов управляет процессом подключения к данным — при необходимости устанавливает нужные драйверы, а при завершении работы автоматически освобождает занятые ресурсы. Поэтому BDE всегда использует ровно столько ресурсов, сколько необходимо.  Система обработки запросов обеспечивает выполнение запросов SQL или QBE от приложения к любым базам данных, для которых установлен драйвер, даже если сама СУБД не поддерживает прямое использование запросов SQL.  Система сортировки является запатентованной технологией и обеспечивает очень быстрый поиск по запросам SQL и через стандартные драйверы аля Paradox и dBASE.  Система пакетной обработки представляет собой механизм преобразования данных из одного формата в другой при выполнении операций над целыми таблицами. Эта система использована в качестве основы для компонента TBatcMove и утилиты DataPump (автоматического переноса структур данных между базами данных), входящей в стандартную поставку BDE.  Менеджер буфера управляет единой для всех драйверов буферной областью памяти, которую одновременно могут использовать несколько драйверов. Это позволяет существенно экономить системные ресурсы.  Менеджер памяти взаимодействует с ОС и обеспечивает эффективное использование выделяемой памяти. Ускоряет работу драйверов, которые для получения небольших фрагментов памяти обращаются к нему, а не к ОС. Дело в том, что менеджер памяти выделяет большие объемы оперативной памяти и затем распределяет ее небольшими кусками между драйверами согласно их потребностям. Транслятор данных обеспечивает преобразование форматов данных для различных типов БД.  Кэш BLOB используется для ускорения работы с данными в формате BLOB.  SQL-генератор транслирует запросы в формате QBE в запросы SQL.  Система реструктуризации обеспечивает преобразование наборов данных в таблицы Paradox или dBASE.  Система поддержки драйверов SQL повышает эффективность механизма поиска при выполнении запросов SQL.  Таблицы в памяти. Этот механизм позволяет создавать таблицы непосредственно в оперативной памяти. Используется для ускорения обработки больших массивов данных, сортировки, преобразования форматов данных.  Связанные курсоры обеспечивают низкоуровневое выполнение межтабличных соединений. Позволяют разработчику не задумываться над реализацией подобных связей при работе на уровне VCL — для этого достаточно установить значения нескольких свойств.  Менеджер конфигурации обеспечивает разработчику доступ к информации о конфигурации драйверов.

Перечисленные функции реализованы в динамических библиотеках, которые, собственно, и называются процессором БД (табл. 16.1).

Таблица 16.1. Ядро процессора баз данных ВОЕ 5

Имя файла

Назначение

IDAPI32.DLL

Базовая динамическая библиотека ВОЕ

IDPROV.DLL

Динамическая библиотека, отвечающая за работу серверной части приложения

BLW32.DLL

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

IDBAT32.DLL

Динамическая библиотека с функциями межтабличного переноса данных

IDQBE32.DLL

Динамическая библиотека, обеспечивающая работу запросов по примеру (Query By Example, QBE)

IDSQL32.DLL

Динамическая библиотека, обеспечивающая обработку запросов SQL

IDASCI32.DLL

Динамическая библиотека, обеспечивающая работу драйвера текстовых файлов

IDPDX32.DLL

Динамическая библиотека, обеспечивающая работу драйвера Paradox

IDDBAS32.DLL

Динамическая библиотека, обеспечивающая работу драйвера dBASE

DODBC32.DLL

Динамическая библиотека, обеспечивающая работу драйвера сокета ODBC

IDR20009.DLL

Динамическая библиотека ресурсов, содержащая сообщения об ошибках

IDDA032.DLL

Динамическая библиотека, обеспечивающая работу драйверов Microsoft Access 95 и Jet Engine 3.0

IDDA3532.DLL

Динамическая библиотека, обеспечивающая работу драйверов Microsoft Access 97 и Jet Engine 3.5

IDDR32.DLL

Динамическая библиотека для работы с Репозиторием данных

Кроме этого имеется шесть дополнительных DLL, обеспечивающих работу BDE с серверами Oracle и Microsoft SQL Server.

 

Псевдонимы баз данных и настройка ВDЕ


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

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

Для решения такого рода проблем разработчик может использовать псевдоним базы данных, который представляет собой именованную структуру, содержащую путь к файлам БД и некоторые дополнительные параметры. В первом приближении можно сказать, что вы просто присваиваете маршруту произвольное имя, которое используется в приложении. Тогда при переносе приложения на компьютере заказчика достаточно создать стандартными средствами BDE одноименный псевдоним и настроить его на нужный каталог. При этом само приложение не требует переделок, т. к. оно обращается к псевдониму с одним именем, а вот BDE уже "знает" куда отправить запрос приложения, использовавшего этот псевдоним.

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

Для управления псевдонимами баз данных, настройки стандартных и дополнительных драйверов в составе BDE имеется специальная утилита — BDE Administrator (исполняемый файл BDEADMIN.EXE). Стандартная конфигурация BDE сохраняется в файле IDAPI.CFG. При необходимости текущую конфигурацию можно сохранить в новом файле с расширением cfg или загрузить заново при помощи команд Save As Configuration и Open Configuration из меню Object.

В верхней части окна утилиты расположена Панель инструментов, кнопки которой используются при работе с конкретным элементом настройки BDE. Рабочая область утилиты BDE Administrator представляет собой двухстраничный блокнот.

Страница Databases (рис. 16.2) содержит иерархическое дерево, в узлах которого расположены установленные в системе на данный момент псевдонимы БД. При выборе какого-либо псевдонима в правой части панели появляется путь к файлам базы данных и перечень параметров драйвера, соответствующего псевдониму, которые можно настраивать вручную.

Рис. 16.2. Окно утилиты BDE Administrator с открытой страницей Databases

Рис. 16.3. Окно утилиты BDE Administrator с открытой страницей Configuration

Страница Configuration (рис. 16.3) используется для настройки параметров драйверов BDE, предназначенных для обеспечения доступа к локальным СУБД и серверам БД. Также здесь определяется системная конфигурация BDE, которая включает параметры числовых форматов, форматов даты и времени. Вся информация на этой странице также структурирована в виде иерархического дерева.

При выборе в левой части панели утилиты какого-либо узла, в правой части на странице Definition отображается вся необходимая информация для этого объекта.

Сохранение изменений осуществляется при помощи команд меню Object, всплывающего меню или при перемещении на другой псевдоним.

Для создания нового псевдонима требуется выбрать команду New из меню Object или из всплывающего меню узла Databases на одноименной странице. Затем в появившемся простом диалоге задается необходимый драйвер.

Отметим, что один из четырех стандартных локальных драйверов устанавливается на странице Configuration в качестве предопределенного, поэтому в списке он доступен под названием STANDARD, а остальные не видны вообще. Из драйверов SQL Links доступны те, которые были установлены при инсталляции Delphi или позже.

Кроме того, в списке можно выбрать один из драйверов ODBC, установка которых осуществляется стандартными системными средствами на Панели управления Windows.

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

Для четырех локальных драйверов список параметров в правой части панели утилиты на странице Definition ограничивается параметрами стандартного драйвера (STANDARD), подробная настройка для каждого драйвера осуществляется на странице Configuration.

Назначение параметров локальных драйверов BDE (Paradox, dBASE, FoxPro, ASCII) представлено в табл. 16.2.

Таблица 16.2. Параметры драйверов BDE для локальных баз данных

Параметр

 Назначение

STANDARD

DEFAULT DRIVER

 Задает тип конкретного локального драйвера (Paradox, dBASE, FoxPro, ASCII)

ENABLE BCD

i Определяет способ представления вещественных чисел. При значении True такие числа преобразуются в формат BCD (Binary Coded Decimals— десятичные с двоичным кодированием). Точность составляет 20 знаков после запятой

PATH

 Указывает путь к файлам базы данных

PARADOX

NET DIR

Указывает путь к файлу обеспечения сетевого доступа  к БД PDOXUSRS.NET. Драйвер приложения, которое  работает с БД локально, должен указывать на этот файл, расположенный на том же компьютере. Драйвер приложения, обращающегося к БД по сети, должен указывать на подключенный сетевой диск с этим файлом

VERSION

Нередактируемая информация о версии драйвера

TYPE

Тип СУБД. Для Paradox имеет значение FILE. Только для чтения

LANGDRIVER

 Определяет драйвер языковой поддержки (используйте  драйвер Paradox Cyrr 866)

BLOCK SIZE

 Задает размер блоков дискового пространства для хранения записей, кратно 1024

FILL FACTOR

 Определяет процент заполнения блока дискового пространства при хранении индексов, по умолчанию 95%

LEVEL

 Задает формат временной таблицы в памяти: 

  3 — совместим с Paradox 3.5 и ниже; 

 4 — Paradox 4.0; 

 5 — Paradox 5.0; 

 7 - Paradox для WIN32

STRICTINTEGRTY

Определяет возможность использования приложениями на базе Paradox 4.0 более поздних таблиц со ссылочной целостностью. При значении True использование разрешается, но возникает риск нарушения целостности данных

DBASE

VERSION

Нередактируемая информация о версии драйвера

TYPE

Тип СУБД. Для dBASE имеет значение FILE. Только для чтения

LANGDRIVER

Определяет драйвер языковой поддержки (используйте драйвер dBASE RUS ср866)

LEVEL

Задает формат таблиц. Значение соответствует номеру  версии СУБД

MDX BLOCK SIZE

Размер блоков для файлов с расширением mdx, кратно 51 2

MEMO FILE BLOCK SIZE

Размер блоков для файлов с данными типа Memo (pacширение dbt), кратно 512

FOXPRO

VERSION

 Нередактируемая информация о версии драйвера

TYPE

Тип СУБД. Для FoxPro имеет значение FILE. Только для  чтения

LANGDRIVER

Определяет драйвер языковой поддержки

LEVEL

Имеет значение 25

Примечание 

Драйвер текстовых файлов ASCIIDRV имеет параметры стандартного драйвера.

Назначение параметров драйверов SQL Links для серверов SQL представлено в табл. 16.3. Сначала приведены параметры, которые встречаются в двух и более драйверах, затем уникальные для каждого драйвера параметры. Драйверы для серверов InterBase и Sybase не представлены, т. к. содержат только общие для двух серверов параметры.

Таблица 16.3. Параметры драйверов ВОЕ для серверов SQL

Параметр

Назначение

Общие параметры (встречаются как минимум у двух драйверов)

VERSION

Нередактируемая информация о версии драйвера

TYPE

Тип СУБД. Только для чтения

DLL

Название библиотеки динамического связывания SQL Links для 16-разрядного драйвера. Только для чтения

DLL32

Название библиотеки динамического связывания SQL Links для 32-разрядного драйвера. Только для чтения

DRIVER FLAGS

Используется только при необходимости применения старых версий драйвера, где не поддерживается уровень изоляции транзакций Read Committed. Для этого необходимо установить значение 512

TRACE MODE

Содержит битовую маску, которая определяет тип выдаваемой отладочной информации

BATCH COUNT

Задает число записей, модифицируемых в одном пакете при фиксации транзакций

BLOB SIZE

Размер кэша для данных типа BLOB. Диапазон от 32К до 1000К

BLOBS TO CACHE

Задает число кэшируемых записей с данными BLOB. Диапазон от 64 до 65 536

ENABLE BCD

Определяет способ представления вещественных чисел. При значении True такие числа преобразуются в формат BCD (Binary Coded Decimals — десятичные с двоичным кодированием), который позволяет округлять погрешности высших разрядов дробной части числа. Изменение параметра для псевдонима работает, только если параметр драйвера на странице Configuration не пустой

ENABLE SCHEMA CACHE

Определяет режим кэширования структуры данных. При значении True структура таблиц БД кэшируется локально в каталоге, задаваемом параметром SCHEMA CACHE DIR. Рекомендуется использовать только для баз данных с постоянной структурой

LANGDRIVER

Определяет драйвер языковой поддержки

MAX ROWS

Ограничивает максимальное число записей, которое может быть передано клиенту в ответ на запрос. Значение по умолчанию  (ограничений нет)

OPEN MODE

Режим работы с записями БД: 

 READ/WRITE — полный доступ; 

 READ ONLY — только чтение

SCHEMA CACHE DIR

Каталог для локального кэширования структуры данных (см. параметр ENABLE SCHEMA CACHE)

SCHEMA CACHE SIZE

Задает число таблиц, структура данных которых может кэшироваться

SCHEMA CACHE TIME

Задает время хранения кэшируемой структуры данных: 

 -1 — время не ограничено;

  0 — данные не кэшируются;

  1 — 21 47483647 — секунды

SERVER NAME

Указывает путь к таблицам БД (это может быть локальный маршрут или маршрут с указанием удаленного сервера БД)

SQLPASSTHRU MODE

Задает способ использования соединения с сервером прямыми запросами SQL и запросами, управляемыми пользователем.

SHARED AUTOCOMMIT— соединение используется совместно и прямые запросы фиксируются автоматически.

SHARED NO AUTOCOMMIT— соединение используется совместно и прямые запросы фиксируются сервером самостоятельно.

NOT SHARED — совместное использование запрещено

 

SQLQRYMODE

Задает режим управления запросами.

NULL — сначала запрос передается серверу, если тот не может обработать его, запрос выполняется локально.

SERVER — запрос передается серверу.

 LOCAL — запрос выполняется локально

VENDOR INIT

Название файла динамической библиотеки поставщика

CONNECT TIMEOUT 

Определяет временной интервал, после которого клиент попытается восстановить прерванную связь с сервером

TIMEOUT

Задает время ожидания ответа сервера на запрос

BLOB EDIT LOGGING 

Управляет механизмом сохранения всех изменений для полей типа BLOB. При значении True изменения сохраняются

DATABASE NAME 

Имя базы данных

MAX QUERY TIME

Задает максимальное время ожидания ответа на запрос

USER NAME

Имя пользователя, которое используется сервером при подключении

Microsoft SQL Server (MSSSQL)

MAX DBPROCESSES 

Максимальное число процессов, одновременно работающих в данном соединении

APPLICATION NAME 

Имя приложения, помогающее серверу идентифицировать процессы

DATE MODE

Определяет формат даты:

0 - МДГ; 

 1 - ДМГ;

2-ГМД

HOST NAME

Содержит имя рабочей станции. Помогает серверу при идентификации процессов

NATIONAL LANG NAME 

Задает национальный язык, который используется для вывода текста в сообщениях об ошибках

TDS PACKET SIZE 

Определяет размер пакетов потоков данных

Oracle (ORACLE)

NET PROTOCOL 

Устанавливает сетевой протокол передачи данных

Informix (INFORMIX)

DATE SEPARATOR 

Задает разделитель для формата даты

Microsoft Access (MSACCIESS)

SYSTEM DATABASE

Путь к системной базе данных с информацией о правах доступа. При изменении параметра драйвер необходимо перезагрузить

DB2 (DB2)

DB2 DSN 

Задает имя соединения с БД. Это название псевдонима клиента DB2, который создается на сервере

DRIVER 

Имя драйвера DB2

ROWSET SIZE 

Определяет число записей, передаваемых одновременно

Драйверы ODBC

ODBC DRIVER 

Имя драйвера ODBC

ODBC DSN 

Имя набора данных ODBC

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

Страница Configuration, помимо настройки установленных в BDE драйверов, позволяет редактировать параметры, используемые BDE при инициализации приложения. Эти параметры доступны при выборе узлов System, a затем INIT иерархического дерева. Назначение параметров представлено в табл. 16.4.

Таблица 16.4. Параметры инициализации приложения

Параметр

Назначение

AUTO ODBC

В значении True при каждой инициализации в BDE автоматически импортируются все установленные в системе драйверы ODBC

DATA REPOSITORY

Имя текущего словаря данных

DEFAULT DRIVER

Локальный драйвер, используемый по умолчанию в драйвере STANDARD

LANGDRIVER

Драйвер языковой поддержки. При использовании стандартных локальных драйверов это значение перекрывают те, которые определены непосредственно в конфигурациях драйверов Paradox, dBASE, FoxPro, ASCII

LOCAL SHARE

Устанавливает режим совместного использования файлов приложениями, работающих через BDE и другие программы. В значении True совместное использование разрешено

LOW MEMORY USAGE LIMIT

Максимальный объем памяти (в Кбайтах), который BDE пытается использовать в первом Мбайте оперативной памяти

MAXBUFSIZE

Максимальный размер кэша данных. Он должен быть не меньше значения параметра MINBUFSIZE и кратен 1 28

MAXFILEHANDLES

Максимальное число используемых файлов

MEMSIZE

Максимальный объем используемой BDE памяти в Мбайтах

MINBUFSIZE

Минимальный размер кэша данных. Он должен быть не больше значения параметра MAXBUFSIZE и кратен 128

MTS POOLING

Управляет режимом объединения ресурсов MTS (Microsoft Transaction Server). Обеспечивает лучшую производительность

SHAREDMEMLOCATION

Содержит адрес памяти, который пытаются использовать Менеджер памяти и Менеджер буфера. При возникновении конфликтов адрес необходимо поменять вручную. Задается только второе слово адреса

SHAREDMEMSIZE

Максимальный объем памяти, используемый Менеджером памяти и Менеджером буфера

SQLQRYMODE

См. табл. 16.2

SYSFLAGS

Не используется

VERSION

Номер внутренней версии BDE. Только для чтения

Также на странице Configuration устанавливаются параметры форматов даты, времени и чисел. Доступ к параметрам осуществляется через узлы System и Format.

 

Интерфейс прикладного программирования ВDЕ


Как уже говорилось выше, любое приложение Delphi, работающее с базами данных и написанное с использованием стандартных компонентов доступа к данным, обращается к данным и получает результат при помощи BDE. При этом механизм доступа к данным использует вызовы функций из API BDE.

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

Итак, для создания приложения на основе вызовов функций BDE необходимо выполнить следующие операции:

1. Инициализация BDE (функция DbiInit).

2. Открытие объекта базы данных (функция DbiOpenDatabase).

3. Определение рабочего каталога (функция obiSetDirectory), если на предыдущем этапе не задается псевдоним БД.

4. Определение временного каталога (функция DbiSetPrivateoir).

5. Открытие набора данных и создание курсора (функции DbOреnТаblе, DbiQExec и пр.; дескриптор курсора hDBICur).

6. Заполнение структуры cuRProps, содержащей данные о курсоре и наборе данных (функция DbiGetCursorProps).

7. Выделение памяти для буфера записи.

8. Навигация набору данных (функции DbiSetToBegin, DbiSetToEnd, DbiSetToCursor и пр.)

9. Чтение необходимой записи (функции DbiGetRelativeRecord,  DbiGetNextRecord, DbiGetRecord, DbiGetPriorRecord и др.).

10. Чтение или обновление необходимого поля (функции DMGetFieid, DbiPutField).

11. Освобождение всех ресурсов (освобождение буфера записи, закрытие курсора, таблицы, BDE).

При использовании в программе функций из API BDE необходимо включить в секцию uses модуль BDE.

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

Дело в том, что при удалении записи из таблицы локальной СУБД (например Paradox) размер файла таблицы остается прежним, даже если удалить все записи. То есть на самом деле запись не удаляется, а только становится недоступной. При интенсивном использовании базы данных файлы таблиц могут занимать значительные объемы дискового пространства при довольно умеренном числе записей.

Рис. 16.4. Главная форма проекта BDEEmptyTable

Полная очистка таблиц базы данных осуществляется функцией DbiErr.ptyTable из API BDE. Именно она используется в демонстрационном приложении для радикального уменьшения размера таблиц.

Примечание 

Функция DbiEmptyTable используется в методе EmptyTable компонентов доступа к данным (см. гл. 17).

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

 Листинг 16.1. Модуль главной формы приложения BDEEmptyTable 

unit Main; 

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 

StdCtrls, BDE, ExtCtrls, DBCtrls, Grids, DBGrids, Db, DBTables, Buttons;

type

TMainForm = class(TForm)

AliasesList: TComboBox;

TablesList: TComboBox;

EmptyBtn: TBitBtn;

Labell: TLabel;

Label2: TLabel;

procedure FormClose(Sender: TObject; var Action: TCloseAction);

procedure FormShow(Sender: TObject);

procedure AliasesListChange(Sender: TObject);

procedure EmptyBtnClick(Sender: TObject); private

hDB: hDBIDB;

hCursor: hDBICur;

DBDesc: DBDesc;

TblDesc : TBLBaseDesc;

 public

{ Public declarations } 

end;

var

MainForm: TMainForm;

implementation 

{$R *.DFM}

procedure TMainForm.FormShow(Sender: TObject); 

var Rslt: DBIResult;

 begin

AliasesList.Items.Clear;

 TablesList.Items.Clear; hDB := Nil; 

try

DbiInit(Nil); // Инициалы BDE

 BDE DbiOpenDatabaseList(hCursor) ;

 repeat

Rslt:= DbiGetNextRecord(hCursor, dbiNOLOCK, @DBDesc, nil) ;

 if (Rslt 0 DBIERR_EOF) then

AliasesList.Items.Add(StrPas(DBDesc.szName));

 until (rslt <> DBIERR_NONE); DbiCloseCursor(hCursor) ;

 except

on E:EDBEngineError do ShowMessage ('OiiMSKa MHMunajiM3auMM BDE');

end; 

end;

procedure TMainForm.FormClose(Sender: TObject;

 var Action: TCloseAction); 

begin

 try

finally

if hDB <> Nil then DbiCloseDatabase(hDB);// Закрытие базы данных

 DbiExit; // Закрытие сеанса работы с ВОЕ 

end

 end;

procedure TMainForm.AliasesListChange(Sender: TObject); 

begin

 try

if hDB <> Nil

then DbiCloseDatabase(hDB);// Закрытие базы данных 

DbiOpenDatabase // Открытие базы данных 

(

PChar(AliasesList.Text), // Псевдоним базы данных 

Nil, // Тип базы данных 

dbiReadWrite, // Режим редактирования данных

 dbiOpenShared, // Режим разделения данных

 Nil, // Пароль

0, // Число дополнительных параметров 

Nil, // Перечень полей для доп. параметров Nil, 

// Список доп. параметров hDB 

// Дескриптор базы данных 

);

DbiSetPrivateDir('с:\temp');// Определение временного каталога

DbiOpenTableList(hDb, False, False, '*.DB', hCursor);

TablesList.Items.Clear;

TablesList.Clear;

while DbiGetNextRecord(hCursor, dbiNOLOCK, @TblDesc, nil) = dbiErr_None

do TablesList.Items.Add(TblDesc.szName);

 DbiCloseCursor(hCursor);

 except

on E:EDBEngineError do ShowMessage('Ошибка открытия базы данных');

 end;

 end;

procedure TMainForm.EmptyBtnClick(Sender: TObject); 

begin

try

DbiEmptyTable(hDB, Nil, PChar(TablesList.Text), '');

except

on E:EDBEngineError do ShowMessage('Неверно задана таблица'}; 

end; 

end;

end.

При открытии главной формы (метод-обработчик FormShow) функция Dbiinit осуществляет инициализацию BDE. Затем функция DbiOpenDatabaseList создает в памяти временную таблицу, в которую записываются характеристики каждой зарегистрированной базы данных. Для этого применяется структура DBDesc. Курсор hcursor обеспечивает доступ к записям о базах данных.

После этого функция DbiGetNextRecord позволяет осуществить последовательное считывание имен псевдонимов баз данных (для этого в параметре передается указатель на структуру DBDesс) и их запись в список компонента AliasesList типа TComboBox.

При выборе из этого списка конкретного псевдонима работает метод-обработчик AliasesListchange. В нем открывается соответствующая база данных (функция DbiOpenDatabase), доступ к которой в дальнейшем осуществляется через дескриптор hDB.

Функция DbiopenTableList создает временную таблицу в памяти, в которую помещаются данные о таблицах выбранной базы данных в соответствии с форматом структуры TBLBaseDesс. Функция DbiGetNextRecord позволяет передать эту информацию в список компонента TablesList типа TCombоВох.

При щелчке на кнопке EmptyBtn в методе-обработчике EmptyBtndick работает функция DbiEmptyTabie, которая очищает выбранную ранее в компоненте TablesList таблицу.

Теперь рассмотрим пример простейшего приложения, которое может отображать два поля из таблицы COUNTRY. DВ в демонстрационной базе данных DBDEMOS. Эта база данных поставляется в комплекте Delphi. В примере использованы только функции API BDE.

Проект называется DirectBDE и имеет только одну форму, в которой отображаются сведения из таблицы COUNTRY. DB о государствах и их столицах (рис. 16.5). Кнопки в нижней части формы позволяют перемещаться по набору данных.

 Листинг 16.2. Модуль главной формы приложения DirectBDE 

unit Unitl; 

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

 StdCtrls, Buttons, BDE, ExtCtrls;

type

TMainForm = class(TForm)

PriorBtn: TBitBtn;

Panel2: ТPanel;:

NextBtn: TBitBtn;

Label3: ТLabel;

CountryEdit: TEdit;

Label1: TLabel;

CapitalEdit: TEdit;

procedure PriorBtnClick(Sender: TObject);

procedure FormShow(Sender: TObject};

procedure FormClose(Sender: TObject;

 var Action: TCloseAction);

procedure NextBtnClick(Sender: TObject); 

private

hDB: hDBIDB;

hCur: hDBICur;

CursProps: CurProps;

RecBuf: pByte;

FValue: array [0 .. 255] of Char;

IsEmpty: Bool;

procedure OnBDEError;

 public

 end;

var

MainForm: TMainForm;

implementation ($R *.DFM}

procedure TMainForm.OnBDEError;

var ErrInfo: dbiErrlnfo; // Структура, содержащая информацию об ошибках

AStr: String; 

begin

DbiGetErrorlnfo(True, Errlnfo);// Функция возвращает информацию об ошибке c

ase Errlnfo.iError of

9733: AStr := 'Для создания записи недостаточно параметров'; 

10024: AStr := 'Ошибка доступа к данным'; 

10245: AStr := 'База данных занята другим пользователем';

 10038: AStr := 'Значение поля задано неверно';

11871: AStr := 'Несоответствие типов';

11959: AStr := 'В выражении отсутствует оператор GROUP BY';

 else

AStr := 'Ошибочная операция с данными'; 

end;

ShowMessage(AStr) ; 

end;

procedure TMainForm.FormShow(Sender: TObject);

 begin

hDB := Nil; hCur := Nil;

Dbilnit(Nil); // Инициализация системы 

BDE DbiOpenDatabase // Открытие базы данных 

(

'DBDEMOS', // Псевдоним базы данных

Nil, // Тип базы данных

dbiReadWrite, // Режим редактирования данных

dbiOpenShared, // Режим разделения данных

Nil, // Пароль

0, // Число дополнительных параметров

Nil, // Перечень полей для доп. параметров

Nil, // Список доп. параметров

hDB // Дескриптор базы данных

);

DbiSetPrivateDir('с:\temp'); // Определение временного каталога

DbiOpenTable // Открытие таблицы

(

hDB, // Дескриптор базы данных 

PChar('COUNTRY'), // Название таблицы

PChar(szParadox), // Тип таблицы (только для локальных БД)

 Nil, // Название индекса (необязательный)

 Nil, // IndexTagName — только для dBASE 

0, // 0 — использовать первичный индекс 

dbiReadWrite, // Режим редактирования данных

 dbiOpenShared, // Режим разделения данных

 xltField, // Режим трансляции данных

False, // Признак одностороннего перемещения курсора

 Nil, // Дополнительные параметры

 hCur // Дескриптор курсора таблицы );

DbiGetCursorProps // Определение параметров курсора 

hCur, // Дескриптор курсора таблицы

CursProps // Структура параметров курсора

 );

GetMem // Вьщеление памяти под буфер записи 

(

RecBuf,

CursProps.iRecbufSize*SizeOf(Byte) );

DbiSetToBegin(hCur); // Установка курсора в начало набора данных

 DbiGetNextRecord // Перемещение на первую запись

 (

hCur, // Дескриптор курсора таблицы 

dbiNoLock, // Режим ограничения доступа

 RecBuf, // Буфер записи 

Nil // Параметры записи );

DbiGetField // Получение значения поля

 (

hCur, // Дескриптор курсора таблицы 

1, // Номер поля в структуре таблицы 

RecBuf, // Буфер записи

@FValue, // Переменная, в которую передается значение

 IsEmpty // Признак пустой ячейки );

MainForm.CountryEdit.Text := FValue;

 DbiGetField(hCur, 2, RecBuf, @FValue, IsEmpty);

 MainForm.CapitalEdit.Text := FValue;

 end;

procedure TMainForm.FormClose(Sender: TObject; 

var Action: TCloseAction);

 begin try

finally

FreeMem(RecBuf); // Освобождение памяти буфера записи DbiCloseCursor(hCur); // Закрытие курсора 

DbiCloseDatabase(hDB); // Закрытие базы данных

 DbiExit; // Закрытие сеанса работы с ВОЕ

end 

end;

procedure TMainForm.PriorBtnClick(Sender: TObject);

begin

try

if DbiGetPriorRecord(hCur, dbiNoLock, RecBuf, Nil) = DBIERR_BOF

then PriorBtn.Enabled := False

else 

begin

if Not NextBtn.Enabled then NextBtn.Enabled := True;

 DbiGetField{hCur, 1, RecBuf, SFValue, IsEmpty); 

MainForm.CountryEdit.Text := FValue;

 DbiGetField(hCur, 2, RecBuf, @FValue, IsEmpty);

 MainForm.CapitalEdit.Text := FValue; 

end; 

except

OnBDEError; 

end;

 end;

procedure TMainForm.NextBtnClick(Sender: TObject);

 begin 

try

if DbiGetNextRecord(hCur, dbiNoLock, RecBuf, Nil)=DBIERR_EOF

 then NextBtn.Enabled := False

 else

begin

if Not PriorBtn.Enabled then PriorBtn.Enabled := True;

 DbiGetFieldfhCur, 1, RecBuf, @FValue, IsEmpty); 

MainForm.CountryEdit.Text := FValue;

DbiGetField(hCur, 2, RecBuf, @FValue, IsEmpty);

 MainForm.CapitalEdit.Text := FValue;

 end; 

except

OnBDEError; 

end;

 end;

end.

Рис. 16.5. Главная форма проекта DirectBDE

При показе главной формы приложения в процедуре Formshow проводится инициализация BDE, открытие базы данных и таблицы. При этом создаются дескрипторы базы данных hDB и курсора таблицы hour, которые играют в дальнейшей работе приложения важную роль. Если при создании базы данных не указывать псевдоним БД, то обязательно нужно определить рабочий каталог базы данных с помощью функции DbiSetoirectory.

После этого отводится память под буфер записи, в который будут передаваться значения полей текущей строки таблицы. Размер буфера определяется при помощи Структуры CURPropS.

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

Навигация по набору данных реализована в методах-обработчиках на нажатие кнопок формы. Их действие аналогично за исключением направления перемещения. При щелчке на кнопке выполняется переход на следующую или предыдущую запись, данные из новой записи помещаются в буфер записи RecBuf. Оттуда при помощи функции DMGetFieid осуществляется чтение значений полей. При достижении начала или конца набора данных кнопка деактивируется.

При закрытии формы проводятся операции по освобождению памяти буфера записи, закрытию базы данных и BDE.

 

Соединение с источником данных


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

Все управление одиночным соединением с какой-либо базой данных в BDE осуществляется компонентом TDatabase (табл. 16.5). В процессе работы компонент активно использует параметры псевдонимов и драйверов BDE.

Таблица 16.5. Свойства и методы компонента TDatabase

Объявление

Тип

Описание

Свойства

property AliasName: string;

Pb

Задает имя псевдонима BDE используемой базы данных

property Connected: Boolean;

Pb

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

property DatabaseName: string;

Pb

Определяет имя базы данных

property DataSetCount:  Integer;

Ro

Возвращает число открытых наборов данных, работающих через данное соединение

property DataSets [Index:  Integer]: TDBDataSet;

Ro

Индексированный список всех объектов открытых наборов данных этого соединения

property Directory: string; 

Pu

Определяет текущий каталог для баз данных Paradox и dBASE

property DriverName: string; 

Pb

Содержит имя драйвера базы данных

property Exclusive: Boolean; 

Pb

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

type HDBIDB: Longint; property Handle: HDBIDB; 

Pu

Дескриптор BDE. Используется для прямых вызовов функций API BDE

property HandleShared: 

Boolean;

 

Pu

При значении True дескриптор BDE компонента доступен в компоненте TSession

property InTransaction:  Boolean 

Ro

Показывает состояние транзакции. При значении True транзакция выполняется

property IsSQLBased: Boolean;

Ro

При значении True соединение работает через драйвер SQL Links

property KeepConnection:  Boolean; 

 

Pb

При значении True соединение продолжает оставаться активным после закрытия всех наборов данных. При значении False после закрытия последнего набора данных соединение закрывается

type TLocale: Pointer;  property Locale: TLocale; 

Ro

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

property LoginPrompt: Boolean; 

Pb

Управляет отображением стандартного диалога регистрации пользователя при подключении к серверу

property Params: TStrings; 

 

Pb

Содержит список значений параметров псевдонима BDE, которые пользователь задает перед подключением к серверу

property Session: TSession

Ro

Указывает на компонент TSession,  который управляет работой данного  компонента

property SessionAlias: Boolean;

Ro

 При значении True при подключении к БД используется псевдоним сессии

property SessionName: string;

Pb

Содержит имя сеанса, который управляет работой компонента

property Readonly: Boolean;

Pb

Управляет режимом доступа к данным  "только для чтения"

property Temporary: Boolean;

Pu

Значение True говорит о том, что экземпляр компонента создан во время выполнения

type

TTraceFlag = (tfQPrepare, tfQExecute, tfError, tfStmt, tf Connect, tfTransact, tfBlob, tfMisc, tfVendor, tfDataln, tfDataOut) ;

TTraceFlags = set of TTraceFlag;

property TraceFlags: TTraceFlags;

Pu

 Определяет перечень операций,  выполнение которых отображается в утилите SQL Monitor при выполнении  приложения

 

type TTransIsolation = (tiDirtyRead, tiReadCommitted, tiRepeatableRead) ;

property Translsolation: TTransIsolation;

Pb

! Определяет уровень изоляции  транзакций:

 tiDirtyRead— незавершенное  чтение;  tiReadCommitted — завершенное  чтение;  tiRepeatableRead — повторяемое чтение

Методы

procedure ApplyUpdates (const DataSets: array of TDBDataSet);

Pu

 

 Фиксирует все изменения в наборах данных, работающих через это соединение, в базе данных

procedure Close;

Pu 

Закрывает все открытые наборы  данных и соединение

procedure CloseDatasets;

Pu

 Закрывает все открытые наборы  данных, работающие через это соединение

procedure Commit;

Pu

Завершает выполнение текущей транзакции и фиксирует все изменения в базе данных

function Execute (const SQL: string; Params : TParams = nil; Cache: Boolean = False; Cursor: phDBICur = nil) : Integer;

Pu

Выполняет запрос SQL без использования компонента TQuery. Текст запроса содержится в параметре SQL. Параметры запроса определяются параметром Params. Режим кэширования изменений включается параметром Cache. Параметр Cursor может использоваться при работе с функциями BDE, использующими курсор набора данных (см. гл. 14)

procedure FlushSchemaCache (const TableName: string);

Pu

Изменяет представление о структуре таблиц БД, загруженной в память

procedure Open;

Pu

Открывает соединение

procedure Rollback;

Pu

Отменяет все операции текущей транзакции и завершает ее

procedure StartTransaction;

Pu

Начинает выполнение транзакции

procedure ValidateName (const Name: string) ;

Pu

Вызывает исключительную ситуацию, если база данных Name уже открыта в текущей сессии

Методы-обработчики событий

type TLoginEvent = procedure (Database: TDatabase; LoginParams: TStrings) of object;

property OnLogin: TLoginEvent;

Pb

Вызывается при регистрации пользователя на сервере

property AfterConnect: TNotifyEvent;

Pb

Вызывается после подключения

property AfterDisconnect: TNotifyEvent;

Pb

Вызывается после отключения

property BeforeConnect: TNotifyEvent;

Pb

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

property AfterDisconnect: TNotifyEvent;

Pb

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

Обычно компонент TDatabase размешается в модуле данных приложения.

Для определения базы данных (сервера), с которой приложение устанавливает соединение при помощи компонента TDatabase, чаще используется свойство AliasName. Свойства DatabaseName и DriverName предоставляют альтернативный способ создания соединения.

Если соединение задано свойством AliasName,то свойство DatabaseName

можно использовать для создания временного псевдонима, который будет доступен только для компонентов доступа к данным внутри приложения. При щелчке на кнопке списка доступных псевдонимов свойства DatabaseName в Инспекторе объектов для любого компонента доступа к данным в списке будет доступен и временный псевдоним компонента TDatabase.

Например, при переключении приложения на другую базу данных можно изменить только значение псевдонима в компоненте TDatabase. Если все компоненты наборов данных подключены к временному псевдониму компонента TDatabase, то они автоматически переключатся на новую БД.

Дополнительные возможности управления наборами данных при переключении соединения предоставляют свойства Connected и KeepConnection. Они позволяют одновременно с соединением закрыть все активные наборы данных.

Если наборы данных приложения подключены к базе данных через компонент TDatabase, то перед их открытием необходимо установить соединение с БД. Соединение с БД устанавливается при помощи метода open. Если попытаться активизировать набор данных без этого метода, то соединение будет установлено автоматически.

Аналогичная картина возникает при закрытии наборов данных и отключении от БД. Дополнительное средство управления в этом случае предоставляет свойство KeepConnection. Если оно равно значению True, то при закрытии последнего открытого набора данных соединение остается открытым. В противном случае соединение автоматически закрывается.

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

При подключении к базе данных довольно часто требуется задать значения для параметров драйвера BDE. Для этого используется свойство Params, представляющее собой обычный список. В нем необходимо задавать названия изменяемых параметров и их новые значения:

USERNAME=SYSDBA 

PASSWORD=masterkey

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

Компонент TDatabase может облегчить подключение к базам данных с регистрацией пользователей. При регистрации на сервере достаточно задать имя пользователя, пароль в свойстве Params (см. выше) и установить для свойства LoginPrompt значение False. Эта комбинация работает как во время выполнения, так и во время разработки.

Примечание

Для организации доступа к защищенным паролем таблицам Paradox используется метод AddPassword компонента TSession (см. выше).

Дополнительные возможности обработки регистрации пользователя дает единственный метод-обработчик onLogin, программный код которого выполняется вместо появления стандартного диалога ввода имени и пароля. Это позволяет разработчику создавать собственные сценарии регистрации пользователей.

Для обеспечения доступа к функциям API BDE используется свойство Handle (BDE играет важную роль при создании соединения).

Управление выполнением транзакций осуществляется при помощи методов StartTransaction, Commit и RollBack.

 

Компоненты доступа к данным


Компоненты доступа к данным, используемые при разработке приложений BDE, располагаются на странице BDE Палитры компонентов. Их общими предками являются классы TBDEDataSet и TDBDataSet (см. рис. 12.1). Они обеспечивают работоспособность основных компонентов доступа к данным BDE — TTable, TQuery, TStoredProc.

 

Класс TBDEDataSet


Этот класс является потомком класса TDataSet, его значение трудно переоценить: именно TBDEDataSet обеспечивает работоспособность важнейших механизмов набора данных за счет обращения к функциям BDE (табл. 16.6). Например, класс TBDEDataSet перекрывает абстрактные методы своего предка TDataSet, отвечающие за такие важнейшие операции, как чтение данных и сохранение изменений в базе данных, навигация по записям набора данных, фильтрация.

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

type

TFilterOption = (foCaselnsensitive, foNoPartialCompare);

TFilterOptions = set of TFilterOption;

property FilterOptions: TFilterOptions;

Оно определяет дополнительные параметры отбора записей по фильтру (чувствительность к регистру символов и отбор по текстовому шаблону).

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

 Примечание

Эта возможность очень полезна при создании клиентских приложений в архитектуре клиент/сервер и играет ключевую роль при обеспечении возможности редактирования наборов данных сложных запросов SQL.

Дополнительно к методам работы с полями класса TDataSet добавлены функции использования полей в формате BLOB.

Для обеспечения использования функций API BDE на программном уровне добавлено свойство, содержащее дескриптор курсора, соответствующего текущей записи набора данных:

type HDBICur: Longint; 

property Handle: HDBICur;

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

Таблица 16.6. Свойства и методы класса TBDEDataSet

Объявление

Тип

Описание

Свойства

property BlockReadSize: Integer;

Pu

Определяет размер буфера при блочном чтении данных. Такой режим используется для быстрого перемещения по большим массивам данных. Если значение свойства больше нуля, навигация по набору данных осуществляется без изменения состояния компонентов отображения данных и вызова методов-обработчиков событий

property CacheBlobs: Boolean;

Pu

Разрешает использование буфера памяти для данных типа BLOB

property CachedUpdates: Boolean;

Pb

Включает или отключает режим кэширования изменений в наборе данных. Используется в клиентских приложениях архитектуры клиент/сервер

property CanModify: Boolean;

Pu, Ro

Если набор данных позволяет делать изменения, свойство возвращает True, иначе — False

property Explndex: Boolean;

Pu, Ro

Показывает, используются ли в наборе данных индексы dBASE

property Filter: string;

Pb, Ro

Содержит выражение для фильтра набора данных

property Filtered: Boolean;

Pb,

Ro

Управляет включением фильтра набора данных

TFilterOption = (foCaselnsensitive, foNoPartialCompare) ;

property FilterOptions: TFilterOptions;

Pb

Определяет параметры фильтра:

 foCaselnsensitive — строковые значения фильтруются без учета регистра;  foNoPartialCompare — при фильтрации символ "*" рассматривается как обычный символ, иначе он означает, что на этом месте может находиться произвольное подмножество любых символов

type HDBICur: Longint; property Handle: HDBICur;

Pu, Ro

Указатель на курсор ВОЕ, связанный с текущей записью набора данных

property KeySize: Word;

Pu, Ro

Содержит размер ключа для текущего индекса набора данных

type TLocale: Pointer; property Locale: TLocale;

Pu, Ro

Указатель на языковый драйвер ВОЕ

property RecNo: Longint;

Pu

Номер текущей записи набора данных

property RecordCount: Longint;

Ro

Содержит число записей в наборе данных

property RecordSize: Word;

Ro

Содержит размер одной записи набора данных

property UpdateObject: TDataSetUpdateObject;

Pu

Экземпляр объекта TUpdateObject, используемого при кэшировании изменений

type TUpdateRecordTypes = set of (rtModified, rtlnserted, rtDeleted, rtUnmodified) ;

property UpdateRecordTypes : TUpdateRecordTypes ;

PU 

Определяет видимость записей в режиме кэширования изменений в зависимости от их состояния:

 rtModified — доступны измененные записи;  rtinserted — доступны добавленные записи;  rtDeleted — доступны удаленные записи;  rtUnmodified — доступны немодифицированные записи

property UpdatesPending: Boolean;

Ro 

Значение True говорит о том, что буфер изменений при кэшировании содержит не сохраненные на сервере изменения

Методы

procedure ApplyUpdates;

Pu 

Записывает изменения из буфера в базу данных в режиме кэширования

function BookmarkValid (Bookmark : TBookmark): Boolean; overrider

Pu

 

Проверяет существование экземпляра закладки, передаваемого в параметре

Bookmark

procedure Cancel;

Pu 

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

procedure CancelUpdates;

Pu

Отменяет все изменения, сделанные с момента последней записи в базу данных и очищает буфер в режиме кэширования

procedure CommitUpdates;

Pu

Очищает буфер изменений в режиме кэширования

function CompareBookmarks (Bookmarkl, Bookmark2: TBookmark): Integer;

Pu 

Проверяет идентичность закладок, указанных в параметрах Bookmark1 и Bookmark2. При значении сигнализирует о наличии отличий в двух закладках

function ConstraintCallBack (Req: DsInfoReq; var ADataSources : DataSources) : DBIResult; stdcall;

Pu

Обеспечивает доступ к функциям ограничения данных API BDE

function ConstraintsDisabled: Boolean;

Pu

Показывает, включены или отключены ограничения данных

function CreateBlobStream ( Field : TField; Mode: TblobStreamMode) : TStream; override;

Pu

Создает поток для чтения/записи данных типа BLOB

procedure DisableConstraints;

Pu

Отключает ограничения данных

procedure EnableConstraints;

Pu

Включает ограничения данных

procedure FetchAll;

Pu

Переносит все изменения из буфера и восстанавливает все записи от текущей позиции до конца набора данных

procedure FlushBuffers;

Pu

Передает в базу данных все изменения из буфера записи

function GetBlobFieldData (FieldNo: Integer; var Buffer: TblobByteData): Integer; override;

Pu

Читает все данные BLOB из поля FieldNo В буфер Buffer

function GetCurrentRecord (Buffer : PChar) : Boolean

Pu

Помещает текущую строку в буфер Buffer

procedure Getlndexlnfo;

Pu

Обновляет информацию о текущем индексе набора данных

function IsSequenced: Boolean; override;

Pu

Определяет, поддерживает ли таблица БД нумерацию последовательности записей. В классе TDataSet всегда возвращает True, т. к. абстрактный набор данных свободен от конкретной реализации БД и всегда нумерует записи

function Locate (const KeyFields: string; const KeyValues : Variant; Options: TlocateOptions) : Boolean;

Pu

Осуществляет поиск в наборе данных. Параметр KeyFields содержит список полей, по которым ведется поиск. Параметр KeyValues содержит значения полей для поиска. Параметр Options определяет условия поиска. Если запись найдена, курсор набора данных устанавливается на эту запись и возвращается True (см. гл. 14)

function Lookup (const KeyFields: string; const KeyValues : Variant; const ResultFields: string): Variant;

Pu 

Осуществляет поиск в наборе данных. Возвращает массив значений требуемых полей найденной записи. Параметры аналогичны методу Locate (см. гл. 14)

procedure Post; override;

Pu

 

Пересылает сделанные в текущей записи изменения в базу данных

procedure RevertRecord;

Pu 

 

Отменяет все изменения в текущей строке при работающем буфере изменений

procedure Translate (Src, Dest : PChar; ToOem: Boolean); override;

Pu

 

Форматирует текст. Если параметр ToOem = True, текст Src в формате ANSI переводится в текст Dest в формате OEM и наоборот

function UpdateStatus: TUpdateStatus;

Возвращает тип сохраняемых в буфере изменений данных (см. табл. 16.1)

Методы-обработчики событий

TUpdateAction = (uaFail, uaAbort, uaSkip, uaRetry, uaApplied);

TUpdateErrorEvent = procedure (DataSet: TDataSet; E: EDatabaseError; UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction) of object;

property OnUpdateError: TUpdateErrorEvent;

Pu

 

Вызывается при возникновении ошибки переноса кэшированных в буфере изменений в таблицу базы данных

type TUpdateAction = (uaFail, uaAbort, uaSkip, uaRetry, uaApplied) ;

TUpdateRecordEvent = procedure ( DataSet : TDataSet ; UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction) of object;

property OnUpdateRecord : TUpdateRecordEvent ;

Pu

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

Применяется для организации дополнительного управления этим процессом, например для контроля какого-либо конкретного значения

 

Класс TDBDataSet


Класс TDBDataSet является непосредственным предком основных компонентов доступа к данным ттаblе, TQuery и TstoredProc. Новые свойства и методы класса обеспечивают соединение набора данных с базой данных и используют функции BDE (табл. 16.7).

В процессе соединения важнейшую роль играет свойство DatabaseName, которое должно содержать псевдоним или полный путь к файлам БД. Для управления отдельным соединением с базой данных можно применять специальный компонент TDatabase. Указатель на экземпляр такого компонента содержится в свойстве Database.

Многие функции API BDE используют в своей работе дескриптор специальной структуры, описывающей подключенную базу данных. Доступ к этому дескриптору можно получить через свойство DBHandie.

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

Для работы с удаленными серверами в класс введено свойство Provider, обеспечивающее доступ к интерфейсу iProvider.

Таблица 16.7. Свойства и методы класса TDBDataSet

Объявление

Тип

Описание

Свойства

property AutoRefresh: Boolean;

Pb

При значении True все автоматически создаваемые значения полей (автоинкрементные, значения по умолчанию) обновляются автоматически

property Database: TDatabase;

Pu, Ro

Указатель связанного с набором данных компонента TDatabase

property DatabaseName: string;

Pu, Pb

Псевдоним базы данных

type HDBISES: Longint; property DBHandie: HDBISES;

Pu, Ro

Дескриптор базы данных. Используется при работе с API BDE

type TLocale: Pointer; property DBLocale: TLocale;

Pu, Ro

Идентифицирует языковый драйвер API BDE

property DBSession: TSession

Pu, Ro

Указатель для компонента TSession, с которым работает набор данных

property Provider: IProvider;

Pu, Ro

Идентифицирует интерфейс IProvider

property SessionName: string;

Pu, Ro

 Содержит имя компонента сеанса, в котором работает набор данных

Методы

function CheckOpent Status: DBIResult): Boolean;

Pu

 Возвращает результат вызова BDE.  Используется для тестирования соединения

procedure CloseDatabase ( Database: TDatabase);

Pu

 Закрывает связь с базой данных,  определяемой параметром Database

procedure GetProviderAttributes (List: TList); override;

Pu

Возвращает в списке List параметры языкового драйвера

function OpenDatabase: TDatabase;

Pu

 Открывает связь с базой данных, определяемой свойством DatabaseName

 

Компонент TTable


Компонент Tтаblе инкапсулирует таблицу реляционной базы данных, причем независимо от типа базы данных. Для доступа к данным компонент использует функции BDE (см. выше).

Необходимая для работы база данных задается свойством DatabaseName, в котором можно указать зарегистрированный в BDE псевдоним БД или полный путь к файлам БД.

Таблица БД, на основе которой создается набор данных, определяется свойством TableName. При необходимости тип таблицы задается свойством TаblеТуре, хотя обычно это свойство имеет значение ttDefault (см. табл. 16.4), которое включает автоматическое определение типа таблицы по расширению файла.

 Примечание 

Свойство ТаblеТуре работает только в локальных БД. Обратите внимание, что возможные значения свойства соответствуют основным типам локальных драйверов BDE.

При помощи методов Open и close набор данных открывается и закрывается. О его состоянии можно судить по значению свойства Active. Более подробно о состоянии набора данных расскажет свойство state (см. ниже).

Записи в набор данных можно отбирать при помощи свойств Filter, Filtered, FilterOptions, создающих фильтр, ограничивающий набор данных по значениям данных в одном или нескольких полях.

Методы SetRangeStart, SetRangeEnd, SetRange, ApplyRange, EditRangeStart, EditRangeEnd создают специальный диапазон включаемых в набор данных записей, отбор в диапазон проводится по задаваемым граничным значениям любых полей набора данных.

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

От предков компонент унаследовал инструменты для работы с закладками. Это свойство Bookmark и методы GetBookmark, FreeBookmark, GotoBookmark.

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

Использование индексов обеспечено свойствами indexName, indexFieids, IndexFieldNames, IndexFiles.

Свойства MasterSource, MasterField, IndexName дают возможность установить отношение типа главный/подчиненный с другой таблицей.

Очень полезны в практическом использовании методы и свойства для работы С буфером изменений (свойства CachedUpdates, PendingUpdates, UpdateRecordTypes, МСТОДЫ ApplyUpdates, CancelUpdates, CommitUpdate, RevertRecord). Буфер применяется в клиентских приложениях многоуровневых систем доступа к данным.

От классов TDataSet и TBDEDataSet унаследован обширный набор методов-обработчиков событий, позволяющий решать любые задачи по управлению набором данных.

В табл. 16.8 приведена справочная информация о свойствах и методах компонента ттаble. После этого рассматриваются подробности применения основных механизмов набора данных.

Таблица 16.8. Свойства и методы класса Tтаblеl

Объявление

Тип

 Описание

Свойства

property DataSource: TDataSource;

Pu, Ro

Ссылается на компонент TDataSource главного набора данных в отношении  главный/подчиненный

property Defaultlndex: Boolean;

Pb

Управляет сортировкой данных. При значении True записи упорядочиваются по первичному ключу. При значении False упорядочивание не производится

property Exclusive: Boolean;

Pb

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

property Exists: Boolean;

Pu, Ro

Значение True говорит о том, что связанная с компонентом таблица базы данных существует

property IndexDef s: TindexDefs;

Pb

Содержит информацию об индексах таблицы

property IndexFieldCount: Integer;

Pu, Ro

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

property IndexFieldNames: string;

Pb

Разделенный запятыми список названий полей, составляющих текущий индекс. Используется для таблиц серверов SQL

property IndexFields: [Index: Integer] : TField;

Pu

Индексированный список полей текущего индекса

property IndexFiles: TStrings;

Pb

Список индексных файлов для таблиц dBASE

property IndexName: string;

Pb

Определяет вторичный индекс для таблицы. Используется для таблиц локальных СУБД

property KeyExclusive: Boolean;

Pu

Управляет границами диапазона, задаваемого методом SetRange. При значении True крайние записи в диапазон не включаются

property KeyFieldCount: Integer;

Pu

Содержит число полей ключа, используемых при поиске. При значении 0 применяется только первое поле, при значении 1 — два первых поля и т. д. По умолчанию устанавливается полное число полей ключа

property MasterFields: string;

 Pb

Список имен полей главной таблицы, разделенных запятой, используемых при создании отношения главный/подчиненный

property MasterSource: TDataSource;

Pb

Содержит имя компонента TDataSource, связанного с набором данных, который является главным в отношении главный/подчиненный

property Readonly: Boolean;

Pb

Включает и отключает режим "только для чтения". В некоторых случаях набор данных можно открыть только в этом режиме

property StoreDef s: Boolean;

Pb

При значении True все сведения об индексах и структуре таблицы хранятся вместе с формой или модулем данных. В этом случае при создании набора данных одновременно создаются поля, индексы, ограничения

property TableLevel: Integer;

Pu

Содержит значение уровня таблицы, используемого в драйвере ВОЕ

property TableName: TFileName;

Pb

Определяет имя таблицы

type TTableType = (ttDefault, ttParadox, ttDBase, ttASCII, ttFoxPro) ;

property TableType: TTableType;

Pb

Определяет тип таблицы для стандартного драйвера ВОЕ. Значение ttDefault означает, что тип таблицы определяется по расширению файла

Методы

procedure Addlndex (const Name, Fields: string; Options: TIndexOptions) ;

Pu

Создает новый индекс. Параметр Name определяет имя нового индекса, параметр Fields — список полей индекса через запятую, параметр Options задает тип индекса

procedure ApplyRange;

Pu

Включает в работу границы диапазона, заданные методами SetRangeStart, SetRangeEnd или EditRangeStart, EditRangeEnd

type TBatchMode = (batAppend, batUpdate, batAppendUpdate , batDelete, batCopy) ;

function BatchMove (ASource: TBDEDataSet; AMode : TBatchMode) : Longint;

Pu

Переносит записи из таблицы ASource в набор данных. Тип операции задается параметром AMode. Возвращает число обработанных записей

procedure CancelRange;

procedure CloselndexFile (const  IndexFileName: string) ; 

Pu Pu 

Удаляет текущий диапазон

Закрывает индексный файл для таблиц dBASE

procedure CreateTable;

Pu

Создает новую таблицу, основываясь на данных о структуре таблицы, содержащихся в свойствах FieldDef s и indexDef s. Если свойство FieldDef s пустое, используется свойство Fields. Структура и данные существующей таблицы перезаписываются

procedure Deletelndex (const  Name: string); 

Pu

Удаляет вторичный индекс

procedure DeleteTable; 

Pu

Уничтожает таблицу базы данных. Набор данных при этом должен быть закрыт

procedure EditKey; 

Pu

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

procedure EditRangeEnd; 

Pu

Разрешает редактирование нижней границы диапазона

procedure EditRangeStart; 

Pu

Разрешает редактирование верхней границы диапазона

procedure EmptyTable; 

Pu

Удаляет все записи из набора данных

function FindKey (const  KeyValues: array of  const) : Boolean; 

 

Pu

Проводит поиск записи, значения полей которой удовлетворяют условиям, заданным параметром KeyValues. Значения разделяются запятыми. Для поиска можно использовать только поля, входящие в текущий индекс. Для локальных стандартных таблиц BDE это поля, определяемые свойством indexName. Для таблиц серверов SQL индекс можно задать свойством indexFieldNames. При успешном поиске функция возвращает значение True

procedure FindNearest (const KeyValues: array of  const);

 

Pu

Проводит поиск записи, значения полей которой, заданные параметром KeyValues, в минимальной степени отличаются от требуемых в большую сторону. Значения для поиска разделяются запятыми. Для поиска можно использовать толькополя, входящие в текущий индекс. Для  локальных стандартных таблиц ВОЕ  это поля, определяемые свойствомIndexName. Для таблиц серверов SQL индекс можно задать свойством indexFieldNames. При успешном поиске  функция возвращает True

procedure GetlndexNames (List : TStrings) ;

Pu

 Возвращает список индексов таблицы

procedure GotoCurrent (Table: TTable) ;

Pu

Синхронизирует курсор набора данных с курсором таблицы, заданной параметром Table

function GotoKey: Boolean;

Pu

Устанавливает курсор на запись, соответствующую значениям полей, заданным  при последнем применении метода

SetKey или EditKey

procedure GotoNearest;

Pu

Устанавливает курсор на запись, точно соответствующую значениям полей,  заданным при последнем применении метода SetKey или EditKey, или следующую ближайшую к ним по значениям

type TLockType = (ItReadLock, ItWriteLock) ; procedure LockTable ( LockType : TLockType) ;

Pu

Закрывает доступ к таблице Paradox или dBASE из других приложений

procedure OpenlndexFile (const IndexFileName: string);

Pu

Открывает индексный файл таблицы dBASE

procedure RenameTable (const NewTableName: string);

Pu

Переименовывает таблицу Paradox или dBASE

procedure SetKey;

Pu

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

procedure SetRange (const StartValues, EndValues:

array of const) ;

 

Pu

Задает диапазон отбора записей. Параметр StartValues определяет значения полей для верхней границы диапазона.

Параметр EndValues определяет значения полей для нижней границы диапазона. Значения диапазона задаются для полей текущего индекса

 procedure SetRangeEnd;

Pu

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

procedure SetRangeStart;

Pu

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

type TLockType = (ItReadLock, ItWriteLock) ; procedure UnlockTable (LockType : TLockType) ;

Pu

Разблокирует таблицу Paradox или dBASE для доступа из других приложений

 

Компонент TQuery


Компонент TQuery реализует все основные функции стандартного компонента запроса, описанные в гл. 12. Прямым предком компонента является класс TDBDataSet.

Для подключения к базе данных используется свойство DatabaseName, в котором задается псевдоним BDE или путь к базе данных.

Текст запроса определяется свойством SQL, для задания которого применяется простой редактор, открывающийся при щелчке на кнопке свойства в Инспекторе объектов (рис. 16.6).

Для управления текстом запроса во время выполнения приложения можно использовать возможности класса TStrings.

Основные свойства и методы компонента TQuery представлены в табл. 16.9.

Таблица 16.9. Свойства и методы компонента TQuery

Объявление

Тип

Описание

Свойства

property Constrained: Boolean;

Pb

При значении True запрещает внесение в набор данных таких значений, которые не соответствуют условиям отбора запроса. Применимо для локальных БД

property DataSource: TDataSource;

Pb

Ссылается на компонент TDataSource, из набора данных которого задаются значения параметров

property Local: Boolean;

Ro

Значение True означает, что запрос обращается к локальной таблице

property ParamCheck: Boolean;

Pb

При значении True параметры запроса обновляются при изменении свойства SQL во время выполнения

property ParamCount: Word;

Ro

Возвращает число параметров в запросе

property Params [Index : Word]TParams;

Pb

Индексированный список объектов TParams, каждый из которых соответствует одному параметру запроса

property Prepared: Boolean

Pu

Возвращает результат выполнения операции подготовки запроса к выполнению

property RequestLive: Boolean;

Pu

При значении False результат запроса нельзя редактировать, независимо от того, редактируемый результат или нет. При значении True результат запроса можно редактировать, но только если он "живой"

property RowsAffected: Integer;

Ro

 

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

property SQL: TStrings;

Pb

Содержит текст запроса

property SQLBinary: PChar;

Pu

Внутреннее свойство для обеспечения работы с ВОЕ

property StmtHandle: HDBIStmt;

Ro

Возвращает экземпляр объекта, соответствующего запросу в BDE. Используется при прямом вызове функций BDE

property Text: PChar;

Ro

Указатель на символьный массив, содержащий передаваемый в BDE текст запроса

property UniDirectional: Boolean;

Pb

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

Методы

procedure ExecSQL;

Pu

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

procedure GetDetailLinkFields (MasterFields, DetailFields: TList) ; override;

Pu

Заполняет списки параметров метода экземплярами объектов полей двух таблиц запроса, находящихся в отношении "один-ко-многим"

function ParamByName (const Value: string) : TParam;

Pu

Возвращает ссылку на экземпляр объекта параметра с именем, переданным в параметре Value

procedure Prepare;

PU

Готовит запрос к выполнению

procedure UnPrepare;

Pu

Освобождает ресурсы, занятые при подготовке запроса к выполнению

 

Рис 16.6. Редактор свойства SQL компонента TQuery

 

Компонент TStoredProc


Компонент TStoredProc обеспечивает использование в приложениях BDE хранимых процедур. Прямым предком компонента является класс TDBDataSet. Поэтому результатом выполнения хранимой процедуры может быть не только одиночный результат, но и полноценный набор данных.

Основные функции компонента TStoredProc соответствуют возможностям стандартного компонента хранимой процедуры, описанного в гл. 12. Свойства и методы компонента TStoredProc представлены в табл. 16.10.

Средствами классов-предков выполняется и подключение компонента к базе данных. Свойство DatabaseName определяет базу данных.

Свойство storedProcName задает имя хранимой процедуры.

Перед выполнением хранимую процедуру необходимо подготовить. В частности, на этом этапе осуществляется передача параметров и выделение ресурсов. Эта операция выполняется автоматически при использовании методов ЕхесРгос и Open, или задается явно методом Prepare.

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

Таблица 16.10. Свойства и методы компонента TstoredProc

Объявление

Тип

Описание

Свойства

property Overload: Word;

Pb

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

type TParamBindMode = (pbByName, pbByNumber) ;

property ParamBindMode: TParamBindMode ;

Pb

Определяет порядок присваивания значений параметров:

pbByName — по именам параметров;  pbByNumber — по номерам параметров в списке свойства Params

property ParamCount: Word;

Ro

Возвращает общее число параметров

property Params: TParams;

Pb

Индексированный список параметров

property Prepared: Boolean;

Pu

Возвращает значение True, если подготовка процедуры уже проводилась

property StmtHandle: HDBIStmt;

Ro

Дескриптор выражения ВОЕ. Используется при прямом вызове функций BDE

property StoredProcName: string;

Pb

Содержит имя хранимой процедуры

Методы

procedure CopyParams (Value : TParams) ;

Pu

Копирует параметры из списка Value

function DescriptionsAvailable : Boolean;

Pu

При значении True параметры хранимой процедуры доступны из приложения

procedure ExecProc;

Pu

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

procedure GetResults;

PU 

 

Возвращает выходные параметры в приложение (используется только для сервера Sybase)

function Pa ramByName (const Value: string) : TParam;

Рu

Возвращает параметр с именем Value

procedure Prepare;

Pu 

Готовит процедуру к выполнению

procedure UnPrepare;

Рu

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

 

Процессор баз данных Borland Database




Процессор баз данных Borland Database Engine 5 реализует стандартные функции доступа к данным и является ПО промежуточного слоя между приложением и базой данных. При помощи системы драйверов и псевдонимов BDE обеспечивает универсальный способ доступа к данным. Специальный набор компонентов доступа к данным Delphi использует BDE. Но при необходимости разработчик может применять функции API BDE напрямую.