Вячеслав Понамарев
(САМОУЧИТЕЛЬ) БАЗЫ ДАННЫХ
в DELPHI 7 •
С&ППТЕР* Москва • Санкт-Петербург • Нижний Новгород • Воронеж Ростов-на-Дону • Екатеринбург • Самара Киев • Харьков • Минск
2003
ББК 32.973.233-018я7 УДК 681.324.06(075)
П56
. |
П56 Базы данных в Delphi 7. Самоучитель / В По-аивэш. — I ~f Питер, 2003. —224с.: ил. ISBN 5-314-00194-2 Среди разработчиков программ для Window быстрой разработки приложений Delphi. Эта костью использования В этой книге урок за уросоч Демонстрируются широкие возможности по создали»: о большом наборе стандартных компонентов, с по: достаточно высокого уровня сложности. Самоучитель предназначен для читателей, знаьсчиыг : программирования и уже имеющих опыт написания
пользуется среда <г:той освоения и лег~~i с базами данных. :~гля и рассказывается издавать приложения тыаг - .-ориентированного v^.t Delphi. . 32.973.233-018Я7 •ЛК 681.324.06(075)
Информация, содержащаяся в данной книге, получена из менее, имея в виду возможные человеческие или технические точность и полноту приводимых сведений и не несет ответственное-* -J ISBN
5-314-00194-2
i надежные. Тем не --иоовать абсолютную : ^пользованием книги.
дом «Питер», 2003
Краткое содержание Введение
10
Занятие 1. Основные понятия и определения
12
Занятие 2. Проектирование баз данных
24
Занятие 3. Средства Delphi 7 для доступа к данным
34
Занятие 4. Средства для работы с базами данных
51
Занятие 5. Палитра компонентов и работа с базами данных
76
Занятие 6. Модификация данных и связанные таблицы Занятие 7. Отчеты в Delphi 7
105 Ill
Занятие 8. Создание простых баз данных
143
Занятие 9. Построение клиент-серверных баз данных
158
Занятие 10. Сервер InterBase
168
Занятие 11. Основы языка SQL
178
Занятие 12. Технология ADO
193
Приложение. Коды ошибок Borland Database Engine
205
Литература
219
Содержание Введение
10
Кому адресована эта книга Соглашения, принятые в книге Благодарности От издательства
10 10 11 11
Занятие 1. Основные понятия и определения _—,
12
Что такое база данных _ Типы баз данных Взаимосвязи данных Основные типы баз данных Форматы таблиц баз данных Локальные и клиент-серверные приложения баз зяя -шп _ Что нового мы узнали?
12 13 13 13 16 19 23
Занятие 2. Проектирование баз данных ___.. Ключи и индексы Взаимосвязи данных Нормализация модели базы данных Автоматизация разработки приложений Что нового мы узнали?
24 24 26 28 32 33
_ _ _
Занятие 3. Средства Delphi 7 для доступа к данным Новые возможности Delphi 7 по работе с базами тршяикт _ Наборы данных _ Общие свойства компонентов Table и Query _ Состояния наборов данных _ Режимы наборов данных Работа с полями наборов данных Набор данных Table .j. _ Набор данных Query
34
1
34 36 37 39 40 41 45 47
Содержание
Источник данных Что нового мы узнали?
48 50
Занятие 4. Средства для работы с базами данных
51
Borland Database Engine, архитектура BDE Настройка BDE Программа BDE Administrator Параметры драйверов и конфигураций Программа Database Desktop Работа с псевдонимами баз данных Работа с псевдонимами в BDE Administrator Работа с псевдонимами в Database Desktop Программа Data Pump Архитектура dbExpress Что нового мы узнали?
51 54 54 57 65 69 69 71 71 74 75
Занятие 5. Палитра компонентов и работа с базами данных
76
Компоненты для работы с локальными базами данных Операции с таблицами Сортировка набора данных Перемещение по набору данных Фильтры Поиск Что нового мы узнали?
76 89 92 93 99 102 104
-
Занятие 6. Модификация данных и связанные таблицы
105
Редактирование, добавление и удаление данных Редактирование набора данных Добавление записей Удаление записей Работа со связанными таблицами Что нового мы узнали?
105 106 108 109 110 110
Занятие 7. Отчеты в Delphi 7
Ill
Конструктор отчетоэ Rave Reports Визуальный дизайнер Rave Reports Область навигации. Панели инструментов Область навигации. Панель компонентов Структура приложения, использующего Rave Reports Компоненты страницы отчета Компоненты управления отчетом
1-11 112 115 116 119 120 126
Содержание
Конструктор отчетов Quick Report Что нового мы узнали?
137 142
Занятие 8. Создание простых баз данных
.....143
Ваша первая локальная база данных Что нового мы узнали?
143 157
Занятие 9. Построение клиент-серверных баз данных Основы технологии «клиент-сервер» Использование хранимых процедур Язык хранимых процедур и триггеров Использование триггеров Генераторы Работа с транзакциями Что нового мы узнали?
_
Занятие 10. Сервер InterBase
158 158 160 161 163 164 165 167
168
Что нового в InterBase 6.5 Организация данных Настройка InterBase-сервера Графический интерфейс программы IBConsole Регистрация локального сервера InterBase Соединение с базой данных из приложения Что нового мы узнали?
168 169 170 171 172 174 177
Занятие 11. Основы языка SQL
178
Основные сведения о языке SQL Функции языка SQL Операторы определения данных Операторы манипулирования данными Навигатор SQL Explorer Отладчик SQL Monitor Конструктор запросов SQL Builder Что нового мы узнали?
178 180 180 182 185 188 190 192
Глава 12. Технология ADO Обзор ADO Компоненты ADO в Delphi 7
_
193 193 195
Содержание События в ADO Асинхронная работа с сервером Асинхронное соединение Асинхронное выполнение команды Асинхронная выборка данных Создание простейшего приложения, использующего ADO Что нового мы узнали?
200 201 201 202 202 202 204
Приложение. Коды ошибок Borland Database Engine
205
Литература
219 •
'
• • „
. -
•
.
Введение Среди разработчиков программных продуктов под Windows в России особой популярностью пользуется среда быстрой разработки приложений Delphi. Эта популярность завоевана прежде всего ее простотой, легкостью в изучении и использовании. Среда Delphi позволяет разрабатывать как обычные приложения, так и приложения для работы с базами данных. Delphi предоставляет программисту широкие возможности создания интерфейса пользователя, а также большой набор стандартных компонентов, с помощью которых можно создавать приложения достаточно высокого уровня сложности. Среда Delphi обладает практически всеми возможностями современных систем управления базами данных. Она имеет встроенную поддержку языка структурированных запросов (SQL). С помощью Delphi можно разрабатывать как локальные, так и удаленные базы данных. Все примеры данной книги были опробованы в версии Delphi 7 Enterprise. Предполагается, что при изучении данной книги читатель будет иметь доступ к установленной на компьютер седьмой версии Delphi. Рекомендуется изучать книгу, одновременно отрабатывая все примеры на компьютере.
Кому адресована эта книга Данная книга предназначена тем, кто знаком с основами объектно-ориентированного программирования. Надеюсь, что читатель знаком с работой в Delphi и уже имеет опыт написания простых программ в этой среде. Книга написана таким образом, чтобы читателю не пришлось пользоваться дополнительной литературой. Однако многие вопросы остались вне рассмотрения, поэтому в книге приведен список рекомендуемой литературы, из которой можно почерпнуть вспомогательные сведения, если они потребуются. Большая просьба к читателям сообщить свое мнение о книге автору. Я буду благодарен за информацию обо всех ошибках, которые, возможно, имеются в данном издании. Просьба писать на следующий электронный адрес:
[email protected].
Соглашения, принятые в книге В книге были использованы следующие типографские соглашения: • листинги, идентификаторы, имена функций, классов, переменных, команд выделены моноширинным шрифтом;
От издательства
11
курсивом выделены новые термины, которые впервые встречаются в тексте книги, а также ключевые понятия; специальным шрифтом выделены имена элементов интерфейса: окон, пунктов меню, вкладок и т. д.; важные моменты, на которые стоит обратить внимание, оформлены как примечания и советы.
Благодарности Выражаю благодарность всем, без чьего содействия данная книга не была бы написана Благодарю весь коллектив издательства «Питер» за поддержку и понимание.
От издательства Ваши замечания, предложения, вопросы отправляйте по адресу электронной почты
[email protected] (издательство «Питер», компьютерная редакция). Мы будем рады узнать ваше мнение! На веб-сайте издательства http://www.piter.com вы найдете подробную информацию о наших книгах. . *
-
, • . . .
>
_ - ~ .. .
'
• '
. .
.
•
Занятие 1 Основные понятия и определения • • • • •
Что такое база данных Типы баз данных Форматы таблиц баз данных Локальные и клиент-серверные приложения баз данных
В материалах этой главы вы найдете сведения, необходимые каждому начинающему программисту, который хочет научиться создавать приложения для работы с базами данных. Вы узнаете, что такое базы данных, из чего они обычно состоят, для чего используются. Кроме того, в материале этого занятия рассказывается об основных типах баз данных, рассматриваются различия и условия применения тех или иных типов баз данных.
Что такое база данных Множество фирм и компаний всего мира используют компьютеры для хранения и обработки служебной информации. Эта информация содержится в так называемых базах данных. База данных — это хранилище для большого количества систематизированных данных, с которыми можно производить определенные действия (добавление, удаление, изменение, копирование, упорядочивание и т. д.). Все данные, находящиеся в базе данных, можно представить в виде записей или объектов. Для успешной работы с базами данных нужны программные средства, которые обеспечивали бы доступ к нужной информации, внесение каких-либо изменений в базу данных и другие действия с данными. Для решения этой задачи используются системы управления базами данных. Система управления базами данных (СУБД) — это совокупность языковых и программных средств, обеспечивающих создание, использование и ведение базы данных.
Типы баз данных
13
Все СУБД делятся на две группы: • локальные; • сетевые. Локальные — это СУБД, работающие на одном компьютере. К ним относятся dBase, FoxPro, Microsoft Access и т. д. Сетевые — это СУБД, позволяющие нескольким компьютерам использовать одну и ту же базу данных с помощью технологии клиент-сервер. Примерами сетевых СУБД являются InterBase, Oracle, Microsoft SQL Server и т. д. О локальных и сетевых СУБД подробнее будет рассказано ниже. •
Типы баз данных
•
•
Прежде чем рассматривать основные типы баз данных, нужно отметить, что все данные, помещенные в базу данных, каким-либо образом связаны между собой.
Взаимосвязи данных Взаимосвязи данных могут быть одного из четырех типов: • один к одному; • один ко многим; • много к одному; . • много ко многим. Давайте рассмотрим принципы построения таких взаимосвязей. Вид взаимосвязи один к одному подразумевает, что каждая запись одного объекта базы данных будет указывать на единственную запись другого объекта. Например, с одним клиентом может быть связан только один заказ. Взаимосвязь один ко многим означает, что одной записи объекта базы данных будет соответствовать несколько записей других объектов. Например, один клиент может иметь несколько квартир. Тогда с записью клиента будут связаны записи о его квартирах. Вид взаимосвязи много к одному равносилен рассмотренному выше виду «один ко многим» и отличается от него только направлением. Последний вид взаимосвязи много ко многим устанавливается между двумя типами объектов базы данных. Например, когда у одного банкира может быть несколько клиентов и, одновременно, один клиент может пользоваться услугами нескольких банков. •
Основные типы баз данных
По принципу хранения данных все базы данных разделяются на несколько основных типов: иерархические;
i *
f
14
Занятие 1. Основные понятия и определения
• сетевые; • реляционные. ,
Иерархические базы данных Иерархические базы данных применялись в начале 60-х годов. Они построены в виде обычного дерева. Данные здесь делятся на две категории: главные и подчиненные. Таким образом, один тип объекта является главным, а остальные, находящиеся на более низких ступенях иерархии, — подчиненными (рис. 1.1).
Рис. 1.1. Схема базы данных иерархического типа Наивысший в иерархии объект называется корневым, остальные объекты носят название зависимых объектов. База данных, организованная по иерархическому принципу, удобна для работы с информацией, которая соответствующим образом упорядочена. В остальных случаях работа с такой моделью будет достаточно сложной. Сетевые базы данных Сетевые базы данных начали применяться практически одновременно с иерархическими. В этих базах данных любой объект может быть как главным, так и подчиненным (рис. 1.2). .
Рис. 1.2. Схема базы данных сетевого типа
Типы баз данных
15
Таким образом, в сетевой модели базы данных каждый объект может иметь сколько угодно связей с другими объектами. Из-за сложности представления данных в таком виде от сетевой модели базы данных в большинстве случаев также пришлось отказаться. Реляционные базы данных Именно реляционные базы данных (от англ, relation — отношение) стали широко использоваться в программировании начиная с 70-х годов. В таких базах данных объекты и взаимосвязи между ними представляются в виде прямоугольных таблиц, состоящих из строк и столбцов (рис. 1.3).
Рис. 1.3. Схема реляционной базы данных
Каждая таблица здесь представляет собой объект базы данных. Такую базу данных легче всего можно реализовать на компьютере. В дальнейшем мы будем рассматривать именно реляционные базы данных. Итак, таблицы, которые составляют базу данных, находятся на магнитном диске в отдельной папке. Папка в целом является базой данных, а входящие в нее таблицы хранятся в виде отдельных файлов. С этими файлами можно производить произвольные операции, которые допускаются операционной системой. Большинство приложений Windows при попытке обращения к одному файлу сразу несколькими приложениями выдают сообщение об ошибке совместного доступа. Для таблиц базы данных такое ограничение крайне неудобно, поэтому им свойственна особенность, которая заключается в том, что несколько приложений могут получить доступ к файлу таблицы одновременно. Такой режим доступа называется многопользовательским. Если внимательно посмотреть на файлы таблиц базы данных, то можно заметить, что для одной таблицы обычно создается несколько файлов. Это файлы, которые содержат дополнительную информацию, относящуюся к таблице. Объединяет эти файлы одинаковое имя, но при этом они имеют разные расширения. Имя файлов таблицы определяет имя самой таблицы. Рассмотрим теперь, из чего состоят таблицы базы данных. Как уже упоминалось, в каждой из них структурно выделяются строки и столбцы (рис. 1.4). Столбцы таблицы обычно называют полями, а строки — записями. К полям таблицы предъявляются следующие требования: • поле должно иметь уникальное имя в пределах одной таблицы; • поле должно содержать данные только одного заранее определенного типа; • любая таблица должна иметь как минимум одно поле.
16
Занятие 1. Основные понятия и определения
Записи
Поля Рис. 1.4. Структура таблицы базы данных
С таблицами реляционной базы данных можно выполнять следующие действия: • создавать таблицу или определять ее структуру; • изменять структуру таблицы; • изменять имя таблицы; • удалять таблицу с диска. ВНИМАНИЕ При переименовании таблицы помните, что имя таблицы можно изменить только с помощью специальных программ, например Database Desktop. Простое изменение имени файла таблицы с помощью проводника Windows не приведет к переименованию таблицы.
Форматы таблиц баз данных Давайте рассмотрим несколько форматов таблиц баз данных, поддерживаемых средой Delphi. Следует заметить, что Delphi не имеет своего собственного формата таблиц, но содержит средства, позволяющие работать со многими внешними форматами. К числу серверных таблиц баз данных, поддерживаемых Deiphi, относятся: • DB2; •» f * т Informix; . • InterBase; ' • 'Microsoft SQL Server; • •~ • Oracle; ,;-. • Sybase. В число локальных таблиц баз данных, поддерживаемых средой Delphi, входят: • Microsoft Access; • dBase; • FoxPro; • Paradox. Наиболее часто используемыми из локальных баз данных являются dBase и Paradox. У каждой из них есть свои особенности, которые мы и рассмотрим.
Форматы таблиц баз данных
17
Базы данных dBase были первыми базами данных для персональных компьютеров. Они поддерживаются большинством сред программирования для разработки приложений баз данных. Таблицы, входящие в состав базы данных dBase, являются простыми и используют мало файлов. В таблице 1.1 перечислены основные расширения файлов таблиц dBase и их назначение. Таблица 1.1. Файлы таблиц dBase Расширение файла
Содержание файла Непосредственно данные таблицы
*.dbf *.dbt
Большие двоичные данные (BLOB, Binary Large Object). В их число входят двоичные данные, memo-поля и OLE-поля Индексы, которые поддерживаются средствами dBase
*.mdx
Не поддерживаемые индексы. Такие индексы должны обрабатываться программно
*.ndx
Поля в таблице базы данных dBase должны удовлетворять следующим условиям: • имя поля может состоять из букв и цифр, но начинаться — с буквы; • не допускается включение в имя поля специальных символов и пробелов; • максимальное количество символов в имени поля — 10. В таблице 1.2 перечислены основные типы полей таблиц dBase, указаны их обоТаблица 1.2. Основные типы полей таблиц dBase Тип поля Binary
Обозначение в Database Desktop
Описание
В
Двоичные значения в виде последовательности байтов, хранящейся в файле с расширением *.dbt. Длина не ограничена Символьная строка. Длина ограничена 255 символами Значение даты Число с плавающей запятой в диапазоне от -10308 до 10308. Точность представления — 15 знаков после десятичной точки Булевская (логическая) переменная. Может принимать одно из двух значений: true (истина) или false (ложь) Неограниченная последовательность символов, хранящихся в файле с расширением *.dbt Двоично-десятичный формат представления чисел Данные, поддерживаемые технологией связывания и внедрения объектов OLE (Object Linking and Embedding)
' Character Date Float
F
Logical
• L
Memo
M
Number
N О
OLE
С
Преимуществом баз данных dBase является поддержка их многими средами программирования. К недостаткам относятся отсутствие контроля целостности связей и отсутствие защиты данных. Рассмотрим теперь базы данных Paradox. Они являются более развитыми по сравнению с dBase. Таблицы Paradox содержат достаточно большое число типов полей, поддерживают целостность ссылок, автоматически проверяют вводимые данные на совместимость по типу и поддерживают парольную защиту данных.
Занятие 1. Основные понятия и определения
18
Основные расширения таблиц базы данных Paradox перечислены в табл. 1.3. Таблица 1.3. Файлы таблиц Paradox Расширение файла
Содержание файла
*.db *.mb *.px
Данные таблицы Большие двоичные данные (BLOB, Binary Large Object) Ключ (главный индекс)
*.xg* и *.yg* *.val *.tv и *.fam *.net
Индексы Параметры для проверки типов вводимых данных и целостности ссылок Форматы вывода таблицы в приложении Database Desktop Применяется для контроля доступа к таблице по сети
Поля в таблице Paradox должны удовлетворять следующим требованиям: • имя поля может состоять из букв (включая символы кириллицы) и цифр, но начинаться должно обязательно с буквы; • в имени поля допускается использовать символы пробела, *, $ и другие специальные символы; • не рекомендуется (хотя и не запрещается) использовать в имени поля символы точки, восклицательного знака и |, так как они зарезервированы средой Delphi; • максимальная длина имени поля составляет 25 символов; ,, ,, • ключевые поля таблицы должны быть первыми в ее структуре. СОВЕТ Если вы хотите обеспечить совместимость данных таблицы Paradox с таблицами других форматов (например, dBase), именуйте поля со следующими ограничениями: длина имени поля не должна быть более 10 символов, имя должно состоять только из латинских букв и цифр.
Таблица 1.4 содержит список полей, которые поддерживаются базой данных Paradox, а также их краткое описание. Таблица 1.4. Основные типы полей таблиц Paradox Тип поля
Обозначение в Database Desktop
Описание
Alpha Autoincrement
А +
BCD Binary
# В
Bytes Date
Y D
Символьная строка, ограниченная 255 символами Поле, автоматически увеличивающее значение новой записи. Обычно используется для ключевого поля Двоично-десятичная форма представления числа Двоичное значение в виде последовательности байтов. Длина не ограничена. Первые 240 байтов хранятся в файле таблицы, остальные — в файле с расширением *.mb Последовательность байтов длиной до 255 Значение даты. Значения от 01.01.9999 до н. э. до 31.12.9999 Неограниченная последовательность форматированных символов
Formatted Memo F
Локальные и клиент-серверные приложения баз данных Тип поля
Обозначение в Database Desktop
L I
Memo
M
Целочисленное поле. Диапазон возможных значений от -2 147 483 648 до 2 147 483 647
-
Money
$
Number
OLE
'
0
Описание Графическое изображение в одном из форматов: *.bmp, *.eps, *.gif, *.pcx, *.tif. После загрузки в поле таблицы изображение преобразуется в формат *.bmp. Значение поля данного типа хранится в файле с расширением *.mb Булево значение: true или false
Graphic
Logical Longlnteger
19
•
Неограниченная последовательность символов. Первые 240 символов хранятся в файле таблицы, остальные — в файле с расширением *.mb Хранит денежные величины. Отличается от типа Number тем, что отображает денежный знак. Символ знака зависит от настроек операционной системы Число с плавающей запятой. Может принимать значения от -10307 до 10308. Точность —15 знаков после запятой Хранит данные, поддерживаемые технологией OLE. Значения содержатся в файле с расширением *.mb
Short
Целое число. Может принимать значения от -32 768 до 32 767
Time TimeStamp
Содержит значения времени Содержит значения даты и времени
Локальные и клиент-серверные приложения баз данных Приложение, созданное с помощью Delphi, осуществляет доступ к базе данных через специальный процессор баз данных, который называется BDE (Borland Database Engine). BDE— это набор драйверов и динамически присоединяемых библиотек (файлов *.<Ш), /> которые t- обеспечивают доступ j к данным. Если вы используете в своих приложениях BDE, то нужно обеспечить его установку на все компьютеры, на которых будут работать ваши приложения. Процессор баз данных BDE позволяет наиболее эффективно работать с таблицами баз данных типа dBase и Paradox. Все базы данных можно условно разделить на две большие группы в зависимости от взаимного расположения приложения и таблиц базы данных: : • локальные; • клиент-серверные. Локальные — это базы данных, таблицы которых расположены на том же компьютере, что и работающие с ними приложения. В таком случае говорят, что база данных имеет локальную архитектуру (рис. 1.5).
20
Занятие 1. Основные понятия и определения
Приложение
ВОЕ
Таблицы базы данных
Компьютер Рис. 1.5. Локальная архитектура базы данных
Приложения, которые работают с локальными базами данных, называются одноярусными (single-tiered applications), так как и приложение и база данных расположены на одном и том же компьютере (ярусе). Кроме представленной выше организации локальной базы данных возможно осуществление многопользовательского доступа к данным таблиц. Такой вариант предусматривает наличие сети компьютеров с сервером. Данный способ организации базы данных называется файл-сервером (рис. 1.6).
f
•>
вг IP
f
-\
/ч
Копия базы данных
Компьютер 1 ч .>
Таблица базы данных
:
'
Се•рвер
>f ^
V
дг с
f
S
Копия базы данных
Компьютер п Рис. 1.6. Файл-серверная архитектура базы данных
Как вы можете видеть, на каждом из компьютеров-клиентов сети создается локальная копия базы данных сервера. Эта копия периодически обновляется. Такая архитектура построения базы данных используется в сетях с малым количеством пользователей. Разработка приложения для работы с таким типом базы данных практически не отличается от создания обычного приложения для локальной базы данных. К числу недостатков данной архитектуры можно отнести: • создание копий базы данных и работа с ними на отдельных компьютерах обусловливает необходимость периодического обновления всей базы данных. Это повышает сетевой трафик (нагрузку сети) и ведет к снижению быстродействия всей системы; • при изменении данных, сделанном одним пользователем, они не сразу передаются в локальные копии базы данных других пользователей, поэтому любой пользователь может видеть уже устаревшую информацию;
Локальные и клиент-серверные приложения баз данных
21
• необходима синхронизация работы пользователей. Она должна заключаться во временном блокировании записей, с которыми работает пользователь, для других пользователей. Таким образом, оказывается невозможным одновременный доступ к одной и той же записи с нескольких компьютеров; • существуют трудности организации контроля доступа к данным, идентификации пользователя и поддержки целостности данных. От всех этих сложностей избавлены клиент-серверные базы данных. Клиент-серверные базы данных (удаленные базы данных) — это базы данных, в которых таблицы расположены на сервере сети, а приложения для работы с этими таблицами находятся на пользовательских компьютерах (клиентах), подключенных к серверу. В данном случае говорят, что база данных имеет архитектуру «клиент-сервер». Клиент-серверные базы данных работают с помощью запросов на языке SQL (Structured Query Language). SQL-запросы применяются для любых операций с таблицами базы данных, расположенной на сервере. В клиент-серверных приложениях баз данных вся информационная система делится на две разнородные части: • клиент базы данных; • сервер базы данных. Клиент базы данных — это приложение пользователя, которое обеспечивает формирование и передачу запросов серверу, а также отображение полученных результатов. Кроме того, приложение-клиент должно обеспечивать интерфейс пользователя базы данных. Сервер базы данных — специальная программа, которая управляет удаленной базой данных и обеспечивает выполнение запросов клиентов и выдачу результатов запросов. Приложения, работающие с клиент-серверными базами данных, называются двухъярусными (рис. 1.7) или многоярусными (рис. 1.8) приложениями (two-tiered и multi-tiered applications). .
•
Компьютер 1 >
Сервер базы данных А
--
Таблица базы данных
Удапенный сервер • i •
Компьютер п Рис. 1.7. Двухъярусная архитектура «клиент-сервер»
22
Занятие 1. Основные понятия и определения
При использовании двухъярусной архитектуры любой клиент посылает серверу SQL-запрос на предоставление данных из таблиц. Сервер обрабатывает этот запрос и возвращает клиенту только те данные, которые были определены запросом. Очевидны следующие преимущества такой архитектуры: • передача только востребованной информации, а не всей базы данных, что приводит к снижению трафика сети; • обеспечение безопасности данных и возможности установки прав доступа к информации для отдельных групп пользователей, связанные с тем, что работа с данными осуществляется одной программой — сервером базы данных; • упрощение клиентских приложений за счет сокращения кода, необходимого для обработки данных и обеспечения доступа к ним. Несмотря на указанные достоинства, следует заметить, что обслуживание сервера и самой базы данных требует наличия в организации соответствующего специалиста. Такого специалиста называют администратором базы данных. В круг его обязанностей обычно входит обеспечение механизма защиты данных, поддержание их целостности, резервное копирование и восстановление данных и многое другое. Для того чтобы еще больше упростить приложения клиентов базы данных, была разработана многоярусная архитектура базы данных, пример которой (трехъярусная архитектура) приведен на рис. 1.8.
Компьютер-сервер приложений
Рис. 1.8. Трехъярусная архитектура «клиент-сервер»
В многоярусной архитектуре часть кода приложений клиентов перенесена в сервер приложений. Сервер приложений — это программа, которая содержит средства доступа к данным и программный код, являющиеся наиболее общими для всех приложенийклиентов базы данных.
Что нового мы узнали?
23
Преимущество данной архитектуры заключается в упрощении программ-клиентов и уменьшении их кода. Выбор типа базы данных зависит от многих факторов, не последним из которых является наличие сети из нескольких компьютеров. Выбирая тип создаваемой базы данных, ответьте на следующие вопросы: • сколько человек будут использовать таблицы базы данных? Клиент-серверные базы данных разработаны для одновременного доступа к ним нескольких пользователей. Локальные базы данных обычно работают с одним пользователем; • какое количество данных будет содержаться в таблицах базы данных? Клиентсерверные базы данных могут содержать намного больше данных, чем локальные базы данных; • какая скорость доступа к данным вас устроит? Локальные базы данных обеспечивают более быстрый доступ к данным по сравнению с клиент-серверными; • как вы планируете администрировать базу данных? Локальные базы данных менее требовательны к настройке и администрированию.
Что нового мы узнали? На этом занятии мы выяснили, что такое: • база данных; • основные типы баз данных; • архитектуры баз данных.
. •
. ;
.
i , • -'
-
* : • • • •
. .
• •
I
•
i _
Занятие 2 Проектирование баз данных • . • • • •
Ключи и индексы Взаимосвязи данных Нормализация модели базы данных Автоматизация разработки приложений
.
I Это занятие посвящено внутренней структуре реляционных баз данных. Вы узнаете о взаимосвязях между таблицами реляционной базы данных. Мы рассмотрим понятия ключа и индекса. В конце занятия мы расскажем о нормализации построенной модели базы данных.
Ключи и индексы Поля таблицы могут определять так называемые ключи и индексы. Ключ — это комбинация нескольких полей, данные в которых однозначно определяют запись таблицы. Ключи бывают простыми и сложными (составными). Простой ключ — это ключ, состоящий из одного поля. Сложный или составной ключ включает в себя данные нескольких полей. Данные простого ключа должны быть уникальными. Составной ключ может иметь повторы в отдельных полях, но не во всех одновременно. Соответственно поля, по которым строится ключ, называются ключевыми полями. В каждой таблице может быть только один ключ. Ключ иногда называют первичным ключом или главным индексом. Для чего же служит ключ? Прежде всего, для обеспечения однозначного определения записей таблицы. Кроме того, ключ предназначен для более быстрого выполнения запросов к базе данных. По ключевым полям организуется связь между таблицами базы данных. У ключа есть еще много других функций, они будут объясняться по мере изложения материала книги.
Ключи и индексы
25
Сведения о ключе таблицы могут храниться как вместе с данными таблицы, так и в отдельном файле. Этот файл имеет такое же имя, что и файл таблицы, но другое расширение. Например, в базе данных Microsoft Access информация о ключе содержится вместе с данными в одном файле, который имеет расширение .MDB. A Paradox выделяет для информации о ключе отдельный файл с расширением .РХ. Ключевой файл содержит значения ключа, которые располагаются в определенном порядке. Для каждого из значений ключа имеется уникальная ссылка, которая указывает местоположение соответствующей записи в файле таблицы. Таким образом, во время поиска в таблице будет выполнен прямой доступ к необходимой записи на основании упорядоченных значений ключа, а не последовательный перебор записей таблицы. Тем самым значительно увеличивается скорость доступа к искомой информации, хотя в результате размер базы может сильно вырасти (возможно, даже в два раза) за счет хранения дополнительной ключевой информации. Ключевые поля вам придется определять самостоятельно, поэтому следуйте представленным ниже правилам, которые помогут достаточно эффективно выбрать эти поля: • ключ не должен содержать поля, которые можно удалить, не нарушив при этом уникальности ключа; • ключевым полем не может быть поле, содержащее графику, или поле типа memo, включающее в себя комментарии; • нежелательно выбирать в качестве ключевого поля поле, содержащее фамилии людей, так как существует большая вероятность включения в базу данных однофамильцев и при этом будет нарушена уникальность ключа; • если вы используете поле, по которому производится нумерация записей (например, автоинкрементное поле), то имеет смысл сделать его ключевым, поскольку номер записи будет уникальным; • старайтесь задавать ключевые поля в каждой таблице базы данных, даже если их присутствие на первый взгляд не является необходимым. Индекс — это комбинация нескольких полей, которые служат для быстрого доступа к необходимой информации. Основным отличием индекса от ключа является то, что поля индекса могут определять не одну, а несколько записей. Таким образом, индекс не всегда однозначно определяет запись в таблице базы данных. Индексы так же, как и ключи, могут быть простыми и составными. Простой индекс состоит из одного поля, а составной — из нескольких полей. Поля, по которым строится индекс, называют индексными полями. Процесс создания индекса называется индексированием таблицы. В зависимости от используемого типа базы данных, индексы могут храниться как вместе с данными, так в отдельных файлах. Индекс используется для увеличения скорости доступа к данным, для быстрой сортировки данных таблицы, а также для поддержки других функций, которые будут рассмотрены далее. В отличие от ключа, который является уникальным в каждой таблице, индексов в ней может быть несколько. Это в первую очередь необходимо для быстрой
26
Занятие 2. Проектирование баз данных
сортировки по нужному полю или полям. Если эти поля проиндексированы, то сортировка по ним будет выполнена значительно быстрее, чем по обычным полям. В любой момент времени можно активировать любой из индексов таблицы. Именно по активному (текущему) индексу обычно будет выполняться сортировка записей таблицы. Следует, однако, заметить, что, несмотря на наличие нескольких индексов, таблица может не иметь текущего индекса. Вообще говоря, поведение индексов и ключей зависит от типа используемой базы данных. Так, например, в таблицах Paradox ключ автоматически является главным индексом, который не имеет имени. В то же время в таблицах dBase ключ в принципе не создается, вместо него используется один из индексов. Но в общем случае ключевые поля обычно автоматически индексируются. ВНИМАНИЕ Процесс создания ключа в ряде случаев может привести к неожиданным результатам. Например, при создании ключа в таблице базы данных Paradox будут автоматически отсортированы записи по значениям ключа.
Взаимосвязи данных
•
На первом занятии мы уже кратко перечислили возможные взаимосвязи между данными внутри одной базы данных. Теперь рассмотрим особенности этих взаимосвязей для реляционных баз данных. Реляционная база данных может состоять из одной или нескольких таблиц. В ситуации, когда в базе данных имеется всего одна таблица, организация данных довольно проста и никаких связей нет. Но в большинстве случаев база данных содержит в себе несколько таблиц, которые связаны между собой тем или иным способом. Процесс организации связей между таблицами называется связыванием таблиц. ПРИМЕЧАНИЕ В других литературных источниках встречается понятие соединения таблиц, которое является тем же самым связыванием. Также в других источниках вместо термина связь используется термин отношение.
Связи между таблицами могут устанавливаться как в процессе проектирования базы данных, так и в процессе выполнения приложения. В реляционной базе данных могут присутствовать как связанные, так и отдельные таблицы. Для того чтобы связать две или несколько таблиц базы данных, предусмотрены так называемые поля связи. ПРИМЕЧАНИЕ Вместо понятия поля связи к некоторых источниках упоминается термин совпадающие поля.
Нужно заметить, что, независимо от используемого типа базы данных, поля связи обязательно должны быть индексированными. При связывании таблиц используются понятия главной таблицы и подчиненной таблицы.
Взаимосвязи данных
27
Главная таблица (родительская таблица или master) — это таблица, в которой содержатся основные данные. Подчиненная таблица (дочерняя таблица или detail) — таблица, значения в полях которой зависят от значений главной таблицы. Главная таблица может иметь несколько подчиненных таблиц. Таким образом, при перемещении по записям главной таблицы будет автоматически производиться перемещение по записям подчиненной таблицы. В каждой подчиненной таблице для организации связи с главной таблицей берется индекс, состав полей которого должен частично или полностью совпадать с составом полей главной таблицы. Само название связи между таблицами реляционной базы данных формируют по типу таблиц: главный—подчиненный, родительский—дочерний или master—detail. Как было уже сказано на первом занятии, существует четыре вида связи между таблицами: . один к одному; • один ко многим; • много к одному; • много ко многим. Вид связи один к одному означает, что каждой записи в главной таблице соответствует одна запись в подчиненной таблице. При этом не исключается случай, когда некоторым записям главной таблицы может не найтись соответствующих записей в подчиненной таблице. Этот вид связи используется обычно для упрощения структуры одной таблицы с большим количеством полей путем разбиения ее на несколько таблиц. При этом в главной таблице остаются поля с наиболее важной информацией, а остальные поля распределяются между подчиненными таблицами. Вид связи один ко многим означает, что одной записи главной таблицы может ставиться в соответствие несколько записей в подчиненной таблице. При этом не исключается случай, когда записи главной таблицы не будет поставлено в соответствие ни одной записи в подчиненной таблице. Этот вид связи применяется в базах данных наиболее часто. При перемещении по записям в главной таблице будут автоматически становиться доступными записи в подчиненной таблице, у которых значение поля связи равно значению поля связи текущей записи главной таблицы. В качестве примера организации такого вида связи можно привести базу данных, состоящую из двух таблиц, которая содержит данные о покупателях и товаре. В первой, главной таблице хранятся сведения о покупателях (фамилия, имя, отчество, наименование организации и т. п.), во второй — сведения о приобретенном данным покупателем товаре. Один покупатель может приобрести один или несколько товаров. Вид связи много к одному является аналогом вида один ко многим, но отличается направлением, то есть одной записи в подчиненной таблице может соответствовать несколько записей главной таблицы. Последний вид связи много ко многим означает, что одной записи главной таблицы могут быть сопоставлены несколько записей подчиненной таблицы и, наоборот,
Занятие 2. Проектирование баз данных
одной записи подчиненной таблицы может соответствовать несколько записей главной таблицы. Ярким примером организации такого вида связи является база данных типа «Расписание», подразумевающая, что в одной учебной аудитории может заниматься несколько групп и наоборот, одна группа может заниматься в нескольких аудиториях. Таким образом, данные об аудиториях могут находиться в одной таблице, а о группах — в другой. При этом трудно утверждать, что одна из таблиц является главной, а вторая — подчиненной. Данный вид связи является наиболее сложным, поэтому он применяется очень редко. Заметим, что при работе со связанными таблицами нужно выполнять некоторые дополнительные действия. Так, при удалении записи главной таблицы необходимо удалять все соответствующие ей записи из подчиненных таблиц. Такое удаление называется каскадным. При добавлении записи в подчиненную таблицу обязательно нужно устанавливать значение поля связи этой записи равным значению соответствующего поля связи записи из главной таблицы. Изменения значений поля связи главной таблицы нужно производить только вместе с соответствующим изменением значений поля связи в подчиненных таблицах. Если это не будет сделано, может нарушиться соответствие между записями главно!! и подчиненных таблиц.
Нормализация модели базы данных
•
Для построения эффективной структуры базы данных нужно на всех этапах проектирования ориентироваться на то, чтобы создаваемая структура обеспечивала: • достаточно быстрый доступ к данным; • отсутствие повторяющихся записей; • целостность данных. Кроме того, в процессе разработки структуры базы данных может возникнуть так называемая избыточность информации. Избыточность информации — это повторение (дублирование) данных, содержащихся в базе данных. Тем не менее повторение одних и тех же данных может присутствовать в базе данных и не вести к избыточности данных. В этом случае говорят о простом или неизбыточном повторении данных. Такое повторение данных может иметь место, например, при указании города проживания сотрудника организации. Пример простого повторения данных приведен в табл. 2.1. . Таблица 2.1. Простое повторение данных ФИО сотрудника
Город проживания сотрудника
Иванов Иван Иванович Петров Петр Петрович Сидоров Иван Петрович Михайлов Василий Борисович Семенов Иван Данилович Васильев Сергей Анатольевич
Абакан Абакан Черногорск Минусинск Абакан Абакан
'
Нормализация модели базы данных
29
Из приведенной выше таблицы видно, что четыре сотрудника проживают в одном и том же городе. Для каждого из этих сотрудников город проживания является уникальным. Избыточность данных может приводить к различным аномалиям: т аномалии удаления; • аномалии обновления; . • аномалии ввода. Аномалии удаления возникают тогда, когда удаляется какая-либо из записей, содержащая дублированные данные. В этом случае будет потеряна сопутствующая информация. Например, при удалении любой из записей из табл. 2.1 пропадет информация о ФИО сотрудника. Аномалии обновления имеют место, если значение поля одной записи изменяется, а аналогичные значения того же поля для всей таблицы остаются без изменения. Аномалии ввода можно встретить, когда во время ввода новых записей в таблицу для ее полей заданы недопустимые значения либо не задано значение поля, которое обязательно должно заполняться. • В таблице 2.2 приведен пример избыточного повторения данных. Таблица 2.2. Избыточное повторение данных . , .
ц
I
H
ФИО сотрудника
Город проживания
Почтовый индекс
Иванов Иван Иванович Петров Петр Петрович
Абакан Абакан
662600
Сидоров Иван Петрович Михайлов Василий Борисович
Черногорск Минусинск
Null 655150 600000
Семенов Иван Данилович Васильев Сергей Анатольевич
Абакан Абакан
Null Null
В этой таблице появилась новая колонка (поле), в которой хранятся почтовые индексы мест проживания сотрудников. Как вы можете видеть, почтовый индекс города Абакан имеется только в первой записи, а для всех остальных введено нулевое значение Null. В этом случае при работе с таблицей возникает несколько очевидных проблем: • для отображения индекса места проживания сотрудника потребуется искать его в другой записи таблицы по названию города; • объем базы данных будет достаточно большим, так как для хранения нулевых значений потребуется столько же памяти, сколько и для обычных значений; • если будет удалена первая запись, содержащая значение индекса для города Абакан, то мы автоматически лишимся информации об индексе для всех сотрудников, проживающих в Абакане. А что, если вместо нулевых значений поставить значение индекса во всех записях? Этим самым мы решим лишь третью проблему, связанную с удалением записи, но избыточность информации останется. В таблице с избыточными данными содержится мнЪго повторяющихся данных в различных записях. Для избавления от избыточности можно разбить одну большую
1
30
Занятие 2. Проектирование баз данных
таблицу на несколько маленьких. Например, данные из табл. 2.2 можно просто „разместить в двух таблицах меньшего размера (табл. 2.3 и 2.4). Первая будет содержать данные о сотруднике и городе его проживания, а вторая — об индексах всех мест проживания сотрудников фирмы. .Таблица 2.3. Данные о сотрудниках ФИО сотрудника
Город проживания сотрудника
Иванов Иван Иванович Петров Петр Петрович . Сидоров Иван Петрович Михайлов Василий Борисович Семенов Иван Данилович Васильев Сергей Анатольевич
Абакан Абакан Черногорск Минусинск Абакан Абакан
•
Таблица 2.4. Список городов и их индексов
(
Город проживания сотрудника
Почтовый индекс города
Абакан Минусинск Черногорск
662620 600000 655150
В данном примере табл. 2.3 и 2.4 связаны между собой по полю города проживания сотрудника. Для того чтобы получить информацию о почтовом индексе, нужно сначала из первой таблицы извлечь название города, а затем по названию из второй таблицы получить почтовый индекс данного города. Естественно, это приведет к большим затратам времени для доступа к необходимой информации, но зато окупится значительным уменьшением объема памяти, необходимой для хранения данных. Тем более что в данном случае информация о почтовом индексе нужна не очень часто. Таким образом, разбивая большую таблицу с избыточными данными на несколько более мелких таблиц, мы уменьшаем избыточность данных. Тем не менее это не значит, что избыточности данных в таких таблицах уже не будет. Хотя в нашем примере повторения данных все же остались (в табл. 2.3), это допустимое неизбыточное дублирование данных (см. табл. 2.1). Пример с разбиением таблицы относится к ряду операций по приведению таблиц к так называемой нормальной форме. Этот процесс получил название нормализации базы данных. Процесс нормализации базы данных предназначен для уменьшения избыточности информации в базе данных. Существует несколько так называемых нормальных форм базы данных. Давайте рассмотрим их все в теории, а затем на практике попробуем привести сложную информационную систему последовательно к этим нормальным формам. Итак, большинство литературных источников выделяют такую последовательность нормальных форм базы данных: • первая нормальная форма; • вторая нормальная форма;
Нормализация модели базы данных
31
• третья нормальная форма; • усиленная третья нормальная форма (нормальная форма Бойса—Кодда); • четвертая нормальная форма; • пятая нормальная форма. Каждая из нормальных форм получается последовательно из предыдущей нормальной формы. Кроме того, каждая последующая нормальная форма сохраняет свойства предыдущей нормальной формы и удаляет некоторые аномалии, присущие своей предшественнице. Рассмотрим, что же представляют собой эти нормальные формы. Условиям первой нормальной формы удовлетворяет таблица, в которой: • каждое поле содержит неделимую информацию; • отсутствуют повторяющиеся группы полей. Таблица, соответствующая второй нормальной форме, должна отвечать следующим требованиям: • таблица должна быть приведена к первой нормальной форме; • любое поле таблицы, не являющееся ключевым, должно однозначно идентифицироваться ключевыми полями. Третья нормальная форма предъявляет к таблице следующие требования: • таблица должна быть приведена ко второй нормальной форме; • каждое из неключевых полей таблицы должно однозначно идентифицироваться только значениями ключевых полей и не зависеть от любого другого неключевого поля. Таким образом, третья нормальная форма исключает возможность идентификации значений неключевого поля таблицы значениями неключевых полей таблицы. Мы не будем задерживаться на других (более сложных) нормальных формах, так как они практически не применяются на практике. По крайней мере, при создании даже достаточно сложных моделей данных автору не приходилось использовать нормальные формы выше третьей. Рассмотрим теперь процесс нормализации базы данных на конкретном примере. Спроектируем базу данных для хранения информации о читателях библиотеки. Итак, нам необходимо первоначальное распределение данных по полям таблицы. Сделаем предварительный набросок полей (табл. 2.5). Таблица 2.5. Структура ненормализованной таблицы Читатель Дата
Книга
Мы спроектировали три поля. Поле «читатель» содержит информацию о читателе: ФИО, возраст, адрес, телефон, паспортные данные. В поле «дата» находится число, когда читатель взял книгу из библиотеки. Поле «книга» должно хранить полную информацию о книге: название, авторы, издательство, количество страниц. Созданная нами таблица из трех полей имеет Простую СТрукурУ/ и ее ШШР щ;сматривать как базу данных, состоящую из одной таблицы. Однако эта таблица не соответствует требованиям, предъявляемым к нормальным формам. Попробуем привести ее к первой нормальной форме.
32
Занятие 2. Проектирование баз данных
Первое и последнее поля таблицы не отвечают требованию о неделимости информации поля. Разобьем поле «читатель» на пять полей: ФИО читателя, возраст, адрес, телефон и паспортные данные. Также выделим из поля «книга» четыре поля: название книги, авторы, издательство и количество страниц. В результате у нас получится таблица иного вида (табл. 2.6). Таблица 2.6. Таблица в первой нормальной форме ФИО Возраст Адрес Телефон Паспорт Дата Книга Автор Издательство Страницы
Второму требованию первой нормальной формы табл. 2.6 удовлетворяет. Таким образом, мы преобразовали таблицу к первой нормальной форме. Для того чтобы привести табл. 2.6 ко второй нормальной форме, нужно добавить в нее дополнительное ключевое поле. Назовем это поле «номер выданной книги». Каждая последующая выданная книга будет иметь свой уникальный номер. Теперь осталось внести изменения, сводящие нашу таблицу к третьей нормальной форме. Для этого разобьем таблицу на две: таблицу читателей и таблицу книг. Затем свяжем эти таблицы по ключевому полю «номер выданной книги» (табл. 2.7 и 2.8). Таблица 2.7. Таблица читателей Номер
i
ФИО
Возраст
Адрес
Телефон
Паспорт
Таблица 2.8. Таблица книг Номер
Дата
Книга
Автор
Издательство
Число страниц
-
Автоматизация разработки приложений Процесс проектирования структуры и нормализации базы данных может быть весьма трудоемким, так как иногда таблицы содержат несколько сотен полей, а база данных может включать сотни таких таблиц. Организовать правильную взаимосвязь данных в таких случаях вручную очень тяжело. Для облегчения этой задачи были разработаны специальные системы автоматизации разработки приложений (CASE, Computer Aided Software Engineering). Системы CASE — это приложения, которые предназначены для проектирования информационных систем (анализ и формулирование требований, проектирование баз данных, тестирование, генерирование кода и многое другое). Таким образом, среда Delphi также является средством CASE, поскольку она позволяет создавать приложения. Мы не будем останавливаться на рассмотрении существующего множества средств CASE. Скажем лишь, что в состав Delphi включена программа Data Module Designer, которая позволяет проектировать базы данных с таблицами в формате Paradox. При этом структура базы данных и связи между таблицами представляются в графической форме. Для работы с Data Module Designer нужно выбрать пункт главного меню Delphi File > New > Data Module (Файл > Создать > Модуль данных). При этом откроется окно редактора модулей данных (рис. 2.1), в который можно помещать стандартные компоненты для работы с данными. Об этих компонентах мы расскажем на следующем занятии.
Что нового мы узнали?
33
(}? Dat
'
!
4
Рис. 2.1. Окно редактора модулей данных
_
Что нового мы узнали? * На этом занятии мы узнали: • • • •
что такое ключи и индексы и зачем они нужны; - таблиц; * каковы основные виды связей что такое три основные нормальные формы таблиц и способы нормализации; что такое средства CASE. -| .
•
'
'
i -
.
. £
.
-
. . •
•
. .
. =» 0« 2 За». 956
-
•
Занятие 3 Средства Delphi 7 для доступа к данным
.. <
. .
1 • Новые возможности Delphi 7 пог работе с базами данных ш Наборы'данных • Источник данных
' .
•
На этом занятии мы рассмотрим наборы компонентов, которые присутствуют в библиотеке компонентов Delphi 7, предназначенных для работы с базами данных. Вы узнаете, что такое набор данных, источник данных и познакомитесь с другими понятиями, связанными с базами данных. Начнем с рассмотрения новых возможностей Delphi 7. Если вы не являетесь новичком в Delphi, можете пропустить этот раздел и перейти к рассмотрению наборов данных.
Новые возможности Delphi 7 по работе с базами данных Каждая из версий Delphi приносит какие-либо новшества в работу с базами данных. Так, в Delphi 5 ярким примером такой новгщии может являться поддержка технологии ADO. В Delphi 6 также были включены многие новые возможности, в том числе и для работы с базами данных. А именно: • в Delphi б добавлен принципиально новый механизм доступа к данным, называющийся dbExpress. Он обеспечивает исключительно быстрый и простой доступ к серверам баз данных; • наборы данных в Delphi 6 стали поддерживать два новых типа полей: TFMTBCDField и TSQLTimeStampField; • добавлено несколько новых компонентов для упрощения работы с клиентскими наборами данных, а также с двухъярусными и многоярусными приложениями баз данных. Рассмотрим перечисленные выше особенности Delphi 6 более подробно.
Новые возможности Delphi 7 по работе с базами данных
35
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. Были добавлены три новых клиентских набора данных: • TBDECIientDataSet; • TSQLCIientDataSet; • TlBCIientDataSet.
Эти компоненты предназначены для простых приложений и объединяют в се поставщик данных и набор данных. Если создаваемое приложение требует многократного обновления данных с сервера или использует отношение «главный—подчиненный» между таблицами, то лучше всего использовать вместо указанных клиентских наборов, данных внешний поставщик данных и отдельный клиентский набор данных. Компонент TCIientDataSet в Delphi 6 обладает тремя новыми-свойствами: • ConnectionBroker — применяется в случае, когда у вас в приложении имеется несколько наборов данных, которые задействуют одно и то же соединение с сервером базы данных. Данное свойство позволяет централизованно, с помощью изменения только одного значения, изменять значения свойства у всех наборов данных, использующих данное соединение;
Занятие 3. Средства Delphi 7 для доступа к данным
36
• DisableStringTrim — позволяет контролировать ввод .символов пробела в значениях, которые заносят пользователи в поля таблиц. Данное свойство имеет булевый тип. Если значение свойства — true, то данные сохраняются в поле таблицы в том виде, как их вводит пользователь, в ином случае все пробелы, вводимые пользователем, будут отсечены; • XMLData — позволяет получить доступ из клиентского набора данных к XMLданным. Новый набор компонентов позволяет вам работать с XML-документами. Мы их рассмотрим в последующем. Кроме того, в Delphi 6 была реорганизована палитра компонентов. Компоненты, которые основаны на BDE (Borland Database Engine, процессор баз данных Borland), перемещены на отдельную закладку BDE. Добавлены новые закладки: InterBase Admin, dbExpress и DataSnap. Об этих закладках и их компонентах читайте далее в этой главе. Среда Delphi 7 также привнесла изменения в работу с базами данных: • Драйверы dbExpress теперь стали поддерживать Informix 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; О вместо компонента TSQLdientDataSet введен новый компонент TSimpleDataSet, находящийся на вкладке dbExpress палитры компонентов. А*Л,1,ЬгСЫТО»|| fcJ^^J-i f*VjJ\ff
„ -
Наборы данных
.
Среда Delphi работает с таблицами баз данных, которые физически располагаются на диске. Поэтому такие таблицы мы будем называть физическими. Для доступа к данным, содержащимся в физических таблицах, применяются наборы данных. Набором данных называется совокупность записей, выделенных по определенным правилам из одной или нескольких физических таблиц базы данных. Набор данных по определению не будет представлять собой физическую таблицу, поэтому будем называть набор данных логической таблицей. Именно с логическими таблицами работает большинство из стандартных компонентов Delphi. Можно представлять себе взаимодействие физической и логической таблицы по аналогии, как физического файла и файловой переменной.
Наборы данных
37
Итак, из всего вышесказанного можно сделать вывод, что нам при создании приложений баз данных придется работать в основном с наборами данных (или логическими таблицами). ВНИМАНИЕ Во многих других системах управления базами данных вместо термина набор данных используются выборка или таблица.
Среда 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 и позволяет открывать или закрывать набор данных. Его можно установить в окне инспектора объектов, но чаще всего такие операции с наборами данных производят во время выполнения приложения, например: Tablel.Active:=false: // Закрывает набор данных, задаваемых // компонентой Tablel Queryl.Active:=true; // Открывает набор данных, задаваемых // компонентом Query1 Более подробно о свойстве Active рассказывается ниже. Свойство DatabaseName имеет тип String и задает полный путь к каталогу базы данных, например: 'C:\Database\MyDBF'. В значении этого свойства можно указать вместо пути к каталогу базы данных ее псевдоним. Псевдоним (alias) представляет собой специальное имя для обозначения каталога базы данных и применяется для указания местонахождения файлов базы данных.
38
Занятие 3. Средства Delphi 7 для доступа к данным
Более подробно о работе с псевдонимами мы расскажем на четвертом занятии. Все существующие псевдонимы для баз данных будут показаны в окне инспектора объектов при щелчке левой кнопкой мыши на поле со списком напротив свойства DatabaseName. СОВЕТ Старайтесь всегда использовать псевдонимы, так как это позволит вам легко изменять местоположение файлов базы данных, не меняя кода программы. После изменения местоположения файлов достаточно будет изменить название каталога, на который ссылается псевдоним базы данных.
Для компонента Table допустимо применение только свойства DatabaseName при задании пути к базе данных. Компонент Query имеет дополнительную возможность: в запросе SQL можно задать путь доступа к любой из таблиц базы данных. Рассмотрим, как задается путь к нужной базе данных во время работы приложения: • во-первых, необходимо установить свойство Active компонента Table или Query в false (закрыть набор данных); • затем указываем путь к базе данных либо ее псевдоним; • после чего можно открыть набор данных, присвоив свойству Active значение true: Tablel.Active:=false; Queryl.Active:=false: Tablel.DatabaseName:='MyDB':
// Закрываем набор данных // Закрываем набор данных // Задаем местонахождение базы // данных с помощью псевдонима Queryl.DatabaseName:-'C:\Database\MyDBF'; Свойство TableName компонента Table имеет тип String и содержит имя текущей таблицы базы данных. В терминах Delphi каталог — это база данных, а файлы каталога — таблицы. Поэтому после указания пути к базе данных через свойство DatabaseName можно выбрать нужную таблицу из раскрывающегося списка свойства TableName в окне инспектора объектов (там будут отображены все названия файлов таблиц, находящихся в выбранном каталоге). Кроме того, значение этого свойства можно задавать и во время работы приложения, предварительно закрыв набор данных: Tablel.Active-false: Tablel.DatabaseName:='C:\Database\MyDBF': Tablel.Tab!eName: ='My Table':
.
Свойство RecordCount имеет тип Longint и содержит число записей, находящихся в текущий момент времени в наборе данных. Значение данного свойства не отображается в окне инспектора объектов — оно доступно только для чтения во время выполнения приложения. Строка Editl.Text:-IntToStr(Tablel.RecordCount): выводит в компонент Editl количество записей набора данных Tablel. Свойство RecNo имеет тип Longint и содержит номер текущей записи набора данных. Это свойство также доступно только для чтения во время работы приложения. Для перемещения по записям набора данных используются вызовы соответствующих методов: First, Last, Next, Prior и MoveBy:
Наборы данных
Tab! el. First:
Tabl el. Next; Tablel.Last;
Tablel. Prior;
// // // // //
Переход к первой записи набора данных Переход к следующей записи Переход на последнюю запись набора данных Переход на' предыдущую запись
(-12): // Переход на 12 записей назад от // текущей
T^klrtl Mn.i^dw / 1
39
;
• -.
Если вы используете в своем приложении таблицы Paradox, то можно напрямую производить ввод чисел в свойство RecNo для перехода на нужную запись набора данных: Tablel.RecNo:-15:
// Переход на 15-ю запись набора данных .
Состояния наборов данных Как мы уже видели ранее, наборы данных могут принимать два состояния: открытое или закрытое. При установке свойства Active в true набор данных будет открыт. Для закрытия набора данных нужно присвоить свойству Active значение false. Набор данных можно открыть как во время работы, так и во время создания приложения. В случае, когда открыть набор данных нельзя, генерируется исключительная ситуация и выдается сообщение об ошибке. Свойство Active при этом сохраняет значение false. ВНИМАНИЕ При изменении свойств DatabaseName или TableName необходимо обязательно закрыть набор данных, чтобы избежать исключительной ситуации.
Кроме того, вы можете открыть набор данных с помощью вызова метода Open и закрыть с помощью метода Close:
Tablel.Close: // Закрываем набор данных Queryl.Open; // Открываем набор данных Вызов этих методов имеет смысл, если вы хотите выполнить какие-либо действия перед открытием или после открытия набора данных, а также перед закрытием или после закрытия. Итак, метод Open открывает набор данных. При вызове данного метода генерируются события BeforeOpen и AfterOpen. Вы можете написать программы-обработчики этих событий. Это очень полезно, если вы хотите не открывать набор данных до тех пор, пока не выполнились какие-либо условия. Ниже представлен пример такого обработчика: procedure TForml.TablelBeforeOperUDataSet: TDataSet): begin if a<>true then Abort: end: •
.
В данном примере, если переменная а не имеет значение true, открытие набора данных Tablel будет прервано. Это достигается вызовом процедуры Abort, в результате работы которой генерируется исключительная ситуация и операция открытия данных отменяется. При этом на экран не будет выведено никаких сведений об ошибках. Естественно, вы можете добавить команды вывода сведений для пользователя о том, что данные недоступны.
40
Занятие 3. Средства Delphi 7 для доступа к данным
Примером использования события AfterOpen может служить приведенный ниже листинг:
procedure TForml.TablelAfterOpenCDataSet: TDataSet): begin
ShowMessage("Таблица "+Tab1el.TableName+" готова к работе'): end;
Здесь после открытия набора данных выводится текстовое сообщение о готовности таблицы к работе. Имя таблицы содержится в свойстве TableName. Метод Close закрывает набор данных. При его вызове генерируются события BeforeClose и AfterClose. ВНИМАНИЕ
;
При закрытии набора данных необходимо принудительно сохранять сделанные изменения в текущей записи с помощью вызова метода Post, так как метод Close автоматически не сохраняет данные текущей записи.
Можно использовать обработчик события BeforeClose для вызова метода Post: procedure TForml.Tab1elBeforeC1ose(DataSet: TDataSet): begin if (Tablel.State-dsInsert) or" (Tablel.State-dsEdit) then Tablel.Post: end:
В данном примере сначала осуществляется проверка, в каком режиме находится набор данных Tablel, при помощи значения свойства State. Если он находится в режиме вставки новой записи (dslnsert) или редактирования текущей записи (dsEdit), то перед закрытием набора данных все внесенные изменения сохраняются. ВНИМАНИЕ При выходе из приложения несохраненные данные теряются, и обработчик события BeforeClose не вызывается.
К обработке события AfterClose можно прибегать для выдачи пользователю сообщения о закрытии набора данных. '
Режимы наборов данных
,
В примере использования события BeforeClose мы упомянули о режиме набора данных (свойстве State). Остановимся на этом немного подробнее. Наборы данных в разные моменты времени могут находиться в различных режимах, например неактивном, фильтрации данных, вставки, редактирования и т. д. Программист может читать значение свойства State, но изменять его напрямую нельзя. Для того чтобы перевести набор данных в один из режимов, нужно либо вызвать соответствующий метод, либо воспользоваться адекватными визуальными компонентами, речь о которых пойдет ниже. Перечислим возможные режимы, в которых может находиться набор данных. Их всего тринадцать: • dslnactive — неактивный. В этом режиме набор данных является закрытым и доступ к данным невозможен;
Наборы данных
41
• dsBrowse — режим просмотра. Данный режим устанавливается по умолчанию для любого открытого набора данных. В этом режиме данные могут свободно просматриваться, но никаких изменений в них внести нельзя; • dsEdit — режим редактирования. В этом режиме возможно только редактирование текущей (активной) записи набора данных; • dslnsert — режим вставки. В данном состоянии активной является новая запись, которую можно редактировать, а затем либо принять изменения (post) либо отменить их (discard); • dsSetKey — режим поиска, который доступен только для компонентов Table и ClientDataSet. В этом режиме происходит отбор записей, которые соответствуют некоторому критерию. Можно просматривать ограниченный набор данных (соответствующих критерию), но нельзя их редактировать или вставлять новые записи; • dsCalcFields — расчет вычисляемых полей, в процессе которого невычисляемые поля таблицы не могут быть отредактированы и нельзя вставлять новые записи. Этот режим использует событие OnCalcFields; • dsFilter — режим фильтра. В этом режиме показываются только те данные, которые соответствуют фильтру, при этом невозможно редактировать или вставлять записи. Режим использует событие OnFilterRecord; • dsNewValue — режим доступа к свойству NewValue. Данный режим является временным; • dsOldValue — режим доступа к свойству OldValue. Также является временным; • dsCurValue — режим доступа к свойству CurValue. Как и предыдущие, временный режим; • • dsBlockRead — режим чтения блока данных. В этом режиме при переходе на следующую запись набора данных (при вызове метода Next) все визуальные компоненты, отображающие данные, не обновляются и не происходят никакие события; • dsIntemalCak — режим внутренних вычислений. Временный режим, в нем значения полей, свойство TField.FieldKind которых установлено в fklnternalCalc, вычисляются; • dsOpening — режим открытия набора данных. Подразумевает состояние еще не завершенного открытия набора данных. Этот режим активируется, когда набор данных открывается для асинхронной г f t выборки. -
Работа с полями наборов данных . Поле набора данных представляет собой столбец таблицы. В среде Delphi предусмотрен специальный объект Field для работы с полями. Данный объект имеет тип TField. Наследниками этого объекта являются TlntegerField, TFIoatField и т. д. Для того чтобы программист мог работать с отдельными полями набора данных, в Delphi определены специальные методы и свойства, которые мы и рассмотрим. Свойство FieldCount имеет тип Integer и содержит число полей данного набора данных. Свойство доступно только для чтения. Приведем пример чтения значения свойства FieldCount: a: =Tablel. FieldCount; / / a - переменная типа Integer
42
Занятие 3. Средства Delphi 7 для доступа к данным
ВНИМАНИЕ Количество полей набора данных может не быть равным числу полей физической таблицы базы данных, так как в набор данных могут быть не включены некоторые поля таблицы.
Свойство Fields имеет тип TFields и хранит список всех несоставных полей набора данных. Его можно представить себе в виде массива, который содержит поля набора данных, каждое под своим номером (индексом). Вы можете обращаться к конкретному полю набора данных при помощи указания его индекса (Index). Нумерация индексов начинается с нуля и заканчивается значением "FieldCount-1. Если приложению известен тип данных конкретного поля, то его значение можно прочитать с помощью свойства Fields: Editl.Text:=Tablel.Fields.Fields[l].AsString: Кроме того, допускается запись значения в нужное поле набора данных: Tablel.Edit: // Переводим набор данных в режим редактирования Tablel.Fields.Fields[l].AsString:-Ed1tl.Text: Tablel.Post: // Записываем данные в таблицу Вы, вероятно, обратили внимание на то, что при вставке в поле значения мы применили такое свойство объекта Field, как AsString. Данное свойство позволяет обращаться к содержимому поля как к строковому значению. Кроме рассмотренного свойства, имеются еще несколько: Aslnteger — обращение как к целой величине, AsFloat — как к вещественной, AsVariant — как к вариантной, AsCurrency — как к денежной, AsDateTime — как к «дате-времени» и AsBoolean — обращение как к логическому (булевому) значению. ВНИМАНИЕ При доступе к полю набора данных нужно всегда четко представлять/ какого оно типа. Так как, например, если вы обращаетесь к строковому полю с использованием свойства AsFloat, возникнет исключительная ситуация.
Обращение к полям по их номеру не всегда эффективно, поскольку номер поля — величина не постоянная. Номера полей зависят от многих факторов: от порядка полей в физической таблице базы данных, от состава полей набора данных в настоящий момент времени, от значений свойств визуальных компонентов. Поэтому доступ к полю по его номеру чреват ошибками. На практике для доступа к полям разработчики чаще всего используют методы FindField и FieldByName. Метод FindField (const FieldName: string): TField; обнаруживает поле по его имени. Если такое поле найдено, то метод возвращает объект типа TField, то есть поле, соответствующее параметру FieldName. В случае отрицательного результата возвращается значение nil. Данный метод похож на рассматриваемый далее метод FieldByName за исключением того, что он возвращает значение nil в случае, когда поле не найдено, а метод FieldByName генерирует исключительную ситуацию. ВНИМАНИЕ Параметр FieldName указывает имя поля физической таблицы базы данных, которое было задано при первичном проектировании таблицы.
Наборы данных
43
Метод FieldByName(const FieldName: string): TField; также ищет поле по его имени. В случае успешного поиска возвращается поле, соответствующее параметру FieldName. В противном случае генерируется исключительная ситуация EDatabaseError. Вы можете выбрать как первый, так и второй метод для работы с пойями — это дело вкуса. Рассмотрим пример кода, в котором заменим значение поля с помощью вызова метода FindField: Tab!el.Edit; // Переводим набор данных в режим редактирования ТаЫ el. Fi ndFi el d (' Number'). As Integer: =10: Tab!el.F1ndFi eld('Name').AsStri ng: ='Вячесла в ' : Tab!el.Fi ndFi eld('Surname').AsStri ng:='Понамарев'; Tablel.Post: // Записываем данные в таблицу
Мы уже немного научились использовать объект поля Field. Теперь остановимся на нем более подробно. Как уже было сказано ранее, объект Field имеет тип TField, который является абстрактным классом. Поэтому вместо него применяются классы-наследники, перечисленные в табл. 3.2. Таблица 3.2. Наследники класса TField Класс-наследник
Вид поля набора данных
TADTField
Поле абстрактного типа данных (Abstract Data Type) может использовать определенные типы, созданные на сервере баз данных. Может содержать массивы, ссылки и другие данные Составное поле. Позволяет объединять разнородные данные полей набора данных Поле массива. Содержит набор полей одного типа Поле, автоматически увеличивающее свое значение (автоинкрементное). Может служить счетчиком записей набора данных. Диапазон значений: от -2 147 483 648 до 2 147 483 647. Этот тип поля чаще всего используется в качестве уникального первичного ключа Двоично-десятичное поле (Binary-Coded Decimal). В основном требуется для хранения денежных величин. Обычно такое поле содержит десятичные значения. Так как Delphi ранее не поддерживала собственного типа BCD, для работы с этим полем компилятор использует денежный тип Currency, иЗ-за чего значение этого поля ограничено 20 значащими цифрами Данное поле содержит ссылки на большие двоичные объекты (Binary Large OBjects). Этот тип поля является прямым предком для двух других типов полей: TGraphicField и TMemoField Поле логического (булевого) типа. Может иметь значения true или false Последовательность байтов фиксированной длины Поле содержит значения денежного типа (положительные или отрицательные) от 5,0х10'зм до 1,7х10т с точностью до 15 знаков после запятой Поле обеспечивает доступ к вложенному набору данных Поле содержит дату Поле содержит дату и время Данное поле содержит вещественные значения. Они могут находиться в диапазоне от 5,0х10-зи до 1,7хЮ308 с точностью до 15 знаков после запятой
TAgregateField TArrayField TAutoIncField
TBCDField
TBLOBField
TBooleanField TBytesField TCurrencyField TDataSetField TDateField TDateTimeField TFIoatField
продолжение £>
i
44
Занятие 3. Средства Delphi 7 для доступа к данным
Таблица 3.2 (продолжение) Класс-наследник
Вид поля набора данных
TFMTBCDField TGraphicField TGUIdField
Данные представлены в истинной двоично-десятичной форме Графическое поле Поле предназначено для работы с уникальными глобальными идентификаторами (Globally Unique Identifiers, GUIDs) Поле содержит указатели на интерфейсы Idispatch Поле для хранения целочисленных 32-битных значений со знаком. Может содержать числа в диапазоне от -2 147 483 648 до 2 147 483 647 Поле большого целочисленного значения (64-битного) Memo-поле, служит для хранения текста Поле содержит ссылки или указатели на другие объекты Поле маленького целочисленного значения (16-битного). Допускаются числа в диапазоне от -32 768 до 32 767 Содержит данные о дате и времени в формате, совместимом с драйверами dbExpress Строковое поле. Заполняется строками простого текста длиной до 8192 символов Поле времени Поле байтов переменного размера. Значение длины содержится в первых двух байтах Поле вариантного типа Поле длинных строк Поле целочисленного 16-битного значения без знака. Диапазон значений
TIDispatchField TIntegerReld TLargelntField TMemoField TReferenceReld TSmalllntField TSQLTimeStampField TStringField TTimeField TVarBytesField TVariantField TWideStringField TWordField
от 0 до 65 535
В дальнейшем мы будем применять термин TField для обозначения любого из объектов, перечисленных в табл. 3.1. Для того чтобы проверить, какой тип имеет конкретное поле таблицы, используйте свойство DataType типа TFieldType. Оно может принимать значения, представленные в табл. 3.3. Таблица 3.3. Значения свойства DataType Значение
Описание
ftUnknown ftString ftSmalllnt ftlnteger ftWord ftBoolean ftFloat FtCurrency FtBCD FtDate FtTime FtDateTime FtBytes FtVarBytes
Неопределенный тип Поле символа или строки 16-битное целое поле 32-битное целое поле 16-битное целое поле без знака Логическое (булевское) поле Поле вещественных чисел Поле денежных значений Поле двоично-десятичных значений Поле даты Поле времени Поле даты и времени Поле байтовых значений фиксированной длины Поле байтовых значений переменной длины
Наборы данных Значение
45
Описание
FtAutoInc
Поле, автоматически увеличивающее свое значение
FtBLOB
BLOB-поле
FtMemo ftGraphic
Memo-поле Графическое поле
ftFmtMemo
Memo-поле, содержащее форматированный текст
ftParadoxOLE
Поле OLE для таблиц Paradox
ftDBaseOLE
Поле OLE для таблиц dBase
ftTypedBinary ' ftCursor
Двоичное поле • „ „ , Курсор хранимой процедуры Oracle
ftFixedChar
Символьное поле фиксированной длины
ftWideString
Поле длинной строки
fttargelnt
Поле большого целого числа
ftADT
Поле данных абстрактного типа
«Array
Поле массива
ftReference
Поле, содержащее ссылки и указатели на объекты
ftDataSet
Поле типа TDataSet
ftOraBLOB
BLOB-поле в таблице Oracle 8
ftOraCLOB
CLOB-поле в таблице Oracle 8
ftVariant
Данные неизвестного или неопределенного типа
ftlnteitace
Поле ссылок на интерфейсы (lUnknown)
ftlDispatch
Поле ссылок на интерфейсы (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, то с данными можно осуществлять произвольные действия (изменять, добавлять, удалять и т. д.) продолжение &
46
Занятие 3. Средства Delphi 7 для доступа к данным
Таблица 3.4 (продолжение) Название свойства
Тип свойства
Описание
Определяет, как будет осуществляться работа с автоматически вычисляемыми полями. Если свойство установлено в True, то значения таких полей будут автоматически вычисляться в случае открытия набора данных, перевода набора данных в режим редактирования (dsEdit), передачи фокуса с одного визуального компонента на другой или из одной колонки визуального компонента в другую Определяет порядок обновления на сервере базы данных AutoRefresh Boolean визуальных компонентов для отображаемых полей. Если значение свойства — False (по умолчанию), то автоматическое обновление будет отсутствовать. Для обновления данных в этом случае программист должен предусмотреть вызов процедуры Refresh. Если значение свойства — True, то обновления будут осуществляться автоматически Установка значения свойства в True позволяет кэшировать CachedUpdates Boolean изменения, сделанные в базе данных. При этом данные хранятся в оперативной памяти, и для их переноса в базу данных применяется метод ApplyUpdates. Для отмены сделанных изменений вызывается метод CancelUpdates. Для очистки содержимого кэша используется метод CommitUpdates Constraints TCheckConstraints Определяет ограничения целостности на уровне записи, накладываемые на значения отдельных полей набора данных DatabaseName String Определяет имя базы данных, связанной с набором данных Определяет, будут ли данные в таблице отсортированы по Defaultlndex Boolean полю первичного ключа или главного индекса. Значение свойства по умолчанию — True Exclusive Boolean Если значение свойства — True, то другие приложения не смогут обратиться к уже открытому набору данных (применимо только к таблицам Paradox и dBase). Необходимо обязательно закрывать открытую таблицу при смене значения данного свойства Задает набор полей, которые определяют набор данных. FieldDefs TFieldDefs Позволяет программно, во время выполнения приложения создавать таблицы и их поля Rlter String Содержит текст текущего фильтра для набора данных. В визуальных компонентах будут отображаться только те данные, которые соответствуют условиям данного фильтра Boolean Filtered Определяет, будет ли учитываться значение свойства Filter при отображении данных в визуальных компонентах. В случае True данные будут фильтроваться в соответствии со свойством Filter, иначе — фильтр игнорируется FilterOptions TFilterOptions Содержит два подчиненных свойства, которые определяют, является ли фильтр чувствительным к регистру букв и разрешается ли в фильтре использование символа «*» в качестве указателя на любое количество любых символов. По умолчанию эти два свойства имеют значения False IndexDefs TIndexDefs Содержит информацию об индексах таблицы IndexFieldNames String Содержит список столбцов таблицы, которые выбраны в качестве индексных IndexFiles TStrings Содержит название одного или нескольких индексных файлов для таблицы формата dBase IndexName String Определяет альтернативные индексы для таблицы AutoCaicFields
Boolean
47
Наборы данных Название свойства
Тип свойства
Описание
MasterFields
String
MasterSource
TDataSource
Определяет одно или несколько полей главной таблицы (master table) для установления связи с соответствующими полями подчиненной таблицы, то есть для установления связи «master—detail» Задает имя компонента источника данных, свойство DataSet которого определяет набор данных, используемый в качестве главной (master) таблицы при установлении связи «masterdetail» Определяет имя компонента набора данных. По умолчанию присваиваются имена Tablel, Table2,..., TableN
.
Name
TComponentName
ObjectView
Boolean
Указывает, как хранятся объекты полей в свойстве Fields: иерархически или последовательно (дочерние поля размещены после родительских)
Readonly
Boolean
Фиксирует, можно ли изменять данные в таблице, или они доступны только для чтения. Если значение свойства — False (по умолчанию), то изменение данных разрешено, иначе — данные из таблицы доступны только для чтения
•
SessionName String
Определяет имя компонента Session, связанного с данной таблицей
StoreDefs
Указывает, где сохраняются определения полей и индексов. Если значение данного свойства — True, то определения полей и индексов будут сохраняться в модуле данных или в форме. В случае False (по умолчанию), информация сохраняется в файлах базы данных
Boolean
-
TableName
TRIeName
Определяет имя файла таблицы базы данных, которую инкапсулирует объект. Условием установки этого свойства является присвоение значения False свойству Active
TableType'
ТТаЫёТуре
Определяет структуру используемой таблицы базы данных и может принимать следующие значения: ttDefault — тип таблицы определяется по ее расширению (*.db — Paradox, *.dbf — dBase, *.txt — ASCII); «Paradox — таблица Paradox; «DBase — таблица dBase; «FoxPro — таблица FoxPro; ttASCII — таблица в текстовом формате с данными, разделенными запятыми
Longlnt
Не имеет специального назначения. Применяется для хранения целого числа, связанного с компонентом. Может применяться по усмотрению программиста
•
Tag
UpdateMode TUpdateMode
Определяет критерии поиска обновляемой записи базы данных SQL в ВОЕ (какие поля учитываются). Может принимать одно из трех значений: UpWhereAII — все поля; UpWhereChanged — только ключевые поля и поля, значения которых были изменены; UpWhereKeyOnly — только ключевые поля
UpdateObject TDataSetUpdateObject Определяет объект типа TDataSetUpdateObject, который используется для обновления записи
Набор данных Query -
Набор данных Query представлен в Delphi компонентом Query. Особенностью ком понента Query является то, что его записи формируются после выполнения SQL запроса. ' .
48
Занятие 3. Средства Delphi 7 для доступа к данным
В отличие от набора данных Table, компонент Query может содержать записи сразу нескольких таблиц. Данный компонент удобно использовать при работе с удаленными базами данных. Многие свойства компонента Query несут ту же нагрузку, что и соответствующие свойства компонента Table. В таблице 3.5 мы приведем лишь те из них, которые являются специфичными для компонента Query. Таблица 3.5. Некоторые свойства компонента Query Название свойства Constrained
•
Тип свойства
Описание
Boolean
Задает совместимость ограничений в предложении SELECT с операциями редактирования и вставки записей в таблицах Paradox и dBASE Указывает имя компонента TDataSource, относящегося к главному набору данных, из которого берется значение ключа; этому значению должны соответствовать записи набора данных Определяет, должно ли свойство Params автоматически обновляться при изменении запроса в свойстве SQL во время выполнения Содержит параметры запроса, находящегося в свойстве SQL Позволяет попытаться возвратить результат запроса как «живой» набор данных, вместо таблицы «только для чтения» Содержит текст SQL-запроса Определяет доступность двунаправленного курсора Borland Database Engine (BDE)
DataSource
TDataSource
ParamCheck
. Boolean
Params RequestLive
TParams Boolean
SQL UniDirectional
TStrings Boolean
Источник данных
.
Источник данных (data source) представляет собой промежуточный элемент, который применяется для связи набора данных с визуальными компонентами. Получается как бы цепочка: «набор данных — источник данных — визуальный компонент». Для этой цели в Delphi служит компонент DataSource. Указанный компонент имеет пять основных свойств, которые отображаются в окне инспектора объектов. Эти свойства и их краткое описание представлены в табл. 3.6. Таблица 3.6. Свойства компонента DataSource Название Тип свойства свойства
Описание
AutoEdit
Boolean
DataSet
TDataSet
Enabled
Boolean
Определяет, может ли набор данных автоматически переводиться в режим модификации при попытке изменения данных пользователем. По умолчанию значение свойства — True, то есть такой перевод разрешен. В случае если вы не хотите допустить случайное изменение данных — установите значение этого свойства в False Служит для указания набора данных, с которым связан источник данных. Отметим, что визуальные компоненты для связи с источником данных используют свое свойство DataSource Определяет, будут ли визуальные компоненты, связанные с этим источником данных, отображать данные из набора данных (true — да, false — нет)
Источник данных
49
Название Тип свойства свойства
Описание
Name
TComponentName
Tag
Longlnt
Задает имя источника данных. По умолчанию источники данных получают имена DataSourcel, DataSourceZ,..., DataSourceN Не имеет специального назначения. Применяется для хранения целого числа, связанного с компонентом, по усмотрению программиста
ВНИМАНИЕ Вне зависимости от значения свойства AutoEdit есть возможность программно изменять данные в наборе данных. Кроме того, независимо от значения этого свойства пользователь может перевести набор данных в режим модификации с помощью нажатия кнопок визуального компонента DBNavigator. Таким образом, значение свойства AutoEdit влияет лишь на попытку изменения данных пользователем.
При изменении данных в наборе данных происходит генерация события OnDataChange, которое имеет тип TDataChangeEvent Этот тип описан в Delphi следующим образом: type TDataChangeEvent = procedure (Sender: TObject: Field: TField) of object: Параметр Field определяет, значение какого поля было изменено. Если данные были обновлены в нескольких полях, то параметр будет содержать пустое значение (nil). ВНИМАНИЕ Событие OnDataChange может произойти также и в случае, когда происходит переход на другую запись набора данных. Оно возникает, если значение текущего поля старой записи отличается от значения того же самого поля новой записи. Кроме того, это событие имеет место при первоначальном открытии набора данных.
Кроме события OnDataChange, при изменении значений полей текущей записи возникает событие OnUpdateData, которое имеет тип TNotifyEvent. Такое событие происходит перед записью данных в базу данных. Таким образом, его можно использовать, например, для подтверждения внесенных изменений или отказа от них. Связь между набором данных и источником данных обычно устанавливается на этапе проектирования приложения с помощью инспектора объектов. Delphi допускает установку или разрыв этой связи и в процессе выполнения приложения. При установлении новой связи визуальные компоненты автоматически подключатся к новому набору данных и будут отображать его значения. Приведем пример установки и разрыва связи (листинг 3.1). Листинг 3.1. Установка и разрыв связи с наборами данных DataSourcel.DataSet Tablel: // установка связи с набором
// данных Tablel // присвоение пустого // значения свойству DataSet // разрывает связь с набором // данных DataSourcel.DataSet := Queryl: // установка связи с набором // данных Queryl В листинге 3.1 можно было опустить строку, в которой происходит присваивание пустого значения. Переключение между наборами данных можно осуществлять без предварительного разрыва связи со старым набором данных. DataSourcel.DataSet
nil;
ii
i
Занятие 3. Средства Delphi 7 для доступа к данным
50
Что нового мы узнали? На этом занятии мы узнали: • какие новые возможности по работе с данными предоставляет среда Delphi 7; • что такое наборы данных; • каковы свойства и методы основных наборов данных Table и Query. '
.
•
•
•
•
1
.
I
' -
•
,
. '
'
•
.
-
• •
•
1
•
;
• •
-.
!
' -
/"-'
to
. ' .
•
•
.
Занятие 4 Средства для работы с базами данных • • • • • •
_
Borland Database Engine, архитектура BDE Настройка BDE Программа Database Desktop Работа с псевдонимами баз данных Программа Data Pump Архитектура dbExpress В
•
.
•
.
На этом уроке мы рассмотрим архитектуру BDE Delphi, а также новую архитектуру dbExpress, которая появилась еще в версии Delphi 6. Кроме того, вы познакомитесь с набором программ, входящих в комплект поставки Delphi 7 и предназначенных для работы с базами данных. -
Borland Database Engine, архитектура BDE Процессор баз данных фирмы Borland (Borland Database Engine, BDE) — это совокупность файлов динамически присоединяемых библиотек (*.dll) и набора драйверов, обеспечивающих доступ к данным. BDE представляет собой механизм доступа к данным, который может использоваться одновременно несколькими приложениями. BDE содержит мощную библиотеку вызовов API Windows для создания, реструктуризации, обновления данных и других манипуляций с локальными и удаленными базами данных. API, Application Programming Interface Windows — это интерфейс разработки приложений Windows. Таким образом, BDE обеспечивает единство доступа к разнообразным серверам баз данных. В зависимости от используемой версии Delphi вы можете с помощью BDE обращаться к локальным базам данных типа Paradox, dBase, FoxPro и Microsoft
52
.
Занятие 4. Средства для работы с базами данных
Access. Кроме того, с помощью драйверов SQL Links (только в версии Delphi 7 Enterprise) вы можете работать с удаленными серверами баз данных, такими как InterBase, Oracle, Sybase, Informix, Microsoft SQL Server и DB2. ПРИМЕЧАНИЕ Компания Borland отказывается от дальнейшего использования SQL Links. Вместо SQL Links предлагается использовать технологию dbExpress.
BDE разработан для использования не только в среде Delphi. Его применяют также C++ Builder, IntraBuilder, Paradox for Windows и Visual dBASE for Windows. Приведем список программных компонентов, которые обеспечивают работу BDE. • Ядро BDE — файлы, составляющие ядро механизма BDE (по умолчанию устанавливаются в папку Program FHes\Common Files\Borland Shared\BDE): Q IDAPI32.DLL — главный файл BDE; О BLW32.DLL — драйвер поддержки национальных языков; г г Q IDBAT32.DLL — осуществляет пакетные операции; Q IDQBE32.DLL — механизм запросов QBE; a IDWQL32.DLL — механизм запросов SQL; О IDASCII32.DLL — драйвер ASCII для работы с текстовым форматом таблиц; a IDPDX32.DLL — драйвер Paradox; Q IDDBAS32.DLL —драйвер dBase; Q IDODBC32.DLL — драйвер сокетов ODBC (позволяет использовать ODBC 3.0); О IDR20009.DLL — файл ресурса сообщений об ошибках; Q IDDA032.DLL — драйвер для Microsoft Access 95 и Jet Engine 3.0; Q IDDA3532.DLL - драйвер для Microsoft Access 97 и Jet Engine 3.5; Q IDDR32.DLL —хранилище данных; Q BDEADMIN.EXE — утилита BDE Administrator, предназначенная для управления информацией о настройках, находящейся в системном реестре Windows, и о псевдонимах, содержащейся в файле IDAPI.CFG; • СЦ BDEADMIN.HLP — файл помощи для утилиты BDE Administrator; Q BDEADMIN.CNT - таблица содержания файла BDEADMIN.HLP; Q BDE32.HLP - файл справки по BDE; О BDE32.CNT — таблица содержания файла BDE32.HLP; -
Q IDAPI.CFG — файл содержит специфичную конфигурацию BDE, а также сведения о первоначальных псевдонимах баз данных; Q * .BTL — служебная информация; Q CHARSET.CVB — информация о преобразованиях наборов символов. • Функции BDE API — набор функций для управления средой, конфигурацией, обработкой ошибок, работы с индексами, таблицами, транзакциями и т. д.
Borland Database Engine, архитектура BDE
53
• BDE Administrator — удобное средство для конфигурирования BDE: для регистрации драйверов и псевдонимов, задания формата данных и настройки драйверов BDE. Входит в состав ядра BDE. • Database Desktop — утилита, используемая для просмотра, создания и изменения структуры таблиц, а также для запуска запросов с помощью графического интерфейса. • Механизм запросов — средство выполнения запросов ANSI SQL 92. Включает в себя механизм запросов QBE (Query By Example, запрос по примеру). • Драйверы баз данных — пять стандартных драйверов баз данных различных форматов: Paradox, dBase, FoxPro, Microsoft Access и ASCII. Входят в состав ядра BDE. • Дополнительные драйверы — драйверы для поддержки других баз данных, которые могут подключаться по мере необходимости, а именно для InterBase, DB2, Informix, Oracle, Sybase и Microsoft SQL Server. • Связи ODBC — обеспечивают доступ к любым наборам данных, для которых были установлены драйверы ODBC. • Инструментальные средства и примеры — коллекция утилит, облегчающих разработку приложений, а также набор программ, демонстрирующих применение функций BDE. Если вы используете в своем приложении BDE, то при распространении готового продукта вам придется включить в комплект поставки и BDE, хотя это и увеличивает объем дистрибутива. С другой стороны, на одном компьютере достаточно присутствия всего одной копии BDE. Причем желательно, чтобы имеющаяся версия была как можно более поздней. Но если вы хотите использовать различные версии BDE для разных программ, то каждую из них нужно размещать в той папке, которая является рабочей для данного приложения. Вообще говоря, о том, как приложение ищет главный файл BDE (IDAPI32.DLL), можно сказать следующее: сначала проверяется папка, в которой" установлено приложение. Если там файл не найден, то происходит обращение к ключу реестра Windows HKEY_LOCAL_MACHINE/ SOFTWARE/Borland/Database Engine/DLLPATH/xxxxx. Если в реестре нет информации о местонахождении файла, производится дополнительный поиск в такой последовательности: • проверяется текущая папка; • если файл не найден, то сканируется папка System; * • если снова файл не найден, проверяется папка Windows; • наконец, анализируются описания PATH в файле Autoexec.bat. ВНИМАНИЕ Загрузка BDE из папки, в которой установлено приложение, может быть полезна в некоторых случаях. Однако необходимо предупредить о потенциальной проблеме при запуске других приложений, которые также используют собственный BDE (находящийся там же, где и само приложение). Это может вызвать ошибку инициализации. Будьте внимательны!
BDE резервирует определенные адреса памяти для загрузки своих файлов (табл. 4.1).
54
Занятие 4. Средства для работы с базами данных
Таблица 4.1. Адреса загрузки файлов BDE Файл BDE
Адреса
IDAPI32.DLL
OX4BDEOOOO
IDPDX32.DLL
Ox4CDEOOOO
IDDBAS32.DLL
OX4DDEOOOO
IDASCI32.DLL
OX4EDEOOOO
В случае, когда невозможно загрузить файлы в указанное адресное пространство, они помещаются по другим адресам. Как видно из представленных комментариев к файловому составу BDE, этот процессор баз данных использует архитектуру, основанную на драйверах (driver-based architecture).
Настройка BDE
.
Для настройки и конфигурирования BDE применяется специальная программа, которая называется BDE Administrator. .
Программа BDE Administrator Эта программа по умолчанию устанавливается в папку Program Files\Common Files\ Borland Shared\BDE и носит имя bdeadmin.exe. После ее запуска на экране вашего монитора появится окно такого вида, как показанно на рис. 4.1.
•К $ DBDEMGS $•$ DdaJlOO Ж !J iBUca. 2 "в База йамных MS До* ;*; ^* Базайанных VisualFc В "в Т абпиы Visual Fod^if ;tl Tf Файлы dBASE 3 ^ Файлы dBase-Word; ГГ! а Файлы Excd
ii "а Файяи FoxPro-Wwdi
I
Рис. 4.1. Главное окно программы BDE Administrator
Настройка BDE
55
Главное окно программы BDE Administrator состоит из двух основных областей. В левой части при первоначальном запуске (активна закладка Databases) отображаются все зарегистрированные в системе псевдонимы баз данных. Справа выводится информация о выбранной в левой части базе данных, например, как на рис. 4.2.
нмвм
В Ч) Databases
Е SJ DefauHOD IB i*rSj| Local Й5-"7? БвэаданмькМЗАсс! ф - "в" База даннь« Visual Fc Ё 7 Таблицы Visual FoxPri gj Т Файлы dBASE и g Файля dBase -Word Е-"в Файлы Excel Е6-7 ЧЧйяа FoxPro -Woi(i
Ire?
DEFAULT DRIVER ENABLE BCD PATH
STANDARD PARADOX
2f*^ri ...CAPiajfani
Рис. 4.2. Информация о демонстрационных базах данных Delphi . Информацию как в одной, так и в другой части главного окна программы BDE Administrator можно редактировать. Все внесенные изменения будут сохранены в файле IDAPI32.CFG.
Кроме закладки Databases (Базы данных) в левой части главного окна имеется еще одна закладка — Configuration (Конфигурация). С ее помощью можно просматривать и редактировать сведения о драйверах (включая ODBC) и о системе (рис. 4.3). Изменение системной информации позволяет регулировать некоторые специфические настройки для работы приложений баз данных. Давайте рассмотрим теперь все возможности программы BDE Administrator более подробно. Итак, с помощью данной программы можно настраивать: • псевдонимы баз данных (названия, типы, пути и т. д.); • драйверы баз данных (типы, языки и т. д.); • системные установки (форматы даты, времени, числовые и т. д.).
56
Занятие 4. Средства для работы с базами данных
NET D1R VERSION TYPE IANSDRIVER BLOCK SIZE FiLL FACTOR LEVEL STRICTiNTE6RTY
I Configuration • 6l Drivers
© DBASE ;-© FOXPRO -© MSACCESS . © MSSQL '-© SYBASE ': •© INFORMIX © INTRBASE
:
Cs 40 FILE 2048 95 7
'TRUE
© OB г
© ORACLE Й ODBC : ©SQLSeivei © Microsoft Access Dfivw("mdb) © Microsoft Т «Driveif-hf © Microsoft Excel Drivel [• xls] r © Microsoft dBase Dnvet (" dbf) © Microsoft Paradox Driver p.db © Microsoft Visual FoxPro Driver © Microsoft ODBC fa Oracle i © Microsoft dBase VFP Driver f d - © Microtofl FoxPro VFP Dnvei (". System INIT Forniats
Рис. 4.З. Сведения об установленном драйвере Paradox
Для изменения текущего состояния параметра выберите в левой части BDE Administrator нужный объект. При этом в правой части окна появится соответствующий список параметров. Отменить сделанные изменения можно командой Cancel (Отменить) главного меню BDE Administrator Object > Сапсе1(Объект > Отменить) или с помощью такой же команды контекстного меню (вызываемого нажатием правой кнопки мыши на измененном параметре или объекте). Закрепить изменения можно с помощью команды Apply, которая также имеется как в главном, так и в контекстном меню. Для создания нового объекта выберите в главном меню пункт New (Создать). Например, при добавлении нового драйвера ODBC нужно перейти в левой части окна BDE Administrator в раздел ODBC и выбрать Object > New (Объект > Создать) или щелкнуть правой кнопкой мыши и выбрать в контекстном меню пункт New. Еще один вариант — нажатие комбинации клавиш Ctrl+N. После этого на экране появится окно добавления нового объекта, в нашем случае — ODBC-драйвера (рис. 4.4). Для удаления выбранного объекта выберите пункт главного меню Object i> Delete (Объект » Удалить). Кроме того, можно воспользоваться соответствующим пунктом контекстного меню или знаком косого креста на панели инструментов ВОЕ Administrator. ПРИМЕЧАНИЕ Не все объекты можно просто удалить из программы. Выбор объектов, заблокированных для удаления, не сделает доступными пункты Delete указанных меню.
Настройка ВРЕ
57
-
Рис. 4.4. Добавление нового ODBC-драйвера
.
Для отображения текущего состояния объектов левой части окна ВОЕ Administrator используются следующие обозначения: • зеленый квадрат — объект открыт для просмотра; • зеленый треугольник — объект в режиме редактирования; • зеленый треугольник с красными лучами — только что созданный объект, находящийся в режиме редактирования и еще не сохраненный в файле конфигурации; • красный треугольник — изменения, сделанные в данном объекте, являются некорректными, и он не может быть сохранен; • красный треугольник с красными лучами — новый объект, находящийся в режиме редактирования и еще не сохраненный в файле конфигурации, у которого некоторые параметры содержат некорректные значения. •
Параметры драйверов и конфигураций
Для задания или изменения параметров используемых драйверов и системных установок в программе BDE Administrator перейдите на закладку Configuration ее главного окна. После чего найдите нужный драйвер или системный параметр и измените значения параметров, отображаемых справа от выбранного объекта. Рассмотрим основные параметры драйвера dBase (рис. 4.5). • VERSION — текущая версия установленного драйвера (в нашем случае — версия 4.0). • TYPE — типиспольз; мого драйвера. Обычно может принимать два значения: Q FILE —для локальных баз данных; Q SERVER — для клиент-серверных баз данных. • LANGDRIVER — тип используемого драйвера для кодирования символов таблиц базы данных. Рекомендуем использовать кириллические шрифты, например,
58
Занятие 4. Средства для работы с базами данных
для драйвера dBase — dBase RUS ср8бб. Это необходимо для правильного отображения символов русского алфавита в приложениях, а также для корректных сортировки и преобразования записей. LEVEL — тип используемого формата таблиц базы данных для создания временных таблиц dBase. Может принимать значения: Q 7 — для формата таблиц dBase 7.0 (по умолчанию); Q 5 — для формата таблиц dBase 5.0; а 4 — для формата таблиц dBase 4.0; Q 3 — для формата таблиц dBase III и dBase III PLUS.
B-qj Configuration E • Omen Hair,! © PARADOX r-© FOXPRO
1- © MSACCESS © MSSQL МЭ SYBASE © INFORMIX ~© INTRBASE
-©DB2 -© ORAOE ODBC © SQL Serve © МкжкоЛ Access Dnv« (" mdb) © Mooreft Text Drivei f.M:" © Microsoft Excel Drivei p.xh) © Mcrosolt dBase Drivei [" dbf) © Microsoft PatadoxDirveiCdb i- © МюисЛ Visual FoxPraDnver I © M eiosotl ODBC la Oracle : © MctosoftdBaseWPOnveiCd »KtosaK FoxPro VFP Drivei (".
Рис. 4.5. Драйвер dBase и его параметры
MDX BLOCK SIZE — объем памяти на диске в байтах, зарезервированный для файлов *.mdx. Может принимать произвольное числовое значение, кратное 512. По умолчанию —1024. MEMO FILE BLOCK SIZE — объем памяти на диске в байтах, зарезервированный для файлов *.dbt Может принимать произвольное числовое значение, кратное 512. По умолчанию — 1024. ПРИМЕЧАНИЕ Параметры, выделенные полужирным начертанием, являются неизменяемыми.
iniHIIIIHIIlNllllllllll
Настройка BDE
onrigutation rV Qj Drivers В rVr% Native • ! © PARADOX 1 "*-© DBASE •' I- © FOXPRO ;••© MSACCESS i- © MSSQL ; - © SYBASE ф INFORMIX '•• © INTRBASE
i
;4.0
VERSION TYPE
sERyER isQLORAsiDLL
разе"
"
VENDOR INIT DRiyER'FLAGS
"T'RACE'MOP'E BATCH COUNT BLOB SIZE BLOBS TO CACHE ENABLE BCD
1200 ' " i32 Ml"
IWLSE
EWWLE'iNTEGEBS ENABLE SCHEMA"CACHE"
i -© DB2
В QJ ODBC i- © SQL Server ; © Miciosdl Access Olivet Cmdb) ;-© Microsoft Text Driver C.M;" © Microsoft Excel Drive f xte) ; © Microsoft dBase Drivei ("obf) © Miciosotl Paradox Driver (*.db |--© Microsoft Visual FoxPio Oliver :- © Microsoft ODBC for Oracle • © Microsoft dBase VFP Driver f.d '- © Mictosofl FoxPro VFP Dnvel f. Д Sptem INIT Formats
59
UST'SYNONYMS" MAXHOWS ..... NET PROTOCOL OBJECT MODE OPEN MODE ...... ROWSETSiZE ......
IFALSE'
;TNS iTRLIE
"!20
SCHEMACACHE'SIZE' SCHEMAiCACHETiME ~ SERVER NAME " SQLPASSTHRU MODE SQLQRYMODE ™
JSHAREDAUTOCOMMIT
TMYNAME
..1
Рис. 4.6. Драйвер Oracle и его параметры Теперь рассмотрим параметры драйвера удаленных баз данных Oracle (рис. 4.6). • VERSION — текущая версия установленного драйвера (в нашем случае — версия 4.0). • TYPE — тип используемого драйвера. Обычно может принимать два значения: a FILE — для локальных баз данных; Q SERVER — для клиент-серверных баз данных. • DLL32 — задает драйвер SQL Links для доступа к базе данных. В нашем случае - SQLORA32.DLL • VENDOR INIT — содержит название файла драйвера поставщика базы данных. Для Oracle 7 и 8 используются драйверы ORA73.DLL и OCI.DLL соответственно. • DRIVER FLAGS — внутренние, специфичные для драйвера флаги. Не изменяйте значение данного параметра самостоятельно! По умолчанию имеет значение NULL • TRACE MODE — числовой параметр, представляющий собой битовую маску. Указывает, какие значения будут записываться в файл журнала в режиме трассировки. Возможные варианты (в шестнадцатеричной системе счисления): а 1 — подготавливаемые выражения запросов (по умолчанию); Q 2 — выполняемые выражения запросов; D 4 — ошибки; Q 8 — параметры операторов; Q 10 — соединение-разрыв связи;
•
60
• • • •
• •
• • •
• •
•
• • •
Занятие 4. Средства для работы с базами данных Q 20 — транзакции; Q 40 — операции ввода-вывода, связанные с BLOB-объектами; Q 80 — прочее; а 100 — внутренние вызовы. BATCH COUNT — число измененных записей, которые могут объединяться в пакет для отправки на сервер базы данных. BLOB SIZE — определяет размер буфера (в килобайтах) для работы с BLOB-объектами. Может принимать значения от 32 до 1000. BLOBS TO CACHE — определяет, сколько записей, содержащих данные BLOB, может кэшировать приложение-клиент. Дипазон принимаемых значений от 64 до 65 535. ENABLE BCD — предписывает, будет ли использоваться формат BCD для Представления чисел в таблицах базы данных. По умолчанию имеет значение false, то есть формат BCD не используется. Если установить данный параметр в true, то операции с числами будут выполняться более точно, но скорость работы с таблицами замедлится. ENABLE INTEGERS — уточняет, нужно ли преобразовывать поля типа NUMERIC в логические целые числа. ENABLE SCHEMA CACHE — указывает, будет ли схема таблиц сервера базы данных кэшироваться на компьютерах клиента. По умолчанию установлен false — схема не кэшируется. Если вы работаете с Oracle 8, установите данный параметр в false. LANGDRIVER — нужен для указания языкового драйвера. По умолчанию имеет пустое значение. LIST SYNONYMS — регламентирует, нужно ли включать синонимы в схему таблиц при их отображении. MAX ROWS — определяет максимальное число записей, которые могут быть получены от сервера базы данных при одном запросе к нему. По умолчанию установлено значение -1, что означает отсутствие ограничений на число записей. NET PROTOCOL — используемый сетевой протокол для связи клиентов и сервера базы данных. OBJECT MODE - логический параметр должен иметь значение true для работы с Oracle 8. Это обеспечит доступ к некоторым типам объектов. В случае использования более ранних версий Oracle можно установить этот параметр в false. OPEN MODE — режим доступа к данным. По умолчанию имеет значение READ/ WRITE, что позволяет как чтение, так и изменение записей. Возможна установка в READ ONLY, если требуется только просматривать записи. ROWSET SIZE — определяет число записей, которые считываются с сервера при одном запросе к нему. По умолчанию равен 20. SCHEMA CACHE DIR — задает папку, в которой будет храниться кэшированная схема таблиц сервера базы данных. По умолчанию значение не определенр. SCHEMA CACHE SIZE — количество таблиц, схема которых может быть котирована. Диапазон значений от 0 до 32, по умолчанию — 8.
61
Настройка ВРЕ
• SCHEMA CACHE TIME — задает время хранения кэшированием схемы таблиц. Может принимать значения: Q -1 — информация о таблицах хранится до тех пор, пока база данных открыта (по умолчанию); Q 0 — информация не кэшируется; . Q 1—2 147 483 647 — информация кэшируется столько секунд, сколько указано. • SERVER NAME — имя удаленного сервера базы данных. • SQLPASSTHRU MODE — определяет способ взаимодействия BDE и сервера базы данных на уровне транзакций. • SQLQRYMODE — режим выполнения SQL-запросов. Может принимать следующие значения: Q LOCAL — запрос выполняется локально на клиентском компьютере; Q SERVER — запрос выполняется на сервере; Q по умолчанию установлено пустое значение. Это означает, что сначала запрос отправляется на сервер, и если сервер не может обеспечить его выполнение, то запрос выполняется на компьютере клиента. • USER NAME — определяет имя пользователя, которое будет содержаться в поле имени пользователя при установке соединения с удаленной базой данных. По умолчанию имеет значение MYNAME. Рассмотрим теперь системные установки. Они делятся на установки по умолчанию (INIT) и форматы (Formats). Fite*\Comm«t Гг.-
: . ..;.-',i:.-,: ,.-.!ФСУЙА««С-.
AUTO ODBC DATAHETOSiTOFri'
РЕРАШ'ОЯМЕЯ
i FALSE
PARADOX"
LAN6DRiyER ' LOCALSHARE iFALSE LOW MEMORY USAGE LIMIT ;32 2018 MAXBUFSIZE ...... MWILEHANbLES 1 'MEMSiZE' "" MINBUFSiZE
мтз'рооШб SHAREpMEMLOCATION SHAREDMEMSIZE SQLQRYMODE SYSFLAGS VERSION
"1Ш ....... IFAL'SE'"
To ii.'o
Рис. 4.7. Параметры установок по умолчанию (INIT)
I !
62
Занятие 4. Средства для работы с базами данных
Параметры установок по умолчанию (рис. 4.7): • AUTO ODBC — указывает, нужно ли импортировать установленные ODBC-драйверы и источники данных всякий раз при инициализации BDE. По умолчанию имеет значение false; • DATA REPOSITORY — содержит имя активного словаря данных; • DEFAULT DRIVER — драйвер, который устанавливается по умолчанию для каждой новой локальной базы данных. До внесения изменений имеет значение PARADOX; • LANGDRIVER — системный драйвер языка. Рекомендуется поставить какой-либо из кириллических драйверов для корректной работы с русскими буквами; • LOCAL SHARE — определяет, могут ли несколько приложений одновременно получать доступ к записям из локальной базы данных. По умолчанию параметр установлен в false, то есть единовременный доступ к данным запрещен; • LOW MEMORY USAGE LIMIT — нижний предел задействуемой BDE нижней памяти в килобайтах. По умолчанию — 32; • MAXBUFSIZE — максимальный размер памяти в килобайтах для кэширования данных. Может принимать любое целое значение в пределах от MINBUFSIZE до 65535 и кратное 128. По умолчанию равен 2048; • MAXFILEHANDLES — предельно-допустимое число дескрипторов файлов, которые будут использоваться BDE. Может принимать любое целое значение в пределах от 5 до 4096. Большие значения увеличивают производительность программы, но занимают больше ресурсов Windows. Значение по умолчанию — 48; • MEMSIZE — максимальный объем оперативной памяти в мегабайтах, который может использовать BDE. Значение по умолчанию — 16. Граничная величина — 205. Если вы установите значение более 205, под нужды BDE все равно будет выделено 205 Мбайт; • MINBUFSIZE — минимальное значение оперативной памяти в килобайтах для кэширования данных. Может принимать любое целое значение в пределах от 32 до 65 535. Должно быть меньше, чем весь объем доступной в Windows оперативной памяти. По умолчанию равно 128; • MTS POOLING — определяет, применять ли MTS-пул для более быстрого начала соединения с базой данных при ее открытии. По умолчанию — false; • SHAREDMEMLOCATION — указывает местонахождение (в оперативной памяти) менеджера разделения памяти; • SHAREDMEMSIZE — максимальный объем памяти в килобайтах, которая будет использована BDE для хранения разделяемых ресурсов. Больше или равен минимальному значению — 2048; • SQLQRYMODE — задает метод выполнения SQL-запросов; • SYSFLAGS — внутренние флаги BDE. He изменяйте находящееся в этом параметре значение; • VERSION — текущая версия данного BDE. Системные установки форматов разделяются на форматы даты, форматы времени и числовые форматы.
63
Настройка BDE
В (|j Configuration It; ^ Drivers В Ж System
M
INI! Formats
FOURDISITYEAR LEADINGZEROD LEAWNGZEROM MODE
IFALSE
IFALSE" 1 FALSE
IT
SEPARATOR"
]/'
tfffif"
Tin» Number
- -
. . •
•
• .
Рис. 4.8. Параметры форматов даты
, Параметры форматов даты (рис. 4.8): • FOURDIGITYEAR — определяет, будут ли для отображения года использоваться четыре цифры. Если значение true — будет использоваться расширенное представление, иначе — две цифры (по умолчанию); • LEADINGZEROD — указывает, будет ли добавляться к дню незначащий ноль. Например, 05 для пятого числа. Если true, то будет, иначе — нет; •
LEADINGZEROM — то же, что и LEADINGZEROD, только для месяца;
• MODE — уточняет расположение года (Г), дня (Д) и месяца (М) в числовом представлении даты. Может принимать следующие значения: О 0-МДГ; а 1-ДМГ; а 2-ГМД; • SEPARATOR — символ, который будет использоваться для разделения дня, месяца и года. По умолчанию используются текущие настройки Windows; • YEARBIASED — объявляет способ преобразования номера года, заданного двумя цифрами. Если параметр установлен в true, то к двузначному числу прибавляется 1900, иначе — значение года не изменяется. Параметры форматов времени (рис. 4.9): • AMSTRING — определяет символы, которые применяются для отображения времени до полудня. По умолчанию — AM;
64
Занятие 4. Средства для работы с базами данных
MILSECONDS — указывает, будут ли отображаться миллисекунды. По умолчанию имеет значение false, то есть миллисекунды не выводятся; PMSTRING — определяет символы, которые применяются для отображения времени после полудня. По умолчанию — РМ; SECONDS — указывает, будут ли отображаться секунды. По умолчанию установлено в true, то есть секунды отображаются; TWELVEHOUR — определяет формат вывода времени. Если параметр равен true, то время будет представляться 24-часовым циклом, иначе — 12-часовым. Шш СЛРгафот Fite
>•••
:'
AMSTRING MILSECONDS PMSTRING SECONDS TWELVEHOUR
:
ЙАРШШ
;AM FALSE
;PM iTRUE •TRUE
Рис. 4.9. Параметры форматов времени
Параметры числовых форматов (рис. 4.10): • DECIMALDIGIT — число разрядов для дробной части числа (после запятой). По умолчанию равно 2; • DECIMALSEPARATOR — определяет символ (запятая), который будет разделять целую и дробную части числа при отображении. По умолчанию используется символ из системных настроек Windows; • LEADINGZERON — указывает, будет ли добавляться незначащий нуль к числам, меньшим единицы по модулю. По умолчанию установлен в false, то есть нуль не отображается; • THOUSANDSEPARATOR — определяет символ для разделения триад в целой части числа. По умолчанию используется символ из системных настроек Windows.
Программа Database Desktop
65
ftBDE AdimnistralM СЛР.ошат FilertCommon Fafts«<»la«J St«l'«nft[>f UfiAM.Cfli
g-% Conliguation &-^ Drivers E Ж System INIT
ОШМАЙЁРАВАТОВ LEADINGZERQN THOUSANDSEPAHATOR
L :THUE !.'
Рис. 4.10. Параметры числовых форматов
ВНИМАНИЕ Все параметры, которые вы устанавливаете в программе ВОЕ Administrator, действуют только на те приложения, которые работают с ВОЕ.
Программа Database Desktop Программа Database Desktop, так же как и BDE Administrator, входит в поставку Delphi. Она предназначена для создания новых таблиц баз данных (структур) и редактирования уже существующих, а также для работы с визуальными и SQLзапросами и псевдонимами баз данных. Программу можно запустить из папки Program Files\Borland\Database Desktop, если вы устанавливали Delphi в папку по умолчанию. Имя файла программы — dbd32.exe. Можно ее запустить и непосредственно из Delphi, выбрав в главном меню Delphi пункт Tools > Database Desktop (Инструменты > Database Desktop). Рассмотрим процесс создания новой таблицы базы данных. Запустите программу Database Desktop. Теперь выберите в ее главном меню пункт File > New > Table (Файл > Создать > Таблицу). После этого появится диалоговое окно (рис. 4.11), в котором вам нужно будет выбрать тип создаваемой таблицы. По умолчанию программа предлагает тип Paradox 7. Давайте для примера выберем тип dBase IV и нажмем кнопку ОК. В результате откроется новое окно создания структуры таблицы (рис. 4.12). 3 Зж. 956
66
Занятие 4. Средства для работы с базами данных Create Tabte •
. -
-
•
:
Рис. 4.11. Окно создания новой таблицы Create dBASE IV Table: { Ufrtitlerf )
•..
-
Рис. 4.12. Окно создания структуры таблицы
Это окно позволяет: • создавать и описывать поля; • • задавать ключевые поля; • задавать индексы; • накладывать ограничения на значения полей; • задавать пароли (если они поддерживаются); • указывать используемый языковой драйвер; • задавать таблицу для выбора значений. Как мы с вами помним из занятия 1, реляционная таблица должна иметь хотя бы одно поле. Таким образом, наиболее важной функцией данного окна для нас является первая — создание и описание полей. Определим структуру таблицы, которая будет иметь следующие поля: • поле порядкового номера записи — числовое, 10 знакомест; • символьное поле имени, длина строки 25 символов; • символьное поле фамилии, длина строки 25 символов; • символьное поле адреса, длина строки 150 символов; • поле телефонного номера — числовое, 10 знакомест.
Программа Database Desktop
67
Для этого в текстовом поле Field Name (Имя поля) окна создания структуры таблицы мы вводим название поля таблицы, например NUMBER для порядкового номера записи. Затем в поле Туре (Тип) указываем тип данных, которые будет содержать данное поле (в нашем случае — N, сокращение от слова Numeric). И, наконец, в текстовое поле Size (Размер) заносим размер поля (в нашем случае — 10). Описав таким образом всю структуру, мы увидим то, что изображено на рис. 4.13. Create dBASE IV Table: ( Unfilled )
Рис. 4.13. Определение структуры таблицы
После задания структуры мы можем определить индексные поля. Для этого нужно, чтобы в правой части окна создания структуры таблиц в выпадающем списке Table properties (Свойства таблицы) был выбран пункт Indexes (Индексы), как на рис. 4.13. Теперь нажмем кнопку Define (Определить), расположенную под раскрывающимся списком. Откроется окно определения индекса (рис. 4.14).
Рис. 4.14. Окно определения индекса
Illln ill;
•:
68
Занятие 4. Средства для работы с базами данных
Выберем в качестве индексного поля поле NUMBER. При этом обеспечим уникальность значений в нем, установив флажок Unique (Уникальные). Нажмем ОК. Все, теперь можно сохранять созданную нами структуру таблицы, которая пока не содержит никаких данных. Для этого нажмем кнопку Save As... (Сохранить как). Пусть по традиции наша таблица получит имя МуТаЫе. Теперь мы можем использовать таблицу в своих программах. Например, мы вправе ее открыть и посмотреть содержимое с помощью Database Desktop. Для этого выберем пункт главного меню программы Database Desktop File > Open * Table... (Файл > Открыть > Таблица). Мы можем видеть результат своей работы на рис. 4.15. ;
Table MyTabledbf
Рис. 4.15. Таблица MyTable.dbf
Кроме непосредственного создания новой структуры таблицы, можно воспользоваться уже имеющейся структурой другой таблицы и скопировать ее в новую. Для этого воспользуйтесь кнопкой Borrow... (Заимствовать) в окне задания структуры таблицы. Вследствие ваших действий откроется окно выбора таблицы (рис. 4.16). Select BOIIOW Table
Рис. 4.16. Окно выбора таблицы для заимствования ее структуры
Работа с псевдонимами баз данных
69
Кроме копирования данных о структуре полей, вы можете продублировать и дополнительную информацию. Например, информацию о первичном индексе и т. д., установив соответствующий флажок в параметрах. Мы не будем останавливаться на тонкостях работы с программой Database Desktop сейчас. Рассмотрим такие темы, как работа с SQL-запросами и визуальное конструирование запросов, на следующих уроках.
Работа с псевдонимами баз данных Псевдонимом (alias) базы данных называется специальное имя базы данных, служащее для обозначения каталога, в котором хранятся таблицы базы данных. Наличие псевдонимов позволяет программисту писать приложения, не задумываясь над тем, куда будут помещены файлы таблиц базы данных. На практике будет использоваться псевдоним базы данных, а не указание непосредственного пути к таблицам. Таким образом, псевдонимы облегчают перенос файлов таблиц в другие папки и на другие компьютеры без изменения кода приложения.
Работа с псевдонимами в BDE Administrator Для того чтобы создать новый псевдоним базы данных, выполните указанные ниже шаги. • 1. В окне BDE Administrator перейдите на закладку Database (База данных). 2. Выберите пункт Object > New (Объект > Создать) в главном меню BDE Administrator. После этого вы увидите диалоговое окно создания нового псевдонима базы данных (рис. 4.17).
• ' Рис. 4.17. Окно создания нового псевдонима базы данных
В открывшемся окне необходимо выбрать тип драйвера базы данных. Если вы хотите создать псевдоним для таблиц Paradox или dBase локальной базы данных, используйте предлагаемый по умолчанию тип STANDARD. Для всех остальных типов таблиц выбирайте необходимый. Все поддерживаемые типы драйверов перечислены в раскрывающемся списке. Нажав кнопку ОК, можно создать новый псевдоним для таблиц типа Paradox или dBase. После этого в левой части окна BDE Administrator появится новый объект STANDARD! (рис. 4.18). Имя, задаваемое по умолчанию (STANDARD1), можно изменить с помощью команды Rename контекстного меню или аналогичной команды главного меню BDE Administrator.
70
Занятие 4. Средства для работы с базами данных
|Ш*а* & ft
5' х
%Ш .-OjEUdfis Й^
^Z^
BBS!
s
-
Databases DBDEMOS HDelaultDD к *fi IBLocal
Type DEFAULT DRIVER ENABLE BCD PATH
»=1
: :
*
•••'-^ i STANDARD rPARADOX JFALSE
ЕВ-»' База данных MS Access SE "в • • • • I
аза данных Visual FoxPro Иг БТаблицы Visual FoxPro Ё; ^) frl ш ^f вТГ
Файлы dBASE Файлы dBase -Word Файлы Excel Е- "в Файлы FoxPro -Word
;? j
* :
[ \
I •
;•
1
•
:
Г^т1ШШШ1;:;г;:,5шшШ№Рис. 4.18. Новый объект и его параметры
Как вы можете видеть, новый псевдоним для работы с локальными базами данных имеет всего три параметра (отображенных в правой части окна). • DEFAULT DRIVER — указывает на тип используемых таблиц базы данных (по умолчанию установлено значение PARADOX): Q a Q a
PARADOX — таблицы Paradox; DBASE - таблицы dBase; FOXPRO — таблицы FoxPro; ASCIIDRV — таблицы .в виде текстовых файлов.
• ENABLE BCD — показывает, будет ли использоваться формат BCD для представления чисел в таблицах базы данных. По умолчанию имеет значение false, то есть формат BCD не поддерживается. Если установить этот параметр в true, то операции с числами будут выполняться более точно, но скорость работы с таблицами замедлится. • PATH — параметр содержит путь к базе данных, то есть адресует каталог, в котором находятся таблицы базы данных. По умолчанию конкретный путь не указан (пустое значение), поэтому нужно задавать его самостоятельно. Таким образом, если ваша база данных имеет тип Paradox, то можно оставить первые два параметра так, как они заданы по умолчанию, и прописать путь в третий параметр, например: C:\MyDB.
HI
Программа Data Pump
71
ПРИМЕЧАНИЕ При задании новых псевдонимов для удаленных баз данных в окне BDE Administrator может отображаться больше трех параметров (обычно от десяти до тридцати).
Работать с псевдонимами баз данных позволяют и другие программы, например приложение Database Desktop.
Работа с псевдонимами в Database Desktop Возможность использовать псевдонимы в программе Database Desktop предоставляет инструментальное средство, которое называется Alias Manager (рис. 4.19).
Рис. 4.19. Окно Alias Manager
Покажем, как с помощью Alias Manager можно создавать новые псевдонимы. Для этого нажмите кнопку New. Затем введите название нового псевдонима в окне Database alias (Псевдоним базы данных), выберите тип драйвера и путь к каталогу базы данных. Для сохранения изменений используйте кнопку Save As.... По умолчанию вам будет предложено сохранить изменения в файле конфигурации idapi.cfg. Для удаления псевдонима служит кнопка Remove (Удалить).
Программа Data Pump Программа Data Pump предназначена для копирования данных из одной базы данных в другую. В терминах Delphi первая база данных называется источником, а вторая — приемником. В" результате копирования в приемнике автоматически будут созданы таблицы с такими же именами, структурой и содержимым, что и в источнике. Начать работать с программой Data Pump можно, используя пункт меню Пуск среды Windows Программы > Borland Delphi б > DataPump или. же запустив исполняемый файл datapump.exe, устанавливаемый по умолчанию в каталог Program Files\Common FHes\Borland Shared\BDE.
IHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIINI'I
72,
Занятие 4. Средства для работы с базами данных
При запуске программы вы проследуете по цепочке окон, переход между которыми осуществляется с помощью кнопок Next (Далее) и Back (Назад), внешне напоминающих кнопки обычного Мастера (Wizard). Первое окно, которое открывается при запуске программы, — это окно выбора псевдонима источника (рис. 4.20). ' Data Pump - Select Source Alias
DefaultDD IBLocal База данных MS Access База данных Visual FoxPro Т аблицы Visual FoxPro Файлы dBASE Файлы dBase-Word Файлы Excel Файлы FoxPro-Word Sei;
:
•
Рис. 4.20. Окно выбора псевдонима источника
В этом окне вы можете указать псевдоним базы данных, которая будет использована в качестве источника (Select by alias name, Выбрать по псевдониму), или задать папку, в которой расположены таблицы базы данных источника (Select by directory, Выбрать по папке). После выбора источника нажимаем кнопку Next и переходим к следующему окну, которое позволяет выбрать псевдоним приемника (рис. 4.21).
I IBLocal I База данных MS Access IБ аза данных Visual FoxPro | Таблицы Visual FoxPro 1 Файлы dBASE I Файлы dBase-Word 1 Файлы Excel |файяы FoxPro-Word
Рис. 4.21. Окно выбора псевдонима приемника
Программа Data Pump
73
Работа с этим окном аналогична работе с предыдущим, за исключением того, что псевдоним папки приемника должен быть отличен от псевдонима папки приемника. После выбора получателя нажимаем Next и переходим в окно выбора таблиц для перемещения (рис. 4.22).
Ыа «ow bottom mow all tables
btoWe.db cfents.dbf country,* custolydb customer, db employee db events db holdinrjs dbf industry dbf items db master dbf nexr.cust.db nextitem db nextofd.db '.'' • ~'4:
' '''I.
Рис. 4.22. Окно
i таблиц для перемещения
В этом окне предлагается выбрать таблицы, которые можно скопировать. На последнем шаге открывается окно проверки или изменения элементов (рис. 4.23).
ею'. When alithftneoessaj) Wotmsbns moc8t»4
'
Modify Т able Name of Field Mapping Information fat Selected Hen
Рис. 4.23. Окно проверки или изменения элементов
Изменить структуру можно при нажатии кнопки Modify table Name or Field Mapping Information For Selected Item (Изменить имя таблицы или информацию о расположении полей для выбранных единиц).
74
Занятие 4. Средства для работы с базами данных
ПРИМЕЧАНИЕ Изменение структуры будет осуществлено только в таблицах приемника и не затронет исходные таблицы.
При нажатии данной кнопки будет вызвано окно изменения полей и имени таблицы (рис. 4.24). П,,,,,И|МИИИ.ИИИИ,,,И,
Рис. 4.24. Окно изменения полей и имени таблицы
В столбце Source (Источник) указаны значения исходной таблицы, а в столбце Target (Цель) — значения таблицы-приемника. После проведенных изменений нажмите кнопку Upsize (Перенести). Программа Data Pump отобразит индикатор выполнения процесса копирования данных, затем выдаст отчет о результатах.
Архитектура dbExpress DbExpress представляет собой кросс-платформенный независимый от используемой базы данных механизм, обеспечивающий выполнение динамических SQL-запросов. При его посредстве организуется общий интерфейс для доступа к различным SQL-серверам. Для каждого из поддерживаемых серверов dbExpress имеет драйвер, который действует как независимая библиотека dbExpress для выполнения запросов и хранимых процедур. Драйверы dbExpress доступны как из среды Windows в виде файлов *.dll, так и в среде Linux (файлы *.so). dbExpress не задействует все возможности BDE, но является более простым и удобным при распространении собственного продукта. Ядро dbExpress содержит четыре интерфейса: • ISQLDriver — инициализирует механизм и захватывает необходимые ресурсы; • ISQLConnection — устанавливает соединение с базой данных;
Что нового мы узнали?
75
• ISQLCommand — обеспечивает выполнение методов для SQL-запросов и хранимых процедур; • ISQLCursor — содержит данные и метаданные, возвращаемые запросом или при выполнении хранимой процедуры. Все вышеперечисленные интерфейсы содержатся в модуле DBXpress.pas. Более подробно работу с dbExpress мы рассмотрим на занятии, посвященном изучению компонентов для работы с локальными базами данных. /-
Что нового мы узнали? На этом занятии мы узнали: • что такое BDE и его архитектура; • для чего нужны программы BDE Administrator и Database Desktop; • • • •
как создать новую таблицу; как создать новый псевдоним базы данных; для чего применяется программа Data Pump; а также кратко познакомились с механизмом dbExpress.
..
' •
'
-
. . :
. -
'
Занятие 5 Палитра компонентов и работа с базами данных Компоненты для работы с локальными базами данных Операции с таблицами Сортировка набора данных Перемещение по набору данных Фильтры Поиск
На этом занятии вы познакомитесь с той частью палитры компонентов Delphi 7, которая содержит компоненты для работы с локальными наборами данных. Также мы рассмотрим основные операции над данными, такие как перемещение по записям, сортировка данных, фильтрация, добавление и удаление записей. В конце занятия мы изучим тонкости работы со связанными таблицами.
Компоненты для работы с локальными базами данных Среда Delphi предоставляет разработчику набор компонентов, предназначенных для работы с локальными базами данных. Доступ к этим компонентам осуществляется с закладок палитры компонентов: Data Access (Доступ к данным), Data Controls (Управление данными), dbExpress и ВОЕ. Рассмотрим их последовательно. Начнем с закладки Data Access (рис. 5.1). На этой закладке расположены шесть компонентов, которые обеспечивают работу с информацией, хранящейся в базе данных. Следует отметить, что эти компоненты не связаны с каким-либо конкретным механизмом доступа к данным, таким как ВОЕ или dbExpress. В любом случае в своих приложениях вам придется использовать некоторые компоненты для работы с данным и (например, компонент DataSource).
Компоненты для работы с локальными базами данных
.
77
Рис. 5.1. Закладка Data Access
j Итак, рассмотрим все шесть компонентов закладки Data Access по порядку (слева направо). Компонент DataSource (источник данных) работает как промежуточное звено и предназначен для связывания компонента набора данных (TDataSet) и компонента, отображающего данные (например, TDBGrid). Может применяться также для установки связи «главный—подчиненный» между двумя наборами данных. Свойства компонента DataSource, которые отображаются в окне инспектора объектов, мы уже рассматривали на занятии 3. Поэтому перейдем сразу к изучению методов и событий. Таблица 5.1 содержит названия методов компонента DataSource и их краткое описание. Таблица 5.1. Методы компонента DataSource Название метода
Краткое описание
Create
Создает экземпляр компонента типа TDataSource во время выполнения приложения Удаляет экземпляр компонента типа TDataSource во время выполнения приложения. Внимание! Не вызывайте сами метод Destroy, так как он не проверяет состояние свойства DataSet компонента. Вместо вызова данного метода используйте более безопасный метод Free Если возможно, устанавливает набор данных, на который ссылается источник данных, в режим редактирования Корректно удаляет экземпляр объекта типа TDataSource во время выполнения приложения Применяется для проверки, связан ли источник данных с указанным набором данных. Возвращает true, если связан, и false — в противном случае
Destroy
Edit Free IsLinkedTo
Теперь рассмотрим события компонента DataSource (табл. 5.2). Все эти события можно увидеть, перейдя на закладку Events (События) в окне инспектора объектов при выбранном компоненте DataSource. , Таблица 5.2. События компонента DataSource Событие
Краткое описание
OnDataChange
Происходит, когда данные в записи изменяются или при перемещении курсора на новую запись Возникает, если состояние набора данных, на который ссылается DataSource, изменяется. Например, при переходе из режима просмотра (dsBrowse) в режим редактирования (dsEdit) Наступает, когда ожидается обновление текущей записи, то есть перед посылкой текущей записи в базу данных
OnStateChange OnUpdateData
-
Следующий компонент закладки DataAccess — это ClientDataSet. Этот компонент представляет собой независимый от типа базы данных набор данных.
L
78
Занятие 5. Палитра компонентов и работа с базами данных
Рассмотрим свойства компонента ClientDataSet, которые отображаются в окне инспектора объектов (табл. 5.3). Таблица 5.3. Свойства компонента ClientDataSet
-
Название свойства
Тип свойства
Краткое описание
Active
Boolean
Aggregates
TAgg regales
AggregatesActive
Boolean
AutoCalcFields
Boolean
CommandText
String
Connection'Broker
TConnectionBroker
Constraints
TCheckConstraints
DataSetFilld
TDataSetField
DisableStringTrim
Boolean
FetchOnDemand
Boolean
FieldDefs
TFieldDefs
FileName
String
Определяет, является ли набор данных открытым. Если свойство имеет значение False, то набор данных закрыт и с данными ничего не может сделать ни пользователь, ни программа. Если свойство имеет значение True, то с данными можно осуществлять произвольные действия (изменять, добавлять, удалять и т. д.) Содержит список всех агрегатов, которые имеет набор данных. Вы можете использовать это свойство для хранения объектов типа TAggregate, каждый из которых описывает формулу, по которой вычисляется агрегированное значение из группы записей клиентского набора данных Определяет, будет ли клиентский набор данных вычислять и поддерживать агрегированные значения Определяет, как будет осуществляться работа с автоматически вычисляемыми полями. Если значение свойства — True, то значения таких полей будут автоматически вычисляться в случае открытия набора данных, перевода набора данных в режим редактирования (dsEdit) или передачи фокуса с одного визуального компонента на другой или из одной колонки визуального компонента в другую Содержит запрос на языке SQL, который должен быть выполнен сервером базы данных Определяет брокер связи, который будет применяться для осуществления связи с сервером приложения Определяет накладываемые ограничения на редактирование записей набора данных Применяется, если набор данных является подчиненным по отношению к другому — главному набору данных (отношение «master—detail»). Свойство содержит название поля главного набора данных, по которому производится связь главного и подчиненного набора данных Определяет, будут ли незначащие пробелы во вновь введенном значении поля сохраняться в таблице базы данных или они будут отсекаться. Если значение свойства — false (по умолчанию), то незначащие пробелы в начале и конце значения будут удалены перед помещением записи в таблицу. Иначе значение записывается «как есть» Указывает, будут ли пакеты данных считываться только тогда, когда они необходимы. Если значение данного свойства — true (по умолчанию), пакеты данных будут считываться только в случае их необходимости (например, при перемещении на новую запись или при поиске) Содержит описание списка полей набора данных. Служит для задания полей и их типов для набора данных Определяет имя файла, который хранит записи клиентского набора данных
Компоненты для работы с локальными базами данных
79
Название свойства
Тип свойства
Краткое описание
Filter
String
Filtered
Boolean
FilterOptions
TFilterOptions
IndexDefs
TIndexDefs
IndexFieldNames
String
IndexName
String
MasterFields
String
MasterSource
TDataSource
Name
TComponentName
ObjectView
Boolean
PacketRecords
Integer
Params
TParams
Назначает текущий фильтр для набора данных. Фильтр применяется для отбора и отображения нужных записей (удовлетворяющих каким-либо требованиям) Указывает, будет ли применяться фильтр, указанный в свойстве Filter, к записям набора данных. Если значение свойства — true, то фильтр будет задействован. Если false (no умолчанию), фильтр не используется Определяет, будет ли фильтр чувствителен к регистру символов и можно ли проводить частичные сравнения (то есть сравнения по нескольким символам, входящим в слово) Содержит информацию об индексах клиентского набора данных Содержит список полей набора данных, которые используются в качестве индексных Задает альтернативный индекс для клиентского набора данных. Если значение свойства не пустое, то при сортировке набора данных будет использоваться индексное поле, указанное в нем. Иначе будет производиться сортировка по одному из индексных полей, указанных в двойстве IndexFieldNames Содержит имя одного или нескольких полей главной таблицы для связи их с соответствующими полями набора данных и установки отношения «master—detail» Определяет компонент — источник данных типа TDataSource, свойство DataSet которого указывает на главную таблицу и устанавливает взаимоотношение «master—detail» Устанавливает имя набора данных, которое будет использоваться в коде приложения. По умолчанию присваиваются имена ClientDataSetl, ClientDataSet2, ..., ClientDataSetN Определяет, как в свойстве Fields будут храниться названия полей. Если значение свойства — true (по умолчанию), то поля будут храниться в иерархическом виде, иначе они будут представлены в так называемом «выровненном виде» Количество записей, которое может содержаться в одном пакете, передаваемом с сервера. По умолчанию содержит значение -1, что означает неограниченное число записей. Если значение равно 0, то данные с сервера не будут передаваться, будет посылаться лишь информация о структуре базы данных. Если значение свойства содержит любое целое число больше нуля, то оно будет определять количество записей в одном пакете Определяет значения параметров, которые отсылаются провайдеру Содержит имя компонента провайдера, который передает данные и производит изменения данных. Используется для указания внешнего провайдера, связанного с другим набором данных
,.
ProviderName
String
продолжение &
litHllltlllir
80
Занятие 5. Палитра компонентов и работа с базами данных
Таблица 5.3 (продолжение) Название свойства
Тип свойства
Readonly
Boolean
RemoteServer StoreDefe
Краткое описание
Определяет, будет ли набор данных поддерживать редактирование, вставку и удаление записей. Если значение свойства — true, то набор данных будет доступен только для чтения. Если значение свойства — false (по умолчанию), то набор данных доступен для любых операций TCustomRemoteServer Компонент, который будет использоваться набором данных для связи с сервером базы данных Boolean
Указывает, будут ли сохраняться определения полей и индексов в модуле данных или в форме. Если значение свойства — true (по умолчанию), то они будут сохраняться, иначе — не будут
ПРИМЕЧАНИЕ Здесь и далее при рассмотрении свойств компонентов мы не будем описывать свойство Tag, которое присутствует у большинства компонентов Delphi. Скажем лишь, что данное свойство предназначено для использования его по усмотрению программиста.
Рассмотрим третий компонент закладки DataAccess, который называется DataSetProvider. Этот компонент представляет собой провайдер данных, выполняющий задачу снабжения данными из других наборов данных. Таблица 5.4 содержит описание свойств компонента DataSetProvider.
Таблица 5.4. Свойства компонента DataSetProvider Название свойства
Тип свойства
Краткое описание
Constraints
Boolean
DataSet Exported
TDataSet Boolean
Указывает, будут ли отправляться ограничения целостности провайдером данных. Если значение свойства — true (по умолчанию), то ограничения целостности пересылаются, иначе — нет Задает набор данных, с которым работает провайдер
Name
TComponentName
Options
TProviderOptions
ResolveToDataSet
Boolean
Определяет, будет ли приложение-клиент передавать вызовы провайдеру данных, когда он находится в приложении-сервере, с привлечением интерфейса lAppServer. Если значение — true (по умолчанию), то будет, иначе — нет Имя для данного компонента, которое будет использоваться в коде приложения. По умолчанию присваиваются имена DataSetProviderl, DataSetProvider2,..., DataSetProviderN Определяет набор опций, показывающих, как провайдер данных будет взаимодействовать с клиентским набором данных. Содержит 15 опций, каждая из которых может принимать одно из двух значений: true или false Определяет, каким образом будут обновляться измененные данные. Если значение свойства — true, то изменения данных будут происходить на уровне набора данных. Если значение свойства — false (по умолчанию), ть изменения будут передаваться напрямую серверу базы данных
Компоненты для работы с локальными базами данных Название свойства
Тип свойства
UpdateMode
TUpdateMode
81
Краткое описание Описывает, как провайдер данных будет искать записи Чцля применения обновлений данных. Может принимать одно из трех значений: upWhereAII (по умолчанию) — поиск по всем полям; upWhereChanged — по ключевым полям и полям, значения которых были изменены; upWhereKeyOnly — только по ключевым полям
Рассмотрим следующий компонент закладки Data Access, который называется XMLTransform. Этот компонент предназначен для преобразования XML-документа в пакет данных, а также для выполнения обратного преобразования. Основные свойства компонента XMLTransform, которые отображаются в окне инспектора объектов, представлены в табл. 5.5. Таблица 5.5. Свойства компонента XMLTransform Название свойства
Тип свойства
Краткое описание
Name
TComponentName
SourceXmlFile
String
Определяет имя компонента, которое затем будет использовано в коде приложения. По умолчанию присваиваются значения XMLTransforml, XMLJransform2, ..., XMLTransformN Имя XML-документа или пакета данных, который будет преобразован Определяет имя файла, содержащего инструкции по преобразованию данных
TransformationRle String
Компонент XMLTransform имеет единственный собственный (не унаследованный от родителей) метод, который носит имя TransformXML. Описывается следующим образом: function TransformXMLCconst SourceXML: string; const ATransformationFile: string = ""); string; Этот метод непосредственно выполняет преобразование данных. В таблице 5.6 перечислены события компонента XMLTransform и приведено их краткое описание. Таблица 5.6. События компонента XMLTransform
-
Событие
Краткое описание
AfterEachRow AfterEachRowSet
Наступает после преобразования каждой записи пакета данных Происходит после преобразования всего пакета данных либо после преобразования вложенного набора данных Происходит перед преобразованием каждой записи пакета данных Возникает перед преобразованием всего пакета данных либо перед преобразованием вложенного набора данных Происходит, если компонент должен преобразовать кусок данных, определенный пользователем
BeforeEachRow BeforeEachRowSet OnTranslate
Следующий компонент, расположенный на рассматриваемой нами закладке палитры компонентов, называется XMLTransformProvider. Этот компонент предназначен
'"""""""
ntllllllllll
82
Занятие 5. Палитра компонентов и работа с базами данных
для передачи данных из XML-документа в клиентский набор данных и передачи измененных данных обратно. Рассмотрим свойства компонента XMLTransformProvider, которые отображаются в окне инспектора объектов (табл. 5.7). Таблица 5.7. Свойства компонента XMLTransformProvider Название свойства
Тип свойства
Краткое описание
CacheData
Boolean
Указывает, будет ли провайдер кэшировать в памяти пакеты данных после их загрузки из исходного XML-документа. Если значение свойства — false (no умолчанию), то всякий раз при необходимости отображения записей или при применении сделанных изменений в записях будет производиться чтение данных из исходного XML-документа. Иначе данные будут кэшироваться в памяти, что улучшает быстродействие, но требует больше системных ресурсов
Name
TcomponentName
TransformRead
TXMLTransform
TransformWrite
TXMLTransform
XMLDataFile
String
Имя компонента, идентифицирующее его в коде программы. По умолчанию присваиваются имена XMLTransformProviderl, XMLTransformProvider2, ..., XMLTransformProviderN Определяет компонент типа TXMLTransform, который будет преобразовывать данные из исходного XML-документа в пакеты данных Определяет компонент типа TXMLTransform, который будет преобразовывать пакеты данных в формат исходного XML-документа Указывает имя файла исходного XML-документа, с которым будет работать провайдер
Перечислим основные события компонента XMLTransformProvider (табл. 5.8). Таблица 5.8. События компонента XMLTransformProvider Событие
•
Краткое описание
AfterApplyUpdates
Происходит после того, как провайдер утверждает сделанные изменения
AfterGetRecords
Возникает после того, как провайдер создал пакет данных для пересылки его клиентскому набору данных
AfterRowRequest
Происходит после получения провайдером новой информации о текущей записи Возникает перед тем, как провайдер применит изменения, передаваемые клиентским набором данных
BeforeApplyUpdates BeforeGetRecords
Происходит перед тем, как провайдер создаст пакет данных и отправит его клиентскому набору данных
BeforeRowRequest
Возникает перед созданием провайдером пакета данных с информацией о текущей записи Имеет место в момент вызова метода DataRequest
OnDataRequest
Нам осталось разобрать последний компонент закладки Data Access, перед тем как перейти к рассмотрению компонентов следующей закладки. Итак, последний компонент называется XMLTransformClient Он применяется для осуществления преобразования данных, поступающих от провайдера в XML-документ. , Свойства этого компонента описываются в табл. 5.9.
Компоненты для работы с локальными базами данных
83
Таблица 5.9. Свойства компонента XMLTransformClient Название свойства
Тип свойства
Name
TComponentName
Краткое описание
Определяет имя компонента, которое будет идентифицировать его в коде программы. По умолчанию присваиваются имена XMLTransformClientl, XMLTransfbrmClient2,..., XMLTransformClientN ProviderName String Определяет имя компонента провайдера, с которым связан данный компонент RemoteServer TCustomRemoteServer Имя компонента удаленного сервера, обеспечивающего соединение с приложением-сервером TransformApplyTXMLTransfbrm Компонент типа TXMLTransform, который будет преобраUpdates зовывать XML-данные в пакеты, которые затем будут передаваться провайдеру для применения сделанных изменений TransfbrmGetData TXMLTransform Определяет компонент типа TXMLTransform, требуемый для преобразования пакетов данных в формат XML TransformSetTXMLTransform Определяет компонент типа TXMLTransform, который Params будет преобразовывать параметры XML в формат пакета данных
Следующая закладка, которую мы рассмотрим на текущем занятии, носит название Data Controls (рис. 5.2).
Рис. 5.2. Закладка Data Controls
Эта закладка содержит 15 компонентов, предназначенных для отображения записей из наборов данных в форме вашего приложения. Давайте изучим эти компоненты слева направо. При этом мы не будем подробно описывать свойства, события и методы этих компонентов так, как было сделано для компонентов предыдущей закладки, чтобы не увеличивать объем книги. Основные свойства, события и методы, характерные для компонентов закладки Data Controls, мы рассмотрим в процессе работы с ними. Первый по порядку компонент на закладке Data Controls носит название DBGrid. Он предназначен для отображения и редактирования данных в табличном виде, похожем на лист электронной таблицы. Посредством этого компонента можно вставлять новые записи, удалять или редактировать уже существующие или просто просматривать записи. Во время выполнения приложения пользователи могут работать с данными, отображаемыми в компоненте DBGrid, так же, как в электронных таблицах, либо с помощью специального компонента DBNavigator, расположенного на закладке Data Controls сразу после компонента DBGrid. DBNavigator применяется для перемещения по записям активного набора данных, а также вставки, удаления, модификации и помещения данных в таблицу базы данных. Визуально этот компонент представляет собой панель, состоящую из кнопок (рис. 5.3), каждую из которых можно отключить или включить с помощью свойства VisibleButtons.
•
,*
84
Занятие 5. Палитра компонентов и работа с базами данных
* -. *1 ^' xr<*l i• * Рис. 5.3. Компонент DBNavigator
Следующий компонент закладки Data Controls носит имя DBText и служит для отображения значения какого-либо поля текущей записи. Данный компонент не может применяться для изменения значения поля или ввода нового значения пользователем. Для этого можно использовать компонент DBEdit, который мы и рассмотрим далее. Компонент DBEdit следует за компонентом DBText и предназначен как для отображения значения какого-либо поля текущей записи, так и для внесения изменений в это значение. Следующий компонент называется DBMemo и используется для отображения или редактирования содержимого BLOB-поля текущей записи. Компонент DBImage расположен после DBMemo и предназначен для отображения и копирования графического изображения, находящегося в BLOB-поле текущей записи. Компонент DBLJstBox служит для отображения списка значений из поля (столбца) таблицы и выбора одного из них. Применяется, когда нужно, чтобы пользователь ввел одно из фиксированных значений. Компонент DBComboBox используется для отображения списка значений из столбца таблицы с возможностью одиночного выбора, а также поддерживает ручной ввод произвольного значения данного поля текущей записи. Компонент DBCheckBox предназначен для отображения или редактирования значений полей текущей записи, содержащих данные булевского типа. Компонент DBRadioGroup отображает переключатель, то есть группу кнопок, которые соответствуют значениям набора полей булевого типа. Следующий компонент закладки Data Controls называется DBLookupLJstBox. Этот компонент предназначен для вывода списка значений, который формируется по полю другого набора данных. Пользователь может с помощью данного списка выбрать значение поля текущей записи. Компонент DBLookupComboBox применяется для отображения списка значений из поля другого набора данных с возможностью одиночного выбора, а также поддерживает ручной ввод произвольного значения данного поля текущей записи. Компонент DBRichEdit задействуется для вывода или изменения значения поля текущей записи, которое может содержать форматированный текст. Таким образом, этот компонент представляет собой полнофункциональный текстовый редактор. Компонент DBCtrlGrid предназначен для отображения множества значений полей множеством записей в табличной форме. Каждая ячейка такой таблицы связана с множеством полей одной записи, то есть каждая запись таблицы отображается на своей собственной панели (или в персонально выделенной ячейке таблицы). Последний компонент закладки Data Controls называется DBChart и служит для построения и визуализации диаграмм по значениям полей набора данных. Переходим к рассмотрению закладки dbExpress (рис. 5.4), которая появилась в Delphi 6 и предназначена для работы с наборами данных с помощью нового механизма доступа к данным, который называется dbExpress.
Компоненты для работы с локальными базами данных
85
Рис. 5.4. Закладка dbExpress
Эта закладка содержит семь компонентов, которыми мы сейчас и займемся. Рассматривать кнопки будем как обычно — слева направо. Компонент SQLConnection предназначен для обеспечения связи с сервером базы данных dbExpress. Аналогом этого компонента в BDE является компонент Database. Некоторые свойства компонента SQLConnection описаны в табл. 5.10. Таблица 5.10. Свойства компонента SQLConnection Свойство
Описание
Фиксирует, установлена ли связь с базой данных (тип Boolean). Если связь установлена, свойство имеет значение true, иначе — false Содержит имя конфигурации. Имеет тип String. Является аналогом ConnectionName свойства AliasName в Delphi DriverName Содержит имя драйвера, необходимого для соединения с базой данных (DB2, Interbase, Oracle или MySQL). Имеет тип String. Данное свойство устанавливается автоматически после задания значения свойства ConnectionName Определяет, нужно ли поддерживать соединение с сервером базы данKeepConnection ных, если в приложении нет активных наборов данных. Имеет тип Boolean. Если связь необходимо поддерживать, установите это свойство в true, иначе — false Содержит имя библиотеки, в которой находится необходимый драйвер Libra ryName для связи с базой данных. Свойство имеет тип String LoadParamsOnConnect Определяет, нужно ли загружать параметры соединения перед его установлением во время работы приложения. Имеет тип Boolean Указывает, нужно ли при установке соединения запрашивать имя LoginPrompt пользователя и пароль. Имеет тип Boolean. Если — true, то нужно, иначе — не нужно В этом свойстве вы можете указать имя компонента SQLConnection. Name Имеет тип TComponentName D Устанавливает параметры соединения. Имеет тип TStrings arams TableScope Устанавливает параметры видимости таблиц базы данных. Имеет тип TTableScopes и может принимать следующие значения: TsSynonym — видимые синонимы; TsSysTable — видимые системные таблицы; TsTable — видимые таблицы пользователей; TsView — видимые \ представления VendorLib Указывает имя библиотеки клиентской части базы данных. Имеет тип String Connected
Компонент SQLDataSet представляет собой однонаправленный набор данных, который работает с базами данных с помощью механизма dbExpress. В таблице 5.11 перечислены его основные свойства. Таблица 5.11. Свойства компонента SQLDataSet Свойство
Описание
Active
Определяет, является ли набор данных активным. Только активный набор данных может работать с записями таблиц. Свойство имеет тип Boolean. Если значение — true, набор данных активен, иначе — неактивен продолжение #
86
Занятие 5. Палитра компонентов и работа с базами данных
Таблица 5.11 (продолжение) Свойство
Описание
CommandText
Содержит текст запроса SQL на выполнение каких-либо действий с данными. Имеет тип String Определяет тип набора данных. Значение свойства имеет тип TSQLCommandType. Свойство может принимать следующие значения: CtQuery — обычный SQL-запрос; CtTable — таблица целиком, при этом автоматически будет сгенерирован запрос на выборку всех записей таблицы по всем полям; CtStoredProc — процедура, хранимая на сервере базы данных Указывает источник данных для этого набора данных. Имеет тип TData Source Определяет максимальный размер BLOB-полей. Имеет тип Integer Включает или выключает иерархическое представление для вложенных полей. Имеет тип Boolean Указывает, нужно ли обновлять список параметров при изменении текста запроса (свойство CommandText). Имеет тип Boolean Определяет список параметров запроса. Имеет тип Tparams Содержит список наименований полей таблицы, по которым будет производиться сортировка набора данных. Имена полей разделяются точкой с запятой. Имеет тип String. Свойство активно только при установленном типе набора данных CtTable в свойстве CommandType Содержит имя компонента SQLConnection, с помощью которого будет осуществляться соединение с базой данных. Имеет тип TSQLConnection
CommandType
DataSource MaxBlobSize ObjectView ParamCheck :
Params SortFieldNames
•• :-
SQLConnection
-
Компонент SQLQuery представляет собой компонент, позволяющий создавать и выполнять однонаправленные SQL-запросы для работы с таблицами баз данных, использующих механизм dbExpress. Таблица 5.12 содержит описание основных свойств этого компонента. Таблица 5.12. Свойства компонента SQLQuery Свойство
Описание
Active s
DataSource MaxBlobSize ObjectView ParamCheck Params SQL SQLConnection
Определяет, является ли запрос активным. Только активный запрос может работать с записями таблиц. Свойство имеет тип Boolean. Если значение — true, запрос активен, иначе — неактивен Указывает источник данных для набора данных. Имеет тип TDataSource Определяет максимальный размер BLOB-полей. Имеет тип Integer Включает или выключает иерархическое представление для вложенных полей. Имеет тип Boolean Указывает, нужно ли обновлять список параметров при изменении текста запроса (свойство CommandText). Имеет тип Boolean Определяет список параметров запроса. Имеет тип TParams В этом свойстве содержится текст SQL-запроса. Имеет тип TStrings Содержит имя компонента SQLConnection, обеспечивающего соединение с базой данных. Имеет тип TSQLConnection
Компонент SQLStoredProc предназначен для работы с хранимой на сервере базы данных процедурой. Выполнение этой процедуры будет осуществляться с помощью механизма dbExpress. При получении данных ведет себя однонаправлено. Основные свойства этого компонента и их краткое описание представлены в табл. 5.13.
-
Компоненты для работы с локальными базами данных
87
Таблица 5.13. Свойства компонента SQLStoredProc Свойство
Описание
Active
Определяет, является ли процедура, хранимая на сервере, активной. Имеет тип Boolean Определяет максимальный размер BLOB-полей. Имеет тип Integer Включает или выключает иерархическое представление для вложенных полей. Имеет тип Boolean Указывает, нужно ли обновлять список параметров при изменении процедуры. Имеет тип Boolean Определяет список параметров процедуры. Имеет тип TParams Содержит имя компонента SQLConnection, с помощью которого будет осуществляться соединение с базой данных. Имеет тип TSQLConnection Содержит название хранимой на сервере процедуры, с которой связан данный компонент и которая будет вызываться на сервере. Имеет тип String
MaxBlobSize ObjectView ParamCheck Params SQLConnection StoredProcName
Компонент SQLTable задает таблицу базы данных dbExpress и представляет собой однонаправленный набор данных. Таблица 5.14 содержит описание основных свойств указанного компонента. Таблица 5.14. Свойства компонента SQLTable Свойство
Описание
Active
Определяет, является ли таблица активной. Только активная таблица может работать с записями. Свойство имеет тип Boolean Содержит список наименований полей таблицы, по которым будет производиться сортировка набора данных. Имена полей разделяются точкой с запятой. Имеет тип String Имя индекса, по которому будет произведена сортировка набора данных. Имеет тип String Содержит имя главного источника данных при организации связи таблиц «главная—подчиненная» («master—detail»). Имеет тип TDataSource Содержит имена полей, по которым осуществляется связь между главной и подчиненной таблицами. Имеет тип String Определяет максимальный размер BLOB-полей. Имеет тип Integer Включает или выключает иерархическое представление для вложенных полей. Имеет тип Boolean Содержит имя компонента SQLConnection, с помощью которого будет осуществляться соединение с базой данных. Имеет тип TSQLConnection Имя таблицы базы данных, с которой будет производиться работа. Имеет тип String ___
IndexfieldNames
IndexName MasterSource MasterRelds MaxBlobSize ObjectView SQLConnection
i
TableName
Компонент SQLMonitor предназначен для перехвата сообщений, проходящих между компонентом SQLConnection и сервером базы данных, и сохранения их в списке. Таким образом, с помощью этого компонента можно организовать наблюдение за работой компонентов доступа к данным. В таблице 5.15 перечислены основные свойства компонента SQLMonitor. Таблица 5.15. Свойства компонента SQLMonitor Свойство
Описание
Active AutoSave
Определяет, является ли монитор активным. Свойство имеет тип Boolean Определяет, будет ли производиться автоматическое сохранение событий в файле, указанном в свойстве FileName данного компонента. Имеет тип Boolean продолжение &
88
Занятие 5. Палитра компонентов и работа с базами данных
Таблица 5.15 (продолжение) Свойство
Описание
FileName SQLConnection
Имя файла, в который будет производиться запись событий. Имеет тип String Содержит имя компонента SQLConnection, с помощью которого будет осуществляться соединение с базой данных. Имеет тип TSQLConnection Имя файла журнала событий. Имеет тип TString
TraceList
Компонент SQLCIientDataSet служит для кэширования информации в памяти и сохранения любых изменений данных, сделанных приложением. В таблице 5.16 приведены основные свойства этого компонента. Таблица 5.16. Свойства компонента SQLCIientDataSet Свойство
Описание
Active
Определяет, является ли набор данных активным. Свойство имеет тип Boolean Содержит список доступных агрегатов. Имеет тип TAggregates Определяет, нужно ли производить вычисления агрегатов. Имеет тип Boolean Определяет, нужно ли генерировать событие OnCalcFields и обновлять содержимое полей. Имеет тип Boolean. Принимает значение true при открытии набора данных, при переключении набора данных в состояние DsEdit или при передаче фокуса другому компоненту формы Содержит текст SQL-запроса. Имеет тип String. При установленном значении свойства FileName это свойство игнорируется. Свойство игнорируется также и в случае, когда в свойстве Options сброшен флажок poAllowCommandText Определяет тип набора данных. Значение свойства имеет тип TSQLCommandType. Свойство может принимать следующие значения: CtQuery — обычный SQL-запрос; CtTable — таблица целиком, при этом автоматически будет сгенерирован запрос на выборку всех записей таблицы по всем полям; CtStoredProc — процедура, хранимая на сервере базы данных Содержит имя конфигурации. Имеет тип String. Является аналогом свойства AliasName в ВОЕ Накладывает ограничения на значение на уровне одной записи. Имеет тип TConstraints Определяет имя компонента SQLConnection, с помощью которого будет производиться работа с базой данных. Имеет тип TSQLConnection Предписывает, нужно ли удалять лишние пробелы в конце строки при вставке ее в таблицу базы данных. Имеет тип Boolean Определяет, должно ли приложение получать данные по мере необходимости. Имеет тип Boolean Содержит список полей, определяющих набор данных. Имеет тип TfieldDefs Имя файла, в котором хранятся кэшируемые данные. Имеет тип String Задает фильтр, по которому будут выбираться данные из таблицы. Имеет тип String Определяет, включено или выключено свойство Filter. Имеет тип Boolean Параметры фильтрации записей таблицы. Имеет тип TFilterOptions Содержит определения индексов. Имеет тип TlndexDefs Список наименований полей таблицы, по которым будет производиться сортировка набора данных. Имена полей разделяются точкой с запятой. Имеет тип String
Aggregates AggregatesActive AutoCalcFields
CommandText
CommandType
ConnectionName Constraints DBConnection DisableStringTrim FetchOnDemand FieldDers FileName Filter Filtered' FilterOptions IndexDefs IndexFieldNames
Операции с таблицами Свойство IndexName MasterSource MasterRelds ObjectView Options PacketRecord
Params Readonly
UpdateMode
89
Описание Содержит имя индекса, по которому будет произведена сортировка набора данных. Имеет тип String Имя главного источника данных при организации связи таблиц «главнаяподчиненная» («master—detail»). Имеет тип TDataSource Содержит имена полей, по которым осуществляется связь между главной и подчиненной таблицей. Имеет тип String Включает или выключает иерархическое представление для вложенных полей. Имеет тип Boolean Содержит параметры работы с данными. Имеет тип TProviderOptions Определяет количество записей в одном пакете данных. Имеет тип Integer. Возможные значения: -1 — все записи; >0 — конкретное число записей; 0 — в пакет будут включаться только мета-данные Список параметров набора данных. Имеет тип TParams Определяет способ доступа к записям. Имеет тип Boolean. Если значение свойства — true, то данные доступны только для чтения. Если значение — false, то можно изменять существующие данные и записывать новые Указывает способ поиска записи, которую необходимо обновить. Имеет тип TUpdateMode. Может принимать значения: UpWhereAII — искать по всем полям; UpWhereChanged — искать по ключевым и измененным полям; UpWhereKeyOnly — искать только по ключевым полям
Операции с таблицами Рассмотрим основные операции, которые можно выполнять с таблицами базы данных. Изучать эти операции мы будем на примерах работы с компонентами Table и Query. Над таблицами можно производить всего четыре основных действия: • создание таблицы; , • удаление таблицы; • переименование таблицы; • установка режима доступа. Мы уже умеем конструировать таблицы с помощью инструментальных средств, которые рассматривались на занятии 4. Здесь мы будем рассматривать динамический, то есть в ходе выполнения приложения, процесс создания таблиц. Процесс динамического создания таблицы начинается с вызова метода набора данных, который называется CreateTable. Этот метод создает пустую таблицу и помещает ее на диск. Перед вызовом метода нужно позаботиться о подготовке данных, на основе которых будет создаваться таблица. Эти данные нужно присвоить значениям соответствующих свойств набора данных, Естественно, перед вызовом метода CreateTab/e набор данных должен быть закрыт (свойство Active = false). Кроме того, должны быть установл лы значения следующих свойств: DatabaseName, TableName! TatAefype, F\e\dDefs, IndexDefs, то есть должны быть определены путь к базе данных или ее псевдоним, название новой таблицы, тип создаваемой таблицы, описание всех полей таблицы и описание индексных полей таблицы. Большинство из вышеперечисленных свойств мы уже обсуждали на занятии 3, поэтому не будем на них останавливаться. Рассмотрим процесс добавления полей.
90
Занятие 5. Палитра компонентов и работа с базами данных
Итак, в свойстве FieldDefs обязательно должно быть определено хотя бы одно поле. Перед тем как задавать новое значение этого свойства, необходимо очистить предыдущее значение, поскольку в нем может находиться информация о полях другой таблицы. Для этого можно воспользоваться методом Clear: Tablel.FieldDefs.Clear:
Для того чтобы добавить информацию о полях таблицы, можно вызвать метод Add. Метод в документации описан следующим образом: procedure Add (const Name: String: OataType: TFieldType: Size: Word: Required: Boolean): В параметре Name должно быть указано имя поля, а в параметре DataType — его тип. Этот параметр может принимать значения, перечисленные в табл. 3.2. Параметр Size определяет размер поля. Если размер поля не может быть задан (например, в случае поля даты/времени), то значение этого параметра должно быть равным нулю. Последний параметр Required указывает, должно ли поле содержать значение или оно может быть пустым (true или false соответственно). С помощью свойства IndexDefs в создаваемой таблице можно определить индексы. Добавление индекса осуществляется вызовом метода Add. Заметим, что в уже созданной таблице можно удалить или создать индексы посредством методов Addlndex и Deletelndex. ВНИМАНИЕ После определения новых индексов перед открытием набора данных обязательно задайте необходимые значения свойствам IndexName и IndexFieldName, чтобы избежать ситуации, когда в этих свойствах сохранится информация об индексах предыдущей таблицы.
Рассмотрим пример создания таблицы на основе набора данных Table (листинг 5.1). Листинг 5.1. Создание таблицы на основе набора данных Table procedure TForml.ButtonlClick(Sender: TObject):
begin Tablel.Active:=false: // Закрываем набор данных {можно использовать команду Tablel.Close} Tablel.DatabaseName:='С:\MyDatabase': // Путь к базе данных Tablel.TableName:='MyTable': // Имя создаваемой таблицы Tablel.TableType:=ttParadox: // Тип таблицы - Paradox // Теперь переходим к описанию полей таблицы Tablel.FieldDefs.Clear: // Очищаем предыдущую информацию // Создаем три поля: Number. Name. Tel Tab! el.FieldDefs.AddС Number', ftAutoInc. 0. true): Tablel.FieldDefs.AddС Name'. ftString. 35. true): Tablel.FieldDefs.Add('Tel'. ftlnteger. 10. false): II Описываем индексы таблицы Tablel.IndexDefs.Clear: // Очищаем предыдущую информацию // Создаем два индекса Tablel.IndexDefs.AddC'. 'Number'. [ixPrimary. ixUnique]): Tablel.IndexDefs.Add('indName'. 'Name'. [ixCaselnsensitive]): // Теперь создаем таблицу Tablel.CreateTable: // Устанавливаем текущий индекс Tablel.IndexName:-'indName': // Открываем набор данных Tablel.Active:=true: // или Tablel.Openend:
Операции с таблицами
91
После выполнения программы, представленной на листинге 5.1, в каталоге C:\MyDatabase будет создана новая пустая таблица с именем МуТаЫе, имеющая тип Paradox. Таблица состоит из трех полей: порядкового номера записи, имени и телефона. По автоинкрементному полю Number построен главный ключ — для него имя не определено. По полю названия построен вторичный ключ, который становится текущим после создания таблицы. Мы не будем здесь разбирать процесс создания таблицы с помощью набора данных Query, так как это будет рассмотрено достаточно подробно на занятии, посвященном работе с запросами SQL. Удаление таблицы можно осуществить с помощью вызова метода DeleteTable, в результате которого происходит физическое удаление всех файлов таблицы. Перед вызовом данного метода нужно установить необходимые значения свойств DatabaseName и TableName набора данных. Кроме того, необходимо закрыть набор данных. Пример удаления таблицы приведен в листинге 5.2. Листинг 5.2. Удаление таблицы procedure TForml.ButtonlClicktSender: TObject): begin Tablel.Active:=false: // Закрываем набор данных Tablel.DatabaseName: = 'C:\MyDatabase': // Путь к базе данных Tablel.Tab!eName:='MyTable': // Имя удаляемой таблицы // Теперь удаляем таблицу Tab! el.DeleteTable: end:
-
Процесс переименования таблицы (Paradox или dBase) можно осуществить с помощью метода RenameTable, который имеет один параметр NewTableName типа String. Этот параметр должен содержать новое имя таблицы. При вызове метода будут переименованы все файлы, относящиеся к таблице. Рассмотрим теперь процесс установки уровня доступа. Уровень доступа к базе данных задается в случае, когда к ней могут обращаться несколько приложений одновременно. Уровень доступа определяет возможность записи и чтения данных в таблицу. С помощью метода LockTable можно заблокировать таблицу от вмешательства других приложений. Этот метод имеет один параметр LockType типа TLockType, задающий тип блокировки: • ItReadLock — запрещает другим приложениям записывать или считывать данные из таблицы; то есть переводит таблицу в режим монопольного доступа; • ItWriteLock — другим приложениям запрещено записывать данные в таблицу, но они могут считывать имеющиеся данные. Для снятия блокировки таблицы предназначен метод UnLockTable. Этот метод имеет такой же параметр LockType типа TLockType. Итак, методы LockTable и UnLockTable применяются для блокирования и разблокирования таблицы и чаще всего требуются для внесения каких-либо глобальных изменений в данные таблицы.
92
Занятие 5. Палитра компонентов и работа с базами данных
Сортировка набора данных Одной из наиболее часто выполняемых задач является задача сортировки данных таблицы по одному из полей (или по нескольким полям). Дело в том, что обычно записи в таблицу заносятся в порядке их добавления (таблицы Paradox сортируются по ключевым полям). Давайте рассмотрим приемы сортировки таблицы на примере набора данных Table. На срртировке данных для компонента Query мы задержим внимание, когда будем изучать язык SQL. Сразу отметим, что сортировка наборов данных Table выполняется автоматически по текущему индексному полю. Если вы переопределите индекс, произойдет автоматическая сортировка данных по новому индексу. Если нужно, чтобы сортировка шла по нескольким полям сразу, создайте индекс, включающий эти поля. Таким образом, сортировка набора данных Table возможна только по полям, для которых задан индекс. Из рассмотренных на этом занятии свойств компонента Table вы уже знаете, что для задания текущего индекса, по которому будет выполняться сортировка данных, можно использовать свойства IndexName и IndexFieldNames. При этом следует помнить, что установка значения одного из упомянутых свойств автоматически удаляет значение в другом свойстве. Если вы хотите осуществить сортировку по одному полю, используйте свойство IndexName. Если же сортировка должна производиться по нескольким полям, перечислите их в свойстве IndexFieldNames. Иногда необходимо изменить направление сортировки данных. По умолчанию всегда выполняется сортировка по возрастанию значений. Для задания направления сортировки служит параметр ixDescending, который определяется для текущего индекса. По умолчанию он выключен. Если параметр включить, то сортировка будет осуществлена в порядке убывания. Приведем простой пример сортировки значений таблицы по полю Name (листинг 5.3). Листинг 5.3. Сортировка по имени procedure TForml.ButtonlClick(Sender: TObject): begin
Tablel.IndexName:='Name'; end:
На рисунке 5.5 показаны данные таблицы до сортировки, а на рис. 5.6 — данные после сортировки.
Красноярская 12,34 Ленина 30,59 МираТЗ
• • . . - • •
Рис. 5.5. Данные таблицы до сортировки
Перемещение по набору данных
93
Рис. 5.6. Данные таблицы после сортировки
Перемещение по набору данных Процесс перемещения по набору данных осуществляется передвижением указателя текущей записи (курсора). Курсор определяет текущую запись, с которой можно выполнять различные действия. Рассмотрим два способа перемещения по набору данных: • перемещение по записям; • перемещение по закладкам. Для перемещения по записям используются следующие методы: • First — устанавливает курсор на первую запись набора данных; • Last — устанавливает курсор на последнюю запись набора данных; • Next — перемещает курсор на следующую запись набора данных; • Prior — перемещает курсор на предыдущую запись набора данных; • MoveBy — перемещает курсор на число записей, задаваемое параметром Distance. ПРИМЕЧАНИЕ В случае вызова метода Next, когда курсор находится на последней записи, перемещения курсора не происходит. Для метода Prior, если курсор находится на первой записи, также перемещение курсора не происходит. Если значение параметра Distance метода MoveBy больше нуля, то перемещение будет производиться к концу таблицы, при отрицательном значении — назад. Функция MoveBy возвращает число записей, на которое фактически переместился курсор.
Перемещение осуществляется только по тем записям, которые содержатся в текущее время в наборе данных. В случае применения фильтра (о нем мы расскажем далее) количество записей в наборе данных может значительно уменьшиться. Для определения текущего числа записей в наборе данных можно использовать свойство RecordCount. Рассмотрим пример перемещения по записям набора данных (листинг 5.4). Листинг 5.4. Перемещение по записям набора данных procedure TForml.ButtonlClick(Sender: TObject); var i:integer: // Переменная для цикла
94
Занятие 5. Палитра компонентов и работа с базами данных
beginTab!el.First:
// Перемещаем курсор на первую запись
for i:=l to Tablel.RecordCount do begin
// Здесь можно вставить какие-либо действия // Например, суммирование какого-либо поля таблицы
Tablel.Next; // Перемещаемся на следующую запись
end: end:
В рассматриваемом примере производится перебор всех записей набора данных Tablel, и после выполнения программы курсор будет указывать на последнюю запись набора данных. Для того чтобы выяснить, какая запись является в настоящий момент времени текущей, можно использовать свойство RecNo набора данных. Это свойство содержит номер текущей записи. Запись в это свойство значений не допускается. ПРИМЕЧАНИЕ Таблицы типа Paradox поддерживают переход к нужной записи с помощью установки необходимого значения свойства RecNo.
Определение, находится ли курсор на первой или последней записи набора данных, производится считыванием значений свойств ВОР и EOF. Эти свойства имеют тип Boolean. Свойство ВОР показывает, находится ли курсор на первой записи набора данных. Если данное свойство имеет значение true, то указатель находится на первой записи. Свойство EOF показывает, находится ли курсор на последней записи набора данных. Если свойство имеет значение true, то указатель находится на последней записи. * . ПРИМЕЧАНИЕ Свойства ВОР и EOF одновременно имеют значение true, когда набор данных пуст.
Рассмотрим простой пример использования вышеприведенных методов и свойств. Для начала создадим таблицу типа dBase IV с помощью программы Database Desktop. Определим четыре поля Name, Adres, Tel и Oklad, как показано на рис. 5.7. Кроме того, добавим два индексных поля Adres и Name с помощью кнопки Define... (Определить). Создадим новую папку C:\MyDatabase и сохраним в ней таблицу под именем MyTable.dbf с помощью кнопки Save As... (Сохранить как) (рис. 5.8). Теперь разместим в форме Forml в среде Delphi следующие компоненты (рис. 5.9): • DataSourcel с закладки Data Access; • Tablel с закладки BDE; • DBGridl с закладки Data Controls.
Перемещение по набору данных
95
ICieatedBASE IV Table: { Unfilled 1
Рис. 5.7. Задание структуры новой таблицы
Рис. 5.8. Сохранение таблицы в файле *
Установим следующие свойства для компонентов в окне инспектора объектов: • для компонента Tablel: свойству DatabaseName присвоим значение «C:\MyDatabase», свойству TableName присвоим значение «MyTable.dbf», свойство Active установим в true; • для компонента DataSourcel: свойству DataSet присвоим значение Tablel; • для компонента DBGridl: свойству DataSource присвоим значение DataSourcel.
96
Занятие 5. Палитра компонентов и работа с базами данных
Рис. 5.9. Заготовка формы приложения
Таким образом, мы связали все три компонента между собой. Теперь можно запускать приложение с помощью клавиши F9 и заполнять наш пустой набор данных примерно так, как показано на рис. 5.10. Для заполнения пустых полей достаточно просто щелкнуть на нужном поле кнопкой мыши и набрать значение.
Сидоров К.М.
I Металлургов 12,29
25465!
! Зеленая 23.1
2415б[
Петров П.И._^ Константинов Е.П.
|Береговая 22
ЗИИ1 282l]:
"Нвгр ' "1352!:
Рис. 5.10. Заполнение таблицы
Теперь добавим кнопки Buttonl и Button2 с закладки Standard (Стандартные), которые позволят переходить по записям вперед и назад на одну запись. Свойству Caption первой кнопки присвоим значение «Вперед», а этому же свойству второй кнопки — значение «Назад». Теперь осталось включить в обработчики событий нажатия кнопок код, производящий переход на следующую или предыдущую запись набора данных. При этом будем учитывать достижение курсором начальной или конечной записи набора данных и отключать соответствующую кнопку. В листинге 5.5 приведен код обработки нажатия кнопок Buttonl и ButtonZ с комментариями.
Перемещение по набору данных
97
Листинг 5.5. Обработчики нажатия кнопок Buttonl и Button2 procedure TForml.ButtonlClicHSender: TObject): begin
// Если кнопка «Назад» отключена, то ее нужно включить If Button2.Enabled=False then Button2.Enabled:=True; // Если не достигнута последняя запись, перейти к следующей If not Tab!el.EOF then Tablel.Next: // Если достигнута последняя запись. // отключить кнопку «Вперед» If Tablel.EOF then Buttonl.Enabled:=False: end;
procedure TForml.Button2Click(Sender: TObject); begin // Если кнопка «Вперед» отключена, то ее нужно включить If Buttonl.Enabled-False then Buttonl.Enabled—True; // Если не достигнута первая запись, перейти к предыдущей If not Tablel.BOF then Tablel.Prior; // Если достигнута первая запись. // отключить кнопку «Назад» If Tablel.BOF then Button2.Enabled:=False: end; Таким образом, при выполнении кода листинга 5.5 при попытке перехода к записи, которая «находится» после последней или перед первой, будут отключаться соответствующие кнопки. На рис. 5.11 представлен вид формы с отключенной кнопкой «Вперед» после попытки перейти на запись, следующую после последней.
Металлургов 12,23 Зеленея23,. i Красноярская 91,1Э Береговая 22
Рис. 5.11. Окно приложения после попытки перехода к несуществующей записи ПРИМЕЧАНИЕ Того же самого эффекта можно достичь, поместив в форму вместо кнопок «Вперед» и «Назад» компонент DBNavigator.
Добавим теперь в форму еще одну кнопку Buttons и текстовое поле Editl. Присвоим свойству Caption кнопки Buttons значение «Сумма». Очистим значение свойства Text поля Editl. Теперь напишем код обработчика нажатия кнопки Buttons, при выполнении которого будут суммироваться значения всех записей поля OKLAD и итоговая сумма будет выведена в компоненте Editl (листинг 5.6). 4 Зак. 95
98
Занятие 5. Палитра компонентов и работа с базами данных
Листинг 5.6. Обработчик нажатия кнопки Buttons procedure TForml.Button3C1ick(Sender: TObject): var i:integer: // Переменная для цикла sum:real: // В этой переменной будет подсчитываться сумма begin sum:=0: // Обнуляем значение суммы Tablel.First: // Перемещаем курсор на первую запись // Цикл от первой записи до последней for i:-l to Tablel.RecordCount do begin // Складываем значение поля OKLAD текущей записи / / с переменной sum sum:=suimTablel.FieldByName( "OKLAD" ).AsFloat: Tablel.Next: // Переходим на следующую запись end: // Выводим значение суммы в поле Editl Editl.Text:=FloatToStr(sum): Tablel.First: // Перемещаем курсор на первую запись end:
Результат нажатия кнопки «Сумма» представлен на рис. 5.12.
; Металлургов 12,29 Зеленая 23,1 ! Красноярская 9119 ;
Береговая 22
Рис. 5.12. Результат суммирования значений поля OKLAD
Перемещение по закладкам используется для перехода на определенную запись набора данных. Закладки представляют собой маркеры записей. Они похожи на закладки, которыми вы закладываете книгу, чтобы продолжить чтение с нужной страницы. Закладки имеют тип TBookmark. который является не чем иным, как указателем (Pointer), с помощью которого можно ссылаться на определенные объекты. В нашем случае в качестве этих объектов выступают записи набора данных. ПРИМЕЧАНИЕ Указателем в общем ov-ae -взывается переменная, в которой хранится адрес другой переменной в оператишо» -»пг-* компьютера.
Естественно, перед создания закладки .
: пользовать закладку, ее нужно создать. Процесс прост. Для этого в Delphi имеется специальный
Фильтры
99
метод — GetBookmark, типа TBookmark. Вызов данного метода приводит к созданию закладки на текущей записи набора данных. ВНИМАНИЕ Закладка не всегда точно идентифицирует запись — иногда она может неправильно позиционировать курсор. В таком случае говорят о нестабильности закладки. Закладка может быть нестабильной в случае, когда в наборе данных нет признака, позволяющего однозначно определять записи. Такое возможно при отсутствии ключевых полей. Заметим, что для таблиц типа dBase закладка всегда является стабильной.
Так как метод GetBookmark представляет собой функцию, возвращающую значение типа TBookmark, перед его вызовом нужно определить переменную типа TBookmark и установить закладку в этой переменной (листинг 5.7). Листинг 5.7. Пример создания закладки procedure TForml.ButtonlCli ck(Sender: TObject): var z:TBookmark: // Переменная для закладки begin
Tab!el.First: // Переходим на первую запись набора данных Tablel.Next: // Переходим на вторую запись набора данных z:=Tablel.GetBookmark: // Устанавливаем закладку
end:
Для перехода на существующую закладку применяется метод GotoBookmark. В качестве параметра данного метода используется переменная типа TBookmark. Если закладка не была ранее создана и значение параметра равно nil, то курсор не будет перемещаться. Удаление закладки осуществляется с помощью вызова метода FreeBookmark. Параметром метода является переменная типа TBookmark, содержащая указатель на закладку. Вызов сбрасывает значение переменной в nil и освобождает занимаемые ею ресурсы. Если после удаления закладки вы попробуете перейти на нее или повторно ее удалить, сгенерируется исключительная ситуация. Для того чтобы узнать, существует закладка или нет, можно вызвать метод BookmarkValid. Этот метод представляет собой функцию, в качестве параметра которой выступает переменная типа TBookmark. Функция возвращает значение true, если закладка найдена, и false — в противном случае.
Фильтры В процессе работы с данными часто возникает необходимость отбора записей, удовлетворяющих каким-либо критериям. Для этого к наборам данных применяют фильтры. Фильтр — это набор ограничений для записей, которые будут выделены в наборе данных. Процесс задания фильтра называется фильтрацией записей. Среда Delphi позволяет фильтровать записи либо по выражению, либо по диапазону. По умолчанию отображаются все записи набора данных, то есть фильтр не используется.
100
Занятие 5. Палитра компонентов и работа с базами данных
Фильтрация по выражению ограничивает набор данных записями, которые удовлетворяют выражениям, записанным в фильтре. Этот вид фильтрации применим к любым полям, в том числе и неиндексированным. ПРИМЕЧАНИЕ Фильтрация по выражению эффективна в случае, когда набор данных содержит небольшое число записей, так как при фильтрации последовательно просматриваются все записи набора данных.
Для задания выражения фильтра используется свойство Filter набора данных. В состав этого выражения могут входить: • арифметические операции, такие как сложение, вычитание, умножение и деление, обозначаемые символами +, -, * и /; • знаки логических операций: AND, OR, NOT и т. д.;
• имена полей таблиц. Если внутри имени поля содержатся пробелы, его заключают в квадратные скобки, например [Tel Number]; • круглые скобки для определения порядка выполнения арифметических и логических операций; • литералы, то есть явно заданные значения, например строка, символ или число; • операции сравнения, то есть обычные операции >,<,=>,<=и<>. Приведем примеры задания фильтра: Number > 100 AND Number < 1000 Name = 'Иван' Oklad * 0.87 < 1000 Первый фильтр отбирает записи, находящиеся между сотой и тысячной записями (Number) набора данных. Второй оставляет в наборе данных записи для людей, носящих имя (Name) Иван. В третьем случае мы увидим записи только для тех сотрудников, у которых заработная плата (Oklad) при вычитании 13 % составляет сумму меньше 1000 рублей. После установки фильтра в свойстве Filter он не будет активным до тех пор, пока свойству Filtered не будет присвоено значение true. Для отключения фильтрации достаточно сбросить значение свойства Filtered в false. СОВЕТ Во время разработки приложения по возможности проверяйте выражения, записываемые в свойство Filter, с помощью установки свойства Filtered в окне инспектора объектов, так как пока фильтр не станет активным, он не проверяется на корректность, что может привести к исключительной ситуации.
Свойство Filter-Options набора данных позволяет задавать параметры фильтрации. Значение комбинируется из двух параметров: • foCaselnsensitive — при задании фильтра не учитывать регистр букв. То есть, например, для фильтра Name = 'Иван' будут выбраны записи «Иван», «ИВАН», «иван» и другие; • foNoPartialCompare — проверять на полное соответствие значения поля фильтру. Применяется для строгого поиска. Если вы хотите осуществлять фильтрацию
Фильтры
101
записей по частичному совпадению фильтра, отключите этот параметр. В таком случае можно заменить незначащие символы символом звездочки *. В результате при заданном фильтре Name = %И*' будут выбраны все записи, имена людей в которых начинаются с буквы И. По умолчанию оба параметра отключены. Фильтрация по диапазону отбирает записи, значение полей которых попадают в заданный диапазон. Такой вид фильтрации проходит только по индексированным полям, что значительно ускоряет процесс. Индекс поля, по которому будет производиться фильтрация, должен быть установлен как текущий в свойстве IndexName или IndexFieldNames. В случае, если текущий индекс не установлен, по умолчанию будет использоваться главный индекс. Для указания верхней и нижней границ диапазона применяются методы SetRangeStart и SetRangeEnd. Эти методы не имеют параметров. ПРИМЕЧАНИЕ Вызов методов SetRangeStart и SetRangeEnd переводит набор данных в режим dsSetKey.
Для изменения ранее установленных границ диапазона можно воспользоваться методами EditRangeStart и EditRangeEnd. Чтобы включить фильтрацию по диапазону, необходимо вызвать метод ApplyRange. Для отключения фильтрации применяется метод CancelRange. Граничные значения диапазона могут быть как включенными в диапазон, так и исключенными из него. Для определения этого используется свойство KeyExclusive. Если свойство установлено в true, то граничные записи в набор данных не попадают, иначе — включаются. Свойство должно устанавливаться отдельно для верхней и нижней границ диапазона сразу после вызова метода установки или редактирования границы. Приведем пример задания диапазона (листинг 5.8). Листинг 5.8. Задание диапазона фильтрации Tab!el.SetRangeStart: Tab!el.KeyExclusi ve:=true: Tablel.FieldByName("Name").AsString:-TT: Tablel.SetRangeEnd; Tablel.FieldByName("Name").AsString:-'fl': Tablel.ApplyRange:
После выполнения программы из листинга 5.8 набор данных будет содержать записи с фамилиями, начинающимися с букв от П до Я. Индекс по полю Name должен быть текущим. В этом примере заданы обе границы диапазона. Если одна из границ не будет учтена, то диапазон будет открытым. Например, если задана нижняя граница (SetRangeStart), а верхняя — нет, то будут выделены записи от нижней границы до максимально возможного значения. Таким образом, из листинга 5.8 можно убрать две «лишние» строки, устанавливающие верхнюю границу. Тогда получится такой код: Tablel.SetRangeStart: Tablel.KeyExclusive:=true: Tablel.FieldByName("Name").AsString:-'rr: Tablel.ApplyRange:
102
Занятие 5. Палитра компонентов и работа с базами данных
Допустимо фильтровать записи сразу по нескольким полям. Для этого после вызова метода, устанавливающего границу диапазона, указываются значения нужных полей, как, например, в листинге 5.9. Листинг 5.9. Фильтрация записей по двум полям Tab!el.SetRangeStart: Tablel.KeyExclusive:-true: Tablel.FieldByName("Name").AsString:='n-: Tablel.FieldByNameCOklad').AsFloat:-1000: Tablel.ApplyRange:
В этом случае будут отфильтрованы записи, в которых фамилии сотрудников, чей оклад более 1000 рублей, начинаются с букв от П до Я. Естественно, в качестве текущего индекса должен быть указан индекс, построенный по двум полям: Name и Oklad. Если текущий индекс, по которому осуществлялась фильтрация набора данных, был изменен, то фильтрация перестает действовать.
Поиск Кроме отбора записей, соответствующих некоторому критерию, иногда нужно найти какую-либо конкретную запись. Поиск записи очень похож на фильтрацию, но отличается тем, что состав набора данных при поиске остается неизменным, просто осуществляется переход на запись, удовлетворяющую критериям поиска. При поиске записей (особенно в больших таблицах) очень важно наличие индекса у полей, по которым будет производиться поиск. Во-первых, это ускоряет обработку данных. Во-вторых, некоторые методы поиска работают только с индексированными полями. При поиске записей по значению полей используются методы Locate и Lookup. Для данных методов можно задействовать неиндексированные поля. Метод Locate описывается следующим образом: function Locate (const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean: Метод ищет запись, которая соответствует заданным значениям полей. Параметр KeyFields определяет названия полей, по которым будет производиться поиск. Поля разделяются точкой с запятой. В параметре KeyValues указываются значения этих полей. Параметр Options позволяет устанавливать дополнительные критерии поиска: • loCaselnsensitive — не учитывать регистр букв; • loPartialKey — учитывать частичное совпадение значений. ВНИМАНИЕ Если вы установили значение loPartialKey в параметре Options, то Delphi автоматически прибавит к нему значение loCaselnsensitive.
Приведем пример поиска по значению поля: Tab!el.LocateC"Oklad". 3512.
[]):
В этом примере будет производиться поиск записи, значение поля Oklad у которой равно 3512.
Поиск
103
Следует заметить, что в рассмотренном примере мы никак не анализируем результат поиска. Следовательно, если удовлетворяющая нас запись была найдена, будет произведен переход на нее. В ином случае никаких действий производиться не будет. Функция Locate возвращает значение true, если запись найдена, и false — в противном случае. Приведем пример, показывающий использование возвращаемого функцией Locate значения: if Tablel.Locate("Oklad", 351. []) = false then MessageDlg("Запись не найдена", mtlnformation. [mbOk]. 0):
Если запись не будет найдена, появится окно с информацией о том, что запись не найдена. При успехе поиска курсор переместится на найденную запись. Пример поиска записей по нескольким полям: Tablel.LocateCName: Adres'. УагАггауОЩ'И'. 'M']). [loCaselnsensitive. loPartialtey];
В этом случае поиск ведется по полям, содержащим имя и адрес. Будет найдена первая запись, значение поля Name в которой начинается с букв И или и, а значение поля Adres — с букв М или м. Обратите внимание на тот факт, что здесь параметр KeyValues является массивом, в котором содержатся оба значения. Значения должны быть разделены запятыми и заключены в квадратные скобки. Для приведения к типу массива используйте функцию VarArrayOf. Кроме метода Locate, для поиска записей применим также метод Lookup. Описание метода Lookup выглядит так: function Lookup(const KeyFields: String: const KeyValues: Variant: const ResultFields: String): Variant: -
Параметры KeyFields и KeyValues инициируются так же, как и в методе Locate. Метод Lookup в целом похож на метод Locate, но есть два основных отличия: • метод Lookup осуществляет поиск на точное соответствие значений, указанных в параметрах; • метод Lookup не переводит курсор на найденную запись, а считывает значения полей найденной записи. Для получения значений полей найденной записи нужно указать требуемые названия полей в параметре ResultFields. Значения только этих полей и будут считаны из найденной записи. Порядок следования полей в параметре не имеет значения. В случае успешного поиска метод Lookup возвращает в качестве результата значение типа Variant. Если в списке ResultFields всего один элемент, то будет возвращено значение типа Variant. Если же список содержит несколько полей, на выходе получим массив типа Variant, содержащий столько элементов, сколько перечислено в параметре ResultFields. Метод Lookup возвращает значение Null при неудачном поиске. Кроме двух представленных выше методов для поиска записей, в Delphi имеется еще несколько средств, позволяющих осуществлять поиск по индексным полям. Все эти методы можно условно разделить на две группы: • методы поиска записи на точное соответствие значений (FindKey, SetKey, EditKey и GotoKey);
104
Занятие 5. Палитра компонентов и работа с базами данных
• методы поиска, допускающие частичное соответствие значений (FindNearest, setNearest, EditNearest и GotoNearest). Метод FindKey описан следующим образом: function FindKeytconst KeyValues: array of const): Boolean:
Этот метод осуществляет поиск записи в наборе данных, у которой значения полей полностью совпадают со значениями, указанными в параметре KeyValues. Список полей не задается, так как берутся поля, заданные текущим индексом. В случае удачного поиска метод возвращает значение true и перемещает курсор на найденную запись. Иначе возвращается значение false. Вместо метода FindKey можно вызывать одновременно три метода: SetKey, EditKey и GotoКеу. Этот способ похож на ранее рассмотренные методы SetRangeStart, EditRangeStart и ApplyRange для фильтрации набора данных. Приведем пример использования данных методов: Tablel.IndexFieldNames:='Name':
// Устанавливаем текущий // индекс
Tab!el.SetKey: Tablet.FieldByNameCName').AsString:='Петр': Tablel.GotoKey:
Здесь осуществляется поиск записи по полю Name, значение которого равно Петр. Метод FindNearest напоминает метод FindKey, с тем отличием, что поиск производится по частичному совпадению значений индексных полей. Поиск с привлечением метода FindNearest всегда является успешным и перемещает курсор на запись, которая в большей степени отвечает критериям поиска. Вместо метода FindNearest можно воспользоваться комбинацией методов SetNearest, EditNearest и GotoNearest. Работа с этими методами ничем не отличается от уже рассмотренного сочетания SetKey, EditKey и GotoKey. Вот простой пример поиска записи с помощью метода FindNearest: Tablel.IndexFieldNames:='Name': Tablel.FindNearest:=(['В']):
В этом случае курсор будет перемещен на запись, поле Name которой содержит значение, начинающееся с буквы В. Если такой записи нет, будет найдена запись, значение поля Name которой начинается с ближайшей к В буквы.
Что нового мы узнали? На этом занятии мы рассмотрели: • основные компоненты для работы с наборами данных и для визуального отображения и редактирования данных; , • основные операции с таблицами; • способы сортировки наборов данных; • способы перемещения по записям и использования закладок; • фильтры и как с ними работать; • поиск записей, удовлетворяющих определенным критериям.
•
Занятие 6 Модификация данных и связанные таблицы Редактирование, добавление и удаление данных Работа со связанными таблицами
На этом занятии мы отдельно рассмотрим способы редактирования, добавления и удаления записей наборов данных. Кроме того, дадим краткую методику работы со связанными таблицами. Первая и вторая части занятия для пояснения материала будут сопровождаться примерами в виде небольших программ.
Редактирование, добавление и удаление данных Понятия редактирования, добавления и удаления данных можно объединить в едином понятии модификации набора данных. Модифицируемость, то есть возможность изменения набора данных, зависит от различных условий. Delphi предоставляет программисту широкие возможности ограничения модифицируемости набора данных с помощью соответствующих свойств. Ярким примером наложения ограничений на модифицируемость набора данных является переключение его в режим «только для чтения». Например, если мы хотим, чтобы возможности пользователя ограничивались исключительно просмотром записей из набора данных без возможности их редактирования или занесения в них новых записей, можно использовать свойство Readonly. Данное свойство имеет по умолчанию значение false, то есть набор данных можно модифицировать. Приведенная ниже строка кода позволяет перевести набор данных Tablel в режим «только для чтения»: Tab!el.Readonly := true; ВНИМАНИЕ Значение свойства Readonly можно изменять только в том случае, когда набор данных закрыт, то есть свойство Active набора данных установлено в false.
106
Занятие 6. Модификация данных и связанные таблицы
Заметим, что установка свойства Readonly в true ограничивает как полномочия пользователя по изменению данных, так и программные возможности, то есть в данном случае программа тоже не сможет сделать никакие изменения в наборе данных. Практически аналогичное средство для ограничения модифицируемости набора данных имеет и набор данных Query. Для этого применяется свойство RequestLive. По умолчанию свойство Query имеет значение false, что означает доступ к набору данных в режиме «только для чтения». Для обеспечения модифицируемости набора данных нужно установить значение свойства в true. Чтобы проверить, можно ли модифицировать набор данных, предусмотрено свойство CanModify. Это свойство имеет значение true, если набор данных можно модифицировать, и false, если нельзя.
Редактирование набора данных Для редактирования текущей записи набора данных необходимо сначала перевести его в режим редактирования. Перевод набора данных в состояние редактирования можно осуществлять двумя методами: • программно, с помощью метода Edit; • визуально, посредством компонентов, отображающих данные, например DBGrid. ПРИМЕЧАНИЕ Набор данных может автоматически переключаться в режим редактирования. Для этого нужно, чтобы значение свойства DataEdit компонента DataSource было установлено в true. Иначе с помощью визуальных компонентов изменить данные будет нельзя.
Если набор данных является немодифицируемым (CanModify равно false), при попытке редактирования сгенерируется исключительная ситуация. Если набор данных не содержит ни одной записи, то он будет переведен в режим вставки записи. Если набор данных является модифицируемым, то будут произведены следующие действия: • сгенерируется событие BeforeEdit, которое можно обработать; • из набора данных повторно считывается текущая запись и блокируется доступ к ней других пользователей (временно устанавливается доступ только для чтения); ПРИМЕЧАНИЕ Если блокирование записи невозможно (запись уже редактируется другим пользователем), генерируется исключительная ситуация. Выполнение метода Edit в данном случае прекращается.
если запись содержит вычисляемые поля, они пересчитываются; набор данных переводится в режим редактирования; генерируется событие OnDataChange для связанного с набором данных источника данных; последним генерируется событие AfterEdit.
Редактирование, добавление и удаление данных
107
Для того чтобы сделанные изменения были сохранены в наборе данных, нужно вызвать метод Post, который выполняет следующие действия: • записывает новые данные в физическую таблицу, • снимает блокировку записи; • переводит набор данных в режим просмотра. ВНИМАНИЕ Если при вызове метода Post набор данных не находился в режиме редактирования, то будет сгенерирована исключительная ситуация.
После модификации набора данных может возникнуть ситуация, когда изменения не отображаются в визуальных компонентах, связанных с ним. В таких случаях нужно вызывать метод Refresh. Этот метод заново считывает информацию из набора данных и обновляет содержимое компонентов. Приведем простой пример изменения данных в одном из полей набора данных (листинг 6.1). Листинг 6.1. Изменение данных в поле Name if Tablel.CanModify=true then begin // Если модификация данных возможна, выполняем эти действия Tablel.Edit; // Переводим таблицу в режим редактирования // Присваиваем значению поля Name текст из поля Editl Tablel.FieldByName('Name').AsString:=Editl.Text: Tablel.Post: // Записываем данные в физическую таблицу Tab!el.Refresh: // Обновляем содержимое визуальных // компонентов end else MessageDlgCРедактирование невозможно', mtlnformation. [mbOK]. 0): // Если редактирование невозможно, выводим сообщение end:
Если вы решили отказаться от изменений, сделанных в текущей записи, и возвратить набор данных в режим просмотра, можно воспользоваться методом Cancel. При вызове данного метода будут сгенерированы события BeforeCancel и AfterCancel. Рассмотрим простой пример отмены сделанных изменений в текущей записи. Предположим, что для записи изменений на форме присутствует кнопка Post. Тогда обработчик нажатия этой кнопки может выглядеть так, как показано в листинге 6.2. Листинг 6.2. Запись или отмена сделанных изменений в наборе данных procedure TForml.PostClicktSender: TObject): begin // Выводим диалог «Записать изменения?» if MessageDlgC"Записать изменения?". mtConfirmation. [mbOK. mbCancel]. 0)=mrOK then begin // Если нажата кнопка OK Tablel.Post: // Записываем данные Tab!el.Refresh: // Обновляем визуальные компоненты pnd
:
продолжение &
108
Занятие 6. Модификация данных и связанные таблицы
Листинг 6.2 (продолжение) else begin
// Если нажата кнопка Cancel Tablel.Cancel: // Отмена сделанных изменений end: end:
Для редактирования текущей записи можно заменить последовательность присваивания значений полей и вызовов метода Post методом SetFields. Метод SetFields имеет один параметр Values, содержащий массив значений, которые присваиваются полям набора данных. При этом порядок перечисления значений должен соответствовать порядку следования полей в наборе данных. Если параметр Values содержит количество значений меньшее, чем число полей набора данных, то эти значения присваиваются первым полям, а остальные не будут изменены. Если вы хотите оставить значение какого-либо поля без изменений, в качестве соответствующего значения Values следует задать nil. ВНИМАНИЕ Ключевые слова nil и null имеют разный смысл: nil означает отсутствие значения, null подразумевает нулевое значение.
После выполнения метода SetFields метод Post выполнять не нужно. Набор данных будет автоматически обновлен и переведен в режим просмотра. В следующем примере изменяются значения сразу нескольких полей набора данных: Tablel.Edit: // Переводим таблицу в режим редактирования Tablel.SetFields ([nil. 'Сидоров А.Е.'. nil. 3400]): Первое и третье поля текущей записи набора данных Tablel остаются без изменений, а второе и четвертое поля изменяются на значения «Сидоров А.Е.» и 3400.
Добавление записей Сразу следует заметить, что добавлять новые записи можно только к модифицируемому набору данных. Для добавления записи следует: • перевести набор данных в режим вставки; • задать значения для полей новой записи; • подтвердить добавление новой записи или отказаться от нее. Добавление новых записей возможно с помощью одного из четырех методов: • Insert; • InsertRecord; • Append; • AppendRecord.
Рассмотрим эти методы более подробно. Метод Insert выполняет следующие действия: • переводит набор данных в режим вставки записи;
Редактирование, добавление и удаление данных
109
• сдвигает записи на одну вперед, начиная от текущей; • вставляет на место текущей записи новую пустую запись. После перевода данных в режим вставки для задания значений полей можно использовать такие же методы, которые мы применяли при редактировании записи. Можно присваивать новые значения отдельным полям и вызывать метод Post либо использовать метод SetFields. ПРИМЕЧАНИЕ Если при переходе в режим вставки запись добавляется к подчиненному набору данных, связанному с главным набором данных связью master—detail, то индексные поля автоматически получат нужные корректные значения. Программист может не заботиться об их заполнении.
Рассмотрим простой пример вставки новой записи: Tab!el.Insert; // Перевод набора данных в режим вставки Tablel.Fie1dByName('Name').AsString:=Editl.Text: Tablel.FieldByNameCOklad').AsF1oat:=StrToInt(Edit2.Text): Tab!el.Post; // Записываем сделанные изменения
Здесь мы заполняем два поля Name и Oklad значениями из полей редактирования Editl и Edit2. Метод InsertRecord позволяет объединить возможности методов Insert и SetFields. Данный метод имеет параметр Values, аналогичный такому же параметру метода SetFields. Таким образом, метод InsertRecord вставляет в текущую позицию курсора новую запись, задавая значения ее полей. Например: Tab!el.InsertRecord ([nil. 'Сидоров А . Е . ' . nil.
3400]);
Метод Append аналогичен методу Insert за тем исключением, что вставляет новую запись в конец набора данных, то есть новая запись будет последней записью. Метод AppendRecord аналогичен методу InsertRecord, но добавляет новую запись в конец набора данных, так же, как и метод Append. -
-.
Удаление записей
Удалять записи можно только из модифицируемого набора данных. Текущая запись, то есть та, на которую указывает курсор, удаляется с помощью метода Delete. Если удаление произведено успешно, то текущей становится следующая запись. Если была удалена последняя запись, курсор переместится на предыдущую запись. ВНИМАНИЕ При попытке удаления записи из пустого набора данных будет сгенерирована исключительная ситуация.
При удалении записи последовательно генерируются события BeforeDelete и AfterDelete. Для удаления всех данных из таблицы можно применять метод EmptyTable. ВНИМАНИЕ Метод EmptyTable разрешен только в режиме исключительного доступа к таблице.
110
Занятие 6. Модификация данных и связанные таблицы
Работа со связанными таблицами Различные таблицы базы данных могут быть связаны между собой с помощью полей связи. Поля связи обязательно должны быть индексированными. Таблицы связываются по принципу «главный—подчиненный». При перемещении по записям главной таблицы будут автоматически становиться доступными те записи подчиненных таблиц, у которых значения поля связи равно значению поля связи текущей записи главной таблицы. Таким образом, это очень похоже на фильтрацию записей в подчиненных таблицах. Для установления связи между главной и подчиненной таблицами используются следующие свойства подчиненной таблицы: • MasterSource — источник данных главной таблицы; • IndexNames — текущее индексное поле подчиненной таблицы; • IndexFieldNames — поле или поля связи текущего индекса подчиненной таблицы; • MasterFields — поле или поля связи индекса главной таблицы. Перечислим основные особенности при работе со связанными таблицами: • если вы редактируете значение поля связи, нужно изменять и соответствующие значения поля связи у всех подчиненных таблиц во избежание нарушения связи между таблицами; • при удалении записи в главной таблице необходимо удалять соответствующие ей записи во всех подчиненных таблицах. Такое удаление называется каскадным. Мы не будем на этом занятии рассматривать пример работы со связанными таблицами. Отложим его до занятия, посвященного созданию вашей первой локальной базы данных.
Что нового мы узнали? На этом занятии мы выяснили: ; • что такое модифицируемость набора данных; • как редактировать записи набора данных; • как добавлять записи в набор данных; • как удалять отдельные записи из набора данных, а также очистить всю таблицу; • каковы особенности работы со связанными таблицами. •
. :
Занятие 7
•
.
Отчеты в Delphi 7 т Конструктор отчетов Rave Reports •
•, • . На этом занятии мы рассмотрим возможности, которые предоставляет Delphi для вывода текстовой и графической информации, содержащейся в таблицах базы данных, на печать. Мы изучим основные компоненты для создания отчетов и попробуем сами создать отчеты на их основе. Мы рассмотрим механизм и средства создания отчетов, появившиеся в последней версии среды разработки и доставшиеся в наследство от предыдущей.
Конструктор отчетов Rave Reports В среде Delphi 6 отчеты создавались с помощью набора компонентов, расположенных на вкладке QReport и имеющих общее название Quick Report. Эти компоненты поставлялись и в более ранних версиях Delphi. Ближе к концу главы мы обзорно рассмотрим и их, поскольку Quick Report поддержаны на уровне дополнительных компонентов также и в Delphi 7. Quick Report не входит в интегрированную среду разработки Delphi 7 по умолчанию. Чтобы получить возможность с ним работать, вы должны сначала установить модуль dclqrt70.bpl. Для этого требуется выбрать в главном меню пункт Component > Install Packages (Компонент > Пакеты установки). В открывшемся диалоговом окне нужно нажать кнопку Add и затем просмотреть установочные каталоги Delphi для выявления расположения модуля ddqrtJO.bpL (заданное по умолчанию расположение — C:\Program Files\Borland\Delphi7\bin). По завершении установки в панель компонентов будет добавлен новый — QReport, и вы сможете выполнять примеры программ и создавать собственные отчеты с помощью этого средства. (Вообще говоря, различные средства установки поступают по-разному. InstallShield автоматически подключает дополнительные модули, если может их найти. Другие инструментальные средства могут просто сообщать о наличии таких модулей или же генерировать отказ компоновки, если нужные средства не включены в проект.) Отчетом называется документ, предназначенный для печати на принтере, который содержит выборочные данные из таблиц базы данных.
112
Зянятие 7. Отчеты в Delphi 7
Согласно классификации, принятой в Delphi 6, все отчеты, создаваемые Quick Report, можно разделить на следующие: • простые; • с группированием данных; • для связанных наборов данных; • составные. Простым отчетом называется отчет, составленный из записей одного набора данных, которые выводятся в табличном виде без дополнительных условий (таких как группирование данных). Отчеты с группированием данных нужны для того, чтобы данные отчета были сгруппированы по какому-либо признаку. Например, если таблица содержит записи о проданных товарах, при выводе сведений об имеющихся на складе остатках удобно группировать записи по видам товара. Для группирования записей отчета по определенному полю набора данных необходимо установить текущий индекс по данному полю. Отчет для связанных наборов данных позволяет группировать данные по принципу, несколько отличающемуся от простого объединения данных. Основными полосами отчета для связанных наборов данных являются: • полоса данных; • полосы детализации. Для полосы данных указывается главный набор данных, а для полосы детализации — подчиненный набор данных. Составной отчет объединяет в себе несколько отчетов. Этот компонент является визуальным и при помещении на форму не содержит ни одного отчета. Добавление нового отчета в составной отчет происходит по событию. Естественно, внедряемый отчет должен быть предварительно подготовлен. Средства Quick Report достаточно жестко привязываются к перечисленным выше типам отчетов и обладают меньшей гибкостью по сравнению с теми, которые появились в последней реализации Delphi. Среда Delphi 7 предлагает отказаться от механизма Quick Report и перейти к использованию компонентов Rave Reports. Эти компоненты были разработаны компанией Nevrona (www.nevrona.com/rave) и позволяют создавать кроссплатформенные отчеты, поддерживающие такие механизмы доступа к данным, как BDE, dbExpress и ADO. В отчеты Rave Reports можно включать графические элементы, кроме того, отчет может быть сохранен в различных форматах (в число которых входят PDF, HTML и RTF-форматы). Инструменты Rave позволяют проектировать отчеты для различных сочетаний полос отчета и наборов данных. Например, группирование данных может быть обеспечено размещением на форме отчета одного компонента Data Cycle. Из представленной выше классификации, пожалуй, только простые отчеты в силу своей простоты продолжают выделяться особым образом.
Визуальный дизайнер Rave Reports Rave Reports может использоваться и в более ранних версиях Delphi (начиная с четвертой). Визуальный дизайнер отчетов, входящий в состав Rave Reports (кстати,
Конструктор отчетов Rave Reports
113
не переводите Rave буквально во избежание стресса, это просто аббревиатура, образованная от Report Authoring Visual Environment), работает на компонентой основе и позволяет визуально создавать разнообразные отчеты. Этот дизайнер отчетов может работать независимо от того, установлена на компьютере среда Delphi или нет. Таким образом, конечный пользователь получает возможность редактировать отчеты, поставляемые с вашими программами, с помощью такого же дизайнера отчетов. Различным пользователям Rave можно задать свой уровень сложности работы с визуальным дизайнером (Beginner, Intermediate и Advanced) согласно их квалификации. Но если вы считаете, что даже начального уровня в иных случаях больше чем нужно, задействуйте мастер — Simple Table и Master-Detail. Мастера используются для запроса соединения с данными и позволяют пользователю выбрать поля, нужные для данного отчета. Обязательным условием является предварительная активизация Direct DataView. Simple Table Wizard генерирует простые отчеты списочного типа, Master-Detail Wizard позволяет создавать составные отчеты. Количество мастеров в Rave невелико, но это приложение имеет открытую архитектуру, благодаря чему вы можете создавать собственные мастера, адаптированные под нужды конечного потребителя. Для запуска дизайнера отчетов Rave Reports вы можете запустить приложение Rave.exe, находящееся в папке, в которую вы установили Delphi 7, по следующему пути: \Rave5 ~ То есть, по умолчанию, C:\Program Files\Borland\Delphi7\Rave5.
Вы также можете запустить это приложение с помощью пункта главного меню Delphi 7: Tools > Rave Designer (Инструменты > Дизайнер отчетов). После запуска дизайнера отчетов появится окно, показанное на рис. 7.1. Окно дизайнера отчетов состоит из следующих элементов: • область навигации (Navigation Area) — верхняя часть окна. Содержит главное меню, а также панели инструментов и панель компонентов; • страница отчета (Page) — основа для вашего отчета. Находится в центре окна и разбита на ячейки с помощью сетки; • панель дерева проекта (Project Tree Panel) находится в правой части окна. Позволяет быстро просматривать структуру проекта, а также быстро переходить к нужному объекту проекта; • панель свойств (Property Panel) расположена в левой части окна. Служит для отображения значений свойств выбранного компонента, а также для задания значений свойств компонентов отчета. Панель инструментов проекта обеспечивает его базовую функциональность. Эти функции будут «кирпичиками» для всех ваших отчетов. Наибольшее значение из них имеют первая кнопка (RaveProject) и вторая секция панели инструментов (New Report, New Global Page, New DataObject и New Report Page). Эти функции используются для изменения существующей структуры проекта. В структуре проекта дизайнера отчетов выделяются следующие элементы: • Rave Project — компонент, который является контейнером для всех прочих компонентов, все они помещаются в дереве проектов под узлом этого компонента. Компонент Rave Project создается одновременно с созданием нового файла проекта
114
Зянятие 7. Отчеты в Delphi 7
и всегда имеется только один компонент RaveProject для одного такого файла, что отличает его от прочих компонентов. Но как и любой другой компонент, он имеет свои свойства, с которыми можно ознакомиться на панели свойств. AdminPassword позволяет администратору Rave Server ограничить доступ пользователей к создаваемым отчетам и данным. Parameters позволяет создавать элементы, в которые Delphi может помещать результаты вычислений для использования их другими компонентами. Свойство PIVars предназначено для описания специфических данных, требующих динамического обновления во время генерации отчета (нетипичные вычисления или операции над компонентами защиты);
-
.
•
'
•
.
'•'•'••
,:•.'
Рис. 7.1. Окно дизайнера отчетов
Компонент Report (Отчет) содержит страницы отчета. Поддерживается множество отчетов для одного проекта, и каждый отчет может иметь свое множество страниц. Каждый отчет имеет собственные свойства. Мы не будем их описывать ввиду достаточной прозрачности. Познакомиться с ними вы можете на панели свойств, предварительно выделив компонент Report в дереве проекта; Page (Страница).— базовый визуальный компонент, на котором помещаются все стандартные компоненты, компоненты отчета, рисования и другие, в целом представляющие собой законченный шаблон для вывода. Страница также имеет свои свойства, увидеть которые можно, щелкнув в пустом месте страницы; Global Page. Глобальные страницы размещаются в под узлом Каталога глобальных страниц (Global Page Catalog) в дереве проекта. Каждая глобальная страница по определению считается master-страницей. Все глобальные страницы могут быть «зеркалированы». Они могут содержать шаблоны, предназначенные для
Конструктор отчетов Rave Reports
115
различных целей, и использоваться различными отчетами проекта. «Зеркалирование» глобальной страницы может потребоваться, например, если вы ходите получить на выходе то же содержимое, но с другим заголовком; • Data Objects (Объекты данных) — это компоненты Data Connection для соединения с данными, или компоненты, используемые для контроля, кому разрешено просматривать отчеты на стороне сервера отчетов. Диалоговое окно Data Connection, появляющееся при нажатии кнопки New Data Object, предлагает пять вариантов выбора: DataLookupSecurity Controller, Database Connection, Direct Data View, Simple Security Controller и Driver Data View. Выбранный здесь объект помещается в дерево проекта в словарь видов данных (Data View Dictionary). Мы не будем подробно рассказывать обо всех, но задержим внимание на Direct Data View, поскольку именно этот компонент был разработан специально для Borland-редакции Rave Reports и обеспечивает соединение с данными из приложений на Delphi. При его использовании вы должны иметь запущенное приложение и форму с созданным компонентом Data Connection. Соединение осуществляется через свойства Name компонента Data Connection вкладки Rave и свойство ConnectionName для созданного Direct DataView. Рассмотрим основные элементы области навигации более подробно.
Область навигации. Панели инструментов Панели инструментов представляют собой наборы пиктограмм, связанных с той или иной функцией (рис. 7.2).
Рис. 7. 2. Панели инструментов Rave Designer
Перечислим пиктограммы панелей инструментов, показанных на рис. 7.2, слева направо и сверху вниз: • New Project — открывает новый проект; • Open Project — отображает диалоговое окно открытия заданного проекта; • Save Project — служит для сохранения текущего проекта; • New Report —создает новый отчет; • New Global Page — служит для создания новой глобальной страницы отчета; • New Data Object — позволяет задать новую связь с данными (таблицей базы данных); • New Report Page — предназначена для создания новой страницы отчета; • Execute Report — позволяет просмотреть или распечатать отчет; • Activate Grid — включает или выключает сетку; • Snap To Grid — включает или выключает привязку элементов отчета к сетке; • Grid On Top — включает или выключает отображение сетки поверх всех элементов отчета; • Always Show Band Headers — включает или выключает показ заголовков полос отчета;
шшпшшиишииниш
116
Зянятие 7. Отчеты в Delphi 7
• Show Rulers — включает или выключает показ линеек; • Show Waste Area — включает или выключает отображение области печати; • Edit Preferences — открывает диалоговое окно настроек среды дизайнера отчета. 1
Область навигации. Панель компонентов Панель компонентов состоит из нескольких вкладок, на каждой из которых расположены компоненты, сгруппированные по категориям (рис. 7.3).
Рис. 7.3. Панель компонентов. Вкладка Alignment .
Давайте кратко рассмотрим вкладки панели компонентов, а также компоненты, находящиеся на этих вкладках. • Вкладка Alignment (Выравнивание) (рис. 7.3) содержит компоненты, предназначенные для выравнивания элементов отчета на форме. Данная вкладка условно поделена разделителями на четыре секции. Компоненты, расположенные на этой вкладке (слева направо): Q Align Left Edges — выравнивание выбранных элементов отчета по левому краю; Q Align Horizontal Centers — выравнивание по горизонтальной линии, делящей каждый элемент на две равные части; Q Align Right Edges — выравнивание выбранных элементов отчета по правому краю; Q Center Horizontally — выравнивание по левому и правому краю элементов отчета; Q Space Equally Horizontally — установка равных горизонтальных промежутков между выбранными элементами отчета; a Equate Widths — установка одинаковой ширины для всех выбранных элементов отчета; Q Align Top Edges — выравнивание выбранных элементов отчета по положению верхней части; Q Align Vertical Centers — выравнивание по вертикальным линиям, делящим каждый элемент на две равные части; Q Align Bottom Edges — выравнивание выбранных элементов отчета по положению нижней части; Q Center Vertically — выравнивание по верхней и нижней части элементов отчета; О Space Equally Vertically — установка равных вертикальных промежутков между выбранными элементами отчета; Q Equate Heights — установка одинаковой высоты для всех выбранных элементов отчета; Q Move Forward —перемещение элемента отчета на передний план; Q Move Behind — перемещение элемента отчета на задний план;
Конструктор отчетов Rave Reports
117
Q Bring To Front — перемещение элемента «на самый верх» (то есть поверх всех элементов); a Send To Back — перемещение элемента на самый задний план (под все другие элементы отчета); Q Tap Left — перемещение элемента на шаг влево; Q Tap Right — перемещение элемента на шаг вправо; Q Tap Up —перемещение элемента на шаг вверх; Q Tap Down — перемещение элемента на шаг вниз. Вкладка Fonts (Шрифты) содержит компоненты, с помощью которых можно установить необходимое шрифтовое оформление для любого текстового элемента отчета (рис. 7.4). йерой [ Zoom )
Рис. 7.4. Вкладка Fonts Вкладка Fills (Заполнение) содержит компоненты, посредством которых можно заполнять различными узорами графические элементы отчета (рис. 7.5).
Рис. 7.5. Вкладка Fills
Вкладка Lines (Линии) включает в себя компоненты, предназначенные для установки толщины и стиля начертания линий у графических элементов отчета (рис. 7.6).
Рис. 7.6. Вкладка Lines Вкладка Colors (Цвета) содержит компоненты, предназначенные для задания необходимого цвета для элементов отчета (рис. 7.7). :' \ Tife" j fonts j Alignment |
Рис. 7.7. Вкладка Colors
.
• Вкладка Zoom (Масштабирование) состоит из компонентов, предназначенных для просмотра страницы отчета с различной степенью детализации (рис. 7.8). 1 В я Code I Standard I Report
Zoom I Cotos i Lines I
Рис. 7.8. Вкладка Zoom
FBs \ Fonts 1 ABanment
118
Зянятие 7. Отчеты в Delphi 7
Вкладка Report (Отчет) содержит пиктограммы, помеченные в правом верхнем углу красной точкой (рис. 7.9). Это означает, что данные компоненты предназначены для связи с табличными данными и отображения табличной информации. Пока только кратко опишем каждый из компонентов (слева направо), но закончив перечисление предоставляемых инструментов, вернемся к более детальному их рассмотрению: Q DataText предназначен для отображения строки текста из поля таблицы; Q DataMemo используется для отображения многострочного текста из поля таблицы типа Memo; Q CalcText служит для отображения результата арифметических действий, указанных в свойстве CalcType, с полем таблицы; a DataMirrorSection предназначен для задания так называемой «зеркальной» области, которая будет использоваться в отчете для создания вариаций отчетов; a Region предназначен для объединения нескольких полос отчета и является для них контейнером. Применяется при создании отчетов вида master—detail; Q Band применяется для создания новой полосы отчета, в которой можно размещать элементы отчета; Q DataBand предназначен для создания полосы отчета, в которой будут расположены элементы отчета, связанные с таблицей базы данных; a DataCycle представляет собой невидимую полосу отчета, связанную с таблицей базы данных, и ориентированную для работы с изменяющейся в таблице информацией; a CalcOp — невизуальный компонент, предназначенный для выполнения операции (указанной в свойстве Operator) над операндами, являющимися значениями из двух различных источников данных; Q CalcTotal — невизуальный компонент, предназначенный для вычисления арифметического выражения, указанного в свойстве CalcType, над полем таблицы, с дальнейшей передачей полученного значения в параметр проекта, указанный в свойстве DestParam; Q CalcController — невизуальный компонент, служит контроллером для всех вычисляемых компонентов типа Calc. Когда данный компонент выводится на печать, во всех вычисляемых компонентах производятся необходимые арифметические вычисления.
Рис. 7.9. Вкладка Report
Вкладка Standard (Стандартные) содержит компоненты, предназначенные для размещения на странице отчета надписей, рисунков и других данных, не связанных с таблицей базы данных (рис. 7.10). Рассмотрим эти компоненты (слева направо): Q Text предназначен для вставки в отчет строки текста; Q Memo служит для вставки в отчет многострочного текста;
Конструктор отчетов Rave Reports
119
Q Section позволяет объединять компоненты в группы; Q Bitmap и Metafile предназначены для вставки в отчет графических элементов; Q FontMaster позволяет задать фиксированный шрифт для различных частей отчета; Q PageNumlnit задает номер начальной страницы отчета.
Рис. 7.10. Вкладка Standard
Вкладка Bar Code (Кодировка) содержит компоненты, предназначенные для определения перекодировочной таблицы отчета (рис. 7.11). j Standard j Report j Zoom j Cotes
Рис. 7.11. Вкладка Bar Code
Вкладка Drawing (Рисование) содержит компоненты, предназначенные для размещения на странице отчета графических фигур и линий (рис. 7.12).
Рис. 7.12. Вкладка Drawing
Структура приложения, использующего Rave Reports Rave представляет собой два продукта в одном: объектно-ориентированные средства печати данных (13 компонентов Delphi и около 500 методов, свойств и событий) и визуальный интерфейс проектирования, в комплексе позволяющие создавать отчеты без утомительного программирования принтера (TPrinter) напрямую или с использованием Windows API. Визуальный дизайнер Rave — независимое от Delphi приложение, за счет чего для конечных пользователей отпадает необходимость в случае внесения изменений в отчет задействовать Инспектор объектов Delphi или другие средства разработки. При этом разным пользователям можно задать свой уровень сложности работы с визуальным дизайнером (Beginner, Intermediate и Advanced) согласно их квалификации. В структуру приложения, использующего Rave Report, в обязательном порядке входят следующие составляющие. • Стандартные компоненты Data Connection. А именно, RvCustomConnection, RvDataSetConnection и RvTableConnection — обеспечивают связь между данными в вашем приложении и визуальными компонентами Rave. RvCustomConnection также может быть использован для доступа к данным, отличным от табличных, таким как массивы в памяти или файлы с двоичным типом записей.
120
Зянятие 7. Отчеты в Delphi 7
• Компонент RvProject содержит множество свойств и методов и обеспечивает доступ к отчетам и их компонентам — позволяет вам создавать, изменять, отображать и печатать их. Как правило, приложение содержит только один компонент RvProject, что не сказывается на его функциональности. • Файл проекта отчета с расширением RAV. В нем сохраняются все определения и настройки, подготовленные при работе с визуальным дизайнером. По структуре RAV-файл напоминает DFM-файлы Delphi. Все отчеты, глобальные страницы и виды данных при этом сохраняются в одном файле, элементы которого можно импортировать в другой проект. Используя методы компонента RvProject, вы можете также сохранить файл проекта отчета в BLOB-поле базы данных или в другом месте. • Непосредственно отчеты сохраняются в Библиотеке отчетов (Report Library) проекта. При работе с проектом Rave вы подготавливаете страницы отчета, на которых размещаются визуальные компоненты. Вы можете создать множество таких страниц и сочетать их при помощи большого разнообразия методов. • Глобальные страницы сохраняются в Каталоге глобальных страниц (Global Page Catalog) проекта. Компоненты, содержащие глобальные страницы, используются для хранения шаблонов, которые «зеркалируют» другие страницы отчета. • Виды данных сохраняются в Словаре видов данных проекта (Data View Dictionary). Они являются интерфейсом для компонентов Data Connection. Когда вы создаете новые виды данных, вы должны иметь активный компонент Data Connection в приложении или загруженную форму Delphi. Виды данных становятся нужны тогда, когда запрос к компонентам Data Connection возвращает мета-данные, такие как имена полей, типы данных и т. д. Поля компонентов, которые содержатся в каждом виде данных, позволяют управлять отображением соответствующих колонок данных.
Компоненты страницы отчета Компоненты вкладки Report наиболее часто используются при проектировании отчетов, ориентированных на работу с базами данных. О них мы упоминали выше, но перечислим еще раз: Band, CalcText, DataBand, DataMemo, DataText, Region, CalcController, CalcOp, CalcTotal, DataCycle, DataMirrorSection. Большинство из них, включая невизуальные, могут быть размещены непосредственно на странице отчета. Но есть два исключения — Band и DataBand. Они должны обязательно помещаться в компонент Region. Отчет может быть размечен как типичный шаблон, использующий строго определенные полосы, например, как в QuickReport. Но отличительной особенностью Rave Reports является то, что отчет может быть видоизменен в соответствии с другими требованиями. Полосы отчета могут быть передвинуты или изменен их размер. Управлять видимостью полос при работе с визуальным дизайнером можно двумя способами. В первом случае можно указать явно, что заголовки всех полос должны быть видимы, установив флажок Always Show Band Headers в окне, открываемом командой меню Edit > Preferences (или воспользуйтесь кнопкой панели инструментов). Другой путь — использовать свойство DesignerHide для каждой полосы по отдельности. Установка в true скрывает полосу. Это может быть полезно при большом количестве полос или когда полоса занимает много места на странице. При этом свойство DesignerHide не оказывает влияния на вид отчета при печати, оно эффективно только в режиме визуального проектирования.
Конструктор отчетов Rave Reports
121
Region Перед тем как использовать регионы, нужно четко понимать, что они из себя представляют. Region (Регион) — контейнер для полос. В простейшем случае регион может занимать целую страницу. Это типично для отчетов списочного типа (list type). Вместе с тем в свойствах региона имеется возможность указывать его размер и точное положение на странице. Преимущества гибкости использования регионов проявляются при разработке составных отчетов, с группированием данных, для связанных наборов данных. На одной странице может быть размещено несколько регионов в произвольном сочетании: сторона к стороне, один над другим или в шахматном порядке. Не путайте регион с секцией. Регион всегда содержит полосы и только полосы. Секция же может включать в себя любые группы компонентов, включая регионы. Заметьте, что количество регионов на странице не ограничивает число полос внутри регионов. Если вы испытываете трудности в процессе чисто визуального редактирования, вы должны понимать, что в вам доступны самые различные сочетания регионов и полос, нужно только суметь спроецировать их в свое сознание для мысленной «визуализации». DataBand Компонент DataBand предназначен для отображения динамической информации из видов данных. Как правило, DataBand содержит несколько компонентов DataText. Сущность DataBand легко понять на типичном примере — счете-фактуре. Обычно накладная содержит заголовочную информацию, такую как дата, номер счета, имя и адрес клиента и одну или более строк с элементами фактической информации. В этом примере пользовательская таблица будет master-таблицей, а элементы — detalil-таблицей. Информация об элементах может быть размещена в DataBand и управляться с помощью master-таблицы. Свойство BandStyle компонента DataBand задает местоположение полосы при печати и описывает случаи, как полоса будет использоваться при выводе. Для каждой полосы можно установить флажки в любом сочетании, то есть возможно задание верхнего или нижнего колонтитула (страницы, группы, строки), которые будут выводиться на первой странице отчета, на всех последующих и для отдельных колонок. Выбор производится в окне Band Style Editor, открываемом при установке значения в свойстве BandStyle (рис. 7.13). Каждый стиль (флажок) имеет сокращенное обозначение (буква в скобках), которое будет показываться в правой части заголовка полосы в случае его установки. Следует помнить, что при печати полосы региона упорядочиваются в соответствии с их определением во время проектирования. Возможные действия с полосами в окне регламентируются именно этим порядком. Верхние колонтитулы (прописные буквы, BGR) будут напечатаны первыми для всей полосы, тогда как нижние колонтитулы (строчные буквы, bgr) — на каждом уровне. Тем не менее, если есть более чем один верхний колонтитул для какого-либо особенного уровня, тогда каждый верхний колонтитул полосы будет распространен в порядке их определения в регионе. Да, технически возможно разместить все верхние колонтитулы сверху, все компоненты DataBand по центру и все нижние колонтитулы внизу региона для всех уровней master—detail. Или каждый уровень будет сгруппирован со всеми присвоенными ему колонтитулами и данными. Но Rave подразумевает, что описание региона — путь, обеспечивающий легкость восприятия конструкции потока. Просто помните, что последовательность подобных полос на одном уровне определяется порядком их определения в регионе.
122
Зянятие 7. Отчеты в Delphi 7 Band Style Editt» • ВапсП (Master) Ф DataBandl (Master) ^DataBandKMastert ^ DataBandKMaster)
•
Рис. 7.13. Окно редактора Band Style Editor
Band Компонент Band служит для размещения фиксированных компонентов, не изменяющихся на странице. В общем, компонент Band может содержать компоненты Text и CalcText. Типичный пример — верхние и нижние колонтитулы. Тем не менее, компонент Band может также содержать и компоненты для отображения информации из полей таблиц баз данных. Наиболее важным свойством компонента Band является ControllerBand. Это свойство определяет, будет ли полоса DataBand, имя которой устанавливается в значении этого свойства, подчинена компоненту Band (управляться им). Когда принадлежность полосы установлена, заголовок контролируемой полосы будут отображаться так же (включая символы и цвет), как в управляющей. Удобство этой возможности станет очевидным тогда, когда вы измените состояние флажка Always Show Band Headers. В заголовках полос присутствуют также специальные значки, которые показывают отношения вида master—detail (родительский—дочерний) между различными полосами. Вытянутый треугольник говорит о том, что полоса контролируется master-полосой того же цвета (уровня), которая расположена по направлению острого угла. Ромб свидетельствует о том, что это — master- или управляемая полоса. Помните, что вы можете иметь отношения вида master-detail-detail, где обе detailполосы управляются одним master-компонентом или же одна из detail-полос подчинена другой. Заголовок каждой полосы кроме ее имени также содержит в правой части несколько символов, соответствующих ее стилю и уровню. Так, на master-полосе вы увидите MASTER1PC, а на контролируемой — BGRDrgblPC. Если стиль не поддерживается, соответствующая буква погашена (серая). Имена компонентов Region, Band и DataBand могут включать буквы английского алфавита, цифры и символ подчеркивания, но должны быть уникальны.
Конструктор отчетов Rave Reports
123
DataText Компонент DataText служит для работы с данными, то есть может быть использован для отображения значений из полей набора данных в любом месте страницы. Например, вы можете выводить с его помощью пользовательскую информацию из компонента DataBand, но также можете печатать параметры и переменные проекта. Эти возможности предоставляет Data Text Editor. Вам разрешено использовать подстановки для полей с аналогичным содержанием, используя свойства LookupDataView, LookupDisplay, LookupField и Lookuplnvalid. Связать компонент DataText с данными вы можете двумя способами. Первый — выбор одиночного имени поля из выпадающего списка. Это хорошо для отчетов, требующих однозначного соответствия между полем и элементом DataText. Но вам также позволено комбинировать между собой много различных полей данных, привязывая их к одному компоненту DataText с помощью окна DataTextEditor (рис. 7.14). Этот редактор, вызываемый щелчком на кнопке с многоточием при изменении значения в свойстве, позволяет конкатенировать поля, параметры и переменные, строя соответствующие выражения. В окне редактора имеются 4 группы элементов управления: Data Fields, Report Variables, Project Parameters, Post Initialize Variables и Data Text. Data Text — это результирующее окно. Перед вставкой какого-либо элемента в него вам следует нажать одну из двух кнопок в правой части этого окна.
Рис. 7.14. Окно редактора Data Text Editor
Кнопка + соединяет два значения между собой без пробелов, а кнопка & конкатенирует их через одиночный пробел. Нужное поле из таблицы базы данных выбирается в списке, после чего требуется нажать кнопку Insert Field. Содержание списка
124
Зянятие 7. Отчеты в Delphi 7
определяется выбранным видом данных в левой части группы Data Fields. К результирующему выражению можно присоединить различные переменные отчета, такие как номер текущей страницы или дата и время выбором из списка Report Variables. Вы также можете добавить свои собственные параметры, например имя пользователя, заголовок отчета или настройки пользователя. (Для того, чтобы создать параметр, необходимо выбрать в дереве проекта корневой узел проекта и в панели свойств открыть редактор строк, нажав на многоточие при изменении свойства Parameters.) В результирующее выражение DataText можно добавлять строковые константы, ограниченные апострофами или кавычками. В принципе, выражение можно ввести и как просто строку в поле, но в таком случае к вам предъявляются повышенные требования к контролю его корректности.
DataMemo Компонент DataMemo позволяет добавлять в отчет мемо-поля базы данных, то есть содержащие многострочные тексты. Например, помещать комментарий в углу страницы. Для выбора мемо-поля нужно установить значения свойств DataView и Data Field. Rave Reports предоставляет функцию mail merge, которая дает возможность динамически делать замещения в мемо-полях. Окно Mail Merge Editor открывается (рис. 7.15) при щелчке на кнопке с многоточием при задании значения свойства MailMergeltems. В окне редактора можно определить искомые замещаемые фрагменты (используйте кнопку Add и поле Search Token) и значение замещения, которое может представлять собой выражение, аналогичное получаемому при использовании DataTextEditor (этот редактор вызывается при нажатии кнопки Edit).
Рис. 7.15. Окно редактора Mail Merge Editor
CalcText Различие между компонентами DataText и CalcText заключается в том, что рассматриваемый компонент специально предусмотрен для вычислений и отображения их результатов. Свойство CalcType определяет тип вычисления, соответствующий
Конструктор отчетов Rave Reports
125
стандартным агрегатным функциям: ctAverage, ctCount, ctMaximum, ctMinimum и ctSum. Свойство CountBlanks указывает, будут ли пустые (нулевые) значения учитываться при подсчете суммы или среднего. Свойство Рипт'пдТо1а1задает, будет ли в момент запуска генерации отчета обнуляться вычисляемое значение. CalcOp Невизуальный компонент, с помощью которого можно производить всевозможные вычисления с данными, включающими в себя значения из полей таблиц (свойство SrclDataField, Src2DataField), константами (SrclValue, Src2Value) и других вычисляемых параметров (ScrlCalcVar, Src2CalcVar). Свойство Operator задает тип операции. Каждый операнд может быть дополнительно обработан с использованием стандартных функций, например тригонометрических (SrclFunction, Src2Fuction). Задействуй параметры проекта для хранения промежуточных результатов вычислений, можно строить сколь угодно сложные выражения. • CalcController Невизуальный компонент, связывающий между собой компоненты DataBand, CalcText и CalcTotal через их свойства Controller. В процессе печати отчета обрабатывает сигналы от этих компонентов, вырабатывая результат операции в зависимости от полосы, на которой данный компонент расположен. Другая функция — инициализация компонентов CalcText и CalcTotal указанным значением (свойства InitCalcVar,
InrtDataField и InitValue). -
CalcTotal Невизуальная версия компонента CalcText, во время «печати» которой отображаются значения, сохраненные в параметре проекта (свойство DestParam) и форматируются в соответствии со значением свойства DisplayFormat. Используется для выполнения вычислений, результаты которых будут нужны для проведения других вычислений посредством компонентов CalcOp. Data Cycle Невизуальная полоса отчета, связанная с таблицей базы данных, и ориентированная для работы с изменяющейся в Data View информацией. По сути, представляет собой цикл (петлю) через все detail-записи данных для одного уровня master-записи. Типичный случай: счет, генерируемый для таблицы со множеством пользователей, в которой каждый пользователь имеет различные статьи расхода, связанные с этим счетом. Для каждого такого пользователя вы должны представить список его собственных расходов. В таком случае вы можете организовать master-таблицу, в которой каждому пользователю будет присвоен уникальный идентификатор. В результате перед выводом на печать информации по каждому следующему пользователю будет осуществляться цикл по таблице, содержащей сведения по всем статьям расхода, с ним связанным. Имя такой master-таблицы определяется свойством MasterDataView. Две таблицы связываются между собой посредством свойства DetailKey. В нашем примере это идентификатор пользователя. Данные компонента DataCycle могут быть во время формирования отчета отсортированы или отфильтрованы. Эту возможность предоставляет свойство MasterKey. Если нажать на кнопку с многоточием при задании значении свойства, откроется
126
Зянятие 7. Отчеты в Delphi 7
окно Data Text Editor (рис. 7.14). Например, если вы хотите исключить из отчета всех пользователей, проживающих за пределами вашего города, введите в поле Data Text этого окна соответствующее значение.
DataMirror Section Компонент DataMirrorSection предназначен для задания так называемой «зеркальной» области, которая будет использоваться в отчете для создания вариаций отчетов и представляет собой секцию, которая копирует с незначительными расхождениями оригинальную секцию, основываясь на содержании свойства DataReld. «Зеркалирование» секций — мощный метод, поскольку секция (TRaveSection, похожа на TPanel в Delphi) может содержать любые другие компоненты, включая графические, регионы, текстовые и т. д. При этом все дочерние ее элементы зеркалируются. При изменении оригинального компонента все зеркалируемые соответственно изменяются. В качестве примера рассмотрим компонент DataMirrorSection, включенный в демонстрационный файл Rave (найдите его в каталоге Rave и откройте). Этот пример демонстрирует, как зеркалируется блок адресных данных в международный или американский формат (в формате США отсутствует строка государства и сам блок смещен к краю). На странице 2 имеются три секции. Секция 3 включает в себя общие строки, которые присутствуют в обоих шаблонах. Секции 1 и 2 содержат зеркала секции 3. В «международной» секции дополнительно находится строка государства. Заметьте, что комментарий («remarks»), который будет добавлен на страницу 2 проекта — не есть часть какой-либо секции. «US Template» и «International Template» это обычный текстовый комментарий, помогающий понять назначение каждой секции. Свойства DataView и DataField компонента DataMirrorSection на странице 1 используются для выбора шаблона форматирования для зеркала. Чтобы понять логику взаимодействия, щелкните на кнопке с многоточием при задании значения свойства DataMirrors для открытия окна Data Mirror Editor. Выберите пункт DataMirror и ознакомьтесь с установками в нижней группе элементов этого диалогового окна. Обратите внимание, что одна из установок должна быть помечена флажком Default. Если вы этого не сделаете, то при форматировании будет использовано родное содержание компонента.
Компоненты управления отчетом Рассмотрим компоненты для создания отчетов, которые поставляются вместе со средой Delphi 7 и располагаются на вкладке Rave палитры компонентов Delphi. Общий вид вкладки Rave показан на рис. 7.16.
Рис. 7.16. Вкладка Rave палитры компонентов Delphi 7
л
В Rave Reports имеются 2 различных типа объектов: компоненты вывода (Output Components) и классы отчета (Report Classes). Первые отвечают за отправку отчета по различным назначениям, вторые представляют собой управляющие классы. Вкладка содержит тринадцать объектов, часть из которых относятся к первому типу (на пиктограммах с наличием голубого цвета), а остальные соответственно, — ко второму. Все эти объекты мы опишем ниже в порядке их размещения на вкладке слева направо.
Конструктор отчетов Rave Reports
127
Компонент RvProject Компонент RvProject — предназначен для установки связи с файлом отчета, который был создан с помощью дизайнера Rave Reports. Используйте этот класс для получения доступа к листингам любых отчетов и их выполнения. Обычно в приложении используется всего один компонент RvProject, но вы можете определить их и больше, если это необходимо. Свойство ProjectFile задает файл проекта отчета. Этот файл с расширением RAV может содержать множество различных требуемых вам вариантов отчета. При вызове метода Open файл проекта отчета загружается в оперативную память для подготовки печати отчета или настройки конечным пользователем. Вы можете использовать метод Close, если больше не собираетесь работать с проектом или перед завершением работы приложения. Любые изменения, внесенные в проект отчета, вы можете зафиксировать методом Save. RvProject также содержит несколько свойств и методов, таких как SelectReport, GetReportList, ReportDescToMemo, ReportDesc, ReportName и ReportFullName, позволяющих создать эффективный интерфейс для пользователей проекта (рис. 7.17).
time Pmjecfife
iS2SS25!
;io«»;ti;,;.fr,0nei Vets»
" 5,0.04 jVO.7
Рис. 7.17. Свойства компонента RvProject
Свойство Engine позволяет назначить альтернативное средство для вывода отчета. Для этого соответствующим образом настраивается компонент RvSystem и генерируются NDR-потоки или файлы посредством компонента RvNDRWriter. При включении компонента RvProject в свое приложение вы должны обеспечить следующую базовую последовательность операций и реагирование на действия пользователя: 1. Вызвать метод RvProject.Open, то есть открыть файл проекта, указанный в свойстве ProjectFile. 2. Вызвать метод RvProject.GetReportList(ListBoxl.Items, true) для загрузки имен отчетов в список ListBoxl. 3. Задать обработку события OnClick (щелчков пользователем кнопкой мыши на элементах списка). Для этого вызовите RvProject.SelectReport(ListBoxl.Items[ListBoxl.ItemIndex],true); и затем RvProject.ReportDescToMerno(Memol); для выбора текущего элемента списка и копирования описания отчета в поле Memol.
128
Зянятие 7. Отчеты в Delphi 7
4. Вызвать RvProject. Execute для печати выбранного отчета. 5. Вызвать RvProject.Design, чтобы открыть визуальный дизайнер для работы с текущим отчетом для конечного пользователя (поддерживается только при наличии лицензии EUDL (End User Designer License). 6. Включить в проект метод RvProjectClose для закрытия отчета и освобождения выделенной памяти. Ради экономии ресурсов, выделяемых приложению, Rave Reports в обязательном порядке загружает только стандартные и графические компоненты, а также присутствующие на вкладке Report. Компоненты Bar Code и другие должны быть зарегистрированы и подключены для компиляции явно, если они используются приложением. Например, компонент Bar Code можно включить в приложение следующим образом. Сначала на форме с компонентом RvProject нужно добавить объект RvBarCodel для возможности использования его в программном коде, а после чего определить обработку события RvProject.OnCreate и вызвать метод RaveRegister для RvCsBars, как это показано ниже. procedure TForml.RvProjectCreate(Sender: TObject); begin RvBarCodel.RaveRegi ster; end: Эти действия обязательны для любых дополнительных компонентов. В противном случае вы при запуске проекта получите сообщение об ошибке вида «Класс TRavePostNetBarcode не найден». .
Компонент RvSystem Хотя в использовании компонент RvSysten самый легкий, следует обратить на него внимание, потому что интеграция компонентов RvRenderPreview, RvRenderPrinter и RvNDRWriter обеспечивается именно с его помощью. RvSystem может посылать отчет на принтер или экран предпросмотра, а также отображать настройки и статус экрана. Рассмотрим более подробно свойства этого компонента (рис. 7.18).
• . •
-л •
; ' -. • . . •
. • . • :
•
• • • ' - . '"
Рис. 7.18. Свойства компонента RvSystem Default Dest определяет место назначения отчета, предлагаемое по умолчанию;
Конструктор отчетов Rave Reports
129
• System Filer позволяют настроить обработчик файла отчета для RvNDRWriter, RvRenderPreview и RvRenderPrinter. Все опции SystemFiler не работают в режиме потока (если установлено значение smMemory для свойства StreamMode); • System Options управляют конфигурацией компонента RvSystem: Q значение soUseFHer будет всегда направлять отчет в файл отчета. Это может быть полезно при использовании метода Macro; Q soWaitForOK указывает, будет ли отчет посылаться для вывода при нажатии кнопки ОК; О soShowStatus определяет, будет или нет отображаться экран статуса во время генерации отчета; Q soAllowPrintFrom Preview определяет, может ли пользователь направить отчет с экрана предпросмотра на принтер; Q soPreviewModal устанавливает модальный режим окна предпросмотра; Q soNoGenerate указывает, пропускать ли этап генерации отчета, то есть выводить отчет непосредственно на экран. Эти настройки могут быть применены только в режиме StreamMode; • в свойстве SystemPreview отображаются все настройки предпросмотра, соответствующие RvRenderPreview; • в свойстве SystemPrinter отображаются все настройки принтера, соответствующие RvNDRWriter; • SystemSetups содержит логические свойства, отвечающие за конфигурацию экрана для RvSystem. \ Компонент RvNDRWriter Используется в сочетании с RvRenderPrinter и RvRenderPreview для сохранения отчета в файле специального бинарного формата (NDR) для последующей распечатки на принтере или предпросмотра. Полный список свойств и методов компонента представлен на рис. 7.19. Метод AccuracyMethod определяет способ вывода строк. FileName — файл, который будет создан, если StreamMode установлено в значение, отличное от smUser. Используйте smFile для больших отчетов (>10 страниц или при наличии серии изображений) и smMemory для маленьких отчетов (<10 страниц). Отчет направляется в файл вызовом метода Execute.
I Acct!tW3<M(
Рис. 7.19. Свойства компонента RvNDRWriter 5 Зак. 956
130
Зянятие 7. Отчеты в Delphi 7
Компоненты Data Connection
.
Используя события классов Data Connection, вы можете управлять посылкой данных в отчет Rave Reports. Всего имеются четыре таких компонента: • RvCustomConnection предназначен для связи DirectDataView, созданного дизайнером Rave Reports, с обычными данными (массивами в памяти, бинарными файлами, данными, генерируемыми во время событий); • RvDataSetConnection предназначен для связи DirectDataView с набором данных (например, компонентом DataSet); • RvTableConnection предназначен для связи DirectDataView с таблицей (например, компонентом Table); • RvQueryConnection класс предназначен для связи DirectDataView с запросом (например, компонентом Query). Компонент RvCustomConnection работает с индексированными данными и соответственно задействует свойства Datalndex и DataRows, в силу чего обработка событий при его использовании неактуальна. Наиболее эффективным для него является реагирование на OnNext. Если отчет предназначен для вывода информации из базы данных посредством компонентов Data Connection, вам не обойтись без обработки событий, и особенно — OnValidateRow. Имеются следующие виды событий: • OnEOF происходит при достижении конца данных. Значение true говорит о том, что строк для вывода больше не осталось или сгенерировано событие OnNext при попытке перехода за последнюю строку таблицы; • OnFirst происходит в момент перемещения указателя текущей записи в первую строку данных; • OnGetCols возникает, когда Rave Reports получает метаданные: имя поля, тип, размер символов, полные имя и описание; • OnGetRow происходит при получении данных из текущей строки; • OnGetSorts происходит при потребности Rave в информации о поддерживаемых методах сортировки; • OnNext возникает тогда, когда Rave хочет переместить указатель текущей записи на следующую строку данных; • ОпОреп генерируется при инициализации сессии. Текущее состояние может быть впоследствии восстановлено генерацией события OnRestore; • OnRestore происходит, когда Rave хочет восстановить состояние данных, запомненное перед открытием сессии; • OnSetFilter возникает при потребности фильтрации данных, например в отчетах master—detail; • OnSetSort возникает при потребности сортировки данных; • OnValidateRow генерируется для каждой строки данных для их фильтрации. В следующем примере показано, как можно исключить из отчета строки, не удовлетворяющие заданному условию, используя событие OnValidateRow. procedure Tforml.CustomCXNValidateRowCConnection: TRvCustomConnection:
var ValidRow: Boolean); begin
ValidRow := DataRecord.FloatField >= 0 . 0 : end:
Конструктор отчетов Rave Reports
131
Примеры обработки всех событий вы найдете в справочной системе и электронной документации к Rave Reports, но есть смысл внимание на одно из них, позволяющее проводить дополнительную обработку направляемых в отчет данных — OnGetRow. Есть несколько способов записи данных ъ специальный буфер. Порядок и типы сохраняемых полей (dtString, dtlnteger, dtBoolean, dtFloat, dtCurrency, dtBCD, dtDate, dtTime, dtDateTime, dtBlob, dtMemo и dtGraphic) могут быть получены непосредственно из описаний полей, предоставляемых событием OnGetCols. Данные в буфер можно поместить согласно следующему списку методов: procedure WriteStrData(FormatData: string: NativeData: string): { dtString } procedure WriteIntData(FormatData: string; NativeData: integer); { dtlnteger } procedure WriteBoolData(FormatData: string; NativeData: boolean); { dtBoolean } procedure WriteFloatData(FormatData: string; NativeData: extended); { dtFloat } procedure WriteCurrDataCFormatData: string: NativeData: currency); { dtCurrency } procedure WriteBCDData(FormatData: string; NativeData: currency): { dtBCD } procedure WriteDateTimeDataCFormatData: string; NativeData: TDateTime); { dtDate. dtTime and dtDateTime } procedure WriteBlobDataCvar Buffer: Len: longint): ( dtBlob. dtMemo and dtGraphic } Также имеется специальный метод WriteNullData (без параметров), который может быть вызван для любых инициализированных полей или содержащих нулевые данные. Параметр FormatData используется для передачи форматированной строки данных в поле. Параметр NativeData предназначен для передачи неформатированных или «сырых» данных в поле. Если специальное форматирование определено в отчете, то оно будет осуществляться для NativeData, иначе для печати будут использоваться данные FormatData. Например: procedure Tforml.CustomCXNGetRowC Connection: TRvCustomConnecti on): begin With Connection do begin WriteIntData(''.DataRecord.IntField): WriteStrData(''.DataRecord.StrField); WriteFloatDataC''.DataRecord.FloatField); end: { with }
end:
Свойство Name компонента Data Connection (рис. 7.20) используется для именования самого соединения с данными. Очень важно, чтобы ваши компоненты Data Connection имели уникальные имена во избежание возникновения пересечений внутри вашего приложения. Также хорошей практикой считается использовать уникальные для приложения идентификаторы для соединений, которые видны из других программ, например используя в качестве префикса сокращение-анаграмму от названия приложения. Свойство Visible компонента Data Connection определяет, будут ли доступны ваши соединения в других приложениях или версии Rave Reports для конечного пользователя. Соответственно, значение false блокирует видимость соединения извне, a true — открывает его для внешнего доступа. Пока соединение открытого типа доступно конечным пользователям, для него не будут отображаться попытки пользователей
132
Зянятие 7. Отчеты в Delphi 7
создать новый вид данных, если они производятся не изнутри приложения, которое запустило визуальный дизайнер. Если вы хотите сделать соединение с данными доступным из других приложений для ваших конечных пользователей, лучше будет создать проект отчета с версией визуального дизайнера ддя программистов, в которой все виды данных уже определены для таких внешних соединений с данными. yfl!s!ffl!!!!!ff!ffSIKS!K!ISBS!!!!Sf!!!!!l!f!lf!fflfl}flfl!!!l!!l!ll,l
|RvDataSetConnection1 TRvOateS-HCeri
•
Рис. 7.20. Свойства компонента RvDataSetConnection
Компоненты отображения Компонент RvRenderPreview подготавливает файл, генерируемый RvNDRWriter, и посылает его на экран для предпросмотра. Этот компонент поддерживает множество методов и событий, которыми разработчик может пользоваться для создания законченного пользовательского интерфейса. Не будем останавливаться на возможностях, определяемых свойствами этого компонента, — их описание доступно в справочной системе и вынудит нас частично повториться. Компонент RvRenderPrinter формирует файл, генерируемый RvNDRWriter, и посылает его на текущий принтер. RvRenderPrinter часто используется для печати с экрана предпросмотра. Это несложный компонент, не имеющий методов и свойств, позволяющих управлять принтерами и их настройками. Отчет посылается на печать вызовом методов Execute или ExecuteCustom. Компонент RvRenderPDF создает документы Adobe Acrobat из рабочего отчета. Если шрифты должны быть встроены в PDF-файл, свойство EmbedFonts устанавливается в значение true. Желаемое качество встраиваемых изображений устанавливается в процентном представлении в свойстве ImageQuality. Сжатие PDF-документов поддерживается свойством логического типа UseCompression, для которого должна быть предусмотрена обработка события OnCompress, например: With TCompressionStream.Create(clMax. OutStream) do try CopyFromdnStream. InStream.Size): finally Free; end: { with '} Самый простой путь использования компонентов отображения состоит в перетаскивании требуемого значка на форму, при котором автоматически регистрируется формат и стандартные настройки и диалоговые окна предпросмотра. Для получения отличного от стандартного представления вызывается метод Render с передачей в виде параметра объекта NDR TStream или имени файла NDR.
Конструктор отчетов Rave Reports
133
RvRenderHTML преобразует NDR-поток или файл в HTML-страницы с поддержкой графических объектов. Результат представляется согласно спецификации HTML 4.0, но с ориентацией для вывода на печать, насколько это возможно. RvRenderRTF преобразует NDR-поток или файл в RTF-формат. Результирующий RTF-документ по возможности приближен к оригинальному отчету, направляемому на принтер. Положение элементов документа на странице указывается с помощью разделителя frames. RvRenderText преобразует NDR-поток или файл в текстовый формат, при этом все нетекстовые объекты игнорируются. Свойства CPI и LPI задают количество символов и точек на дюйм соответственно при выводе на конечное устройство вывода. Пример создания отчета средствами Rave Reports В общем и целом, возможности разработки отчетов средствами Rave Report сводятся к настройке и организации связи двух независимых инструментов: средств вывода данных на печать (code-based printing engine) и визуального интерфейса (visual reporting interface). Рассмотрим порядок создания простого отчета с помощью мастера Simple Table, чтобы проследить взаимодействие между этими инструментами на примере. При этом последовательность действий после запуска Delphi и создания нового приложения включает в себя несколько этапов. 1. Сначала мы создадим компонент типа Table, Query или DataSet и инициализируем таблицу — установим свойство Active компонента в значение true для гарантии, что все другие свойства установлены корректно. Для простоты возьмем готовый пример из дистрибутивного набора Delphi — Customer.db. 2. После чего создадим компонент RvDataSetConnection и установим в значении его свойства DataSet компонент базы данных, созданный на первом шаге. Назначим имя этому компоненту, отличное от значения по умолчанию (например FirstReport). 3. Создадим компонент RvProject. Двойным щелчком кнопки мыши на этом компоненте вызовем визуальный дизайнер. 4. В окне дизайнера Rave Reports выберем в главном меню пункт File > New Data Object Откроется диалоговое окно Data Connections (рис. 7.21). Выберем Direct Data View и нажмем кнопку Next. Убедимся, что имя FirstReport стало выделенным в списке Active Data Connections, и нажмем кнопку Finish (рис. 7.22). (Data Cormeclfons
Рис. 7.21. Окно Data Connection
134
Зянятие 7. Отчеты в Delphi 7 IDala Connections
Рис. 7.22. Выбор активного соединения
5. Переместимся в панель Project Tree и откроем Data View Dictionary. Выберем новый вид — DataViewl. Используя панель свойств (Property Panel), расположенную ниже дерева проекта, изменим имя созданного вида DataViewl на FirstReportDV. 6. С этого момента приступаем непосредственно к созданию отчета. Выберем Tools > Report Wizards > Simple Table в главном меню для открытия мастера простой таблицы (Simple Table wizard). Удостоверимся, что имя FirstReportDV выделено, и нажмем кнопку Next для продолжения (рис. 7.23). Выберем 2 и 3 поле в списке и еще раз нажмем Next (рис. 7.24). По желанию изменим порядок полей и опять нажмем Next (рис. 7.25). По желанию зададим отчету осмысленное имя в заголовке и изменим размеры полей и снова нажимаем Next (рис. 7.26). Если нужно, изменим размеры шрифта и нажмем кнопку Generate для создания отчета. !Simple Table View you wish to use for this report
Рис. 7.23. Выбор Direct DataView
Конструктор отчетов Rave Reports
_[CUStNO
У; Company ПАсИг2 DOly DCourtry jPhone JFAX _ TTaxRale
Рис. 7.24. Выбор полей таблицы
Рис. 7.25. Перестановка полей
Рис. 7.26. Параметры оформления отчета
135
136
Зянятие 7. Отчеты в Delphi 7
7. Для предпросмотра результатов выберем File t Execute Report, чтобы открыть диалоговое окно Report Setup. Убедимся, что Preview выделено как место отправки отчета и нажмем ОК (рис. 7.27). ' Output Options
fieaori Destination
Рис. 7.27. Настройка печати отчета
Вот теперь мы воочию наблюдаем плоды своей работы (рис. 7.28) и получили представление о новейших принципах «отчетостроительства». Наш первый отчет с помощью Rave создан за минимальное число шагов.
т&ш
Simple Table Report Addrl
Company Kauai Dive Shoppe Unisco Sight Diver Cayman Divers World Unlimited Tom Sawyer Diving Centre Blue Jack Aqua Center VIP Divers Club Ocean Paradise Fantastique Aquatica Marmot Divers Club The Depth Charge Blue Sports Makai SCUBA Club
4-976 Sugarloaf Hwy POBoxZ-547 1 Neptune Lane PO Box 541 632-1 Third Frydenhoj 23-738 Paddington Lane 32 Main St. PO Box 8745 Z32999#12A-77AA. 872 Queen St. 15243 Underwater Fwy. 20312th Ave. Box 746 PO Box 8534
Рис. 7.28. Простой отчет, сгенерированный Delphi
Конструктор отчетов Quick Report
137
Конструктор отчетов Quick Report Среда Delphi 6 имеет специальную вкладку палитры компонентов, на которой располагаются компоненты для построения отчетов. Эта вкладка носит название QReport и содержит 23 компонента (рис. 7.29).
:
I - rift» ИШ ЛШ§щ
* I
Рис. 7.29. Вкладка QReport
Рассмотрим эти компоненты по порядку (слева направо) и познакомимся с их основными свойствами. Первый компонент — QuickRep — является базовым компонентом отчета. Данный компонент представляет собой форму для создания внешнего вида отчета, с его помощью можно размещать полосы, которые являются основными элементами отчета (рис. 7.30). Page Header Time Column Header Detail Summary Page Footer
Верхний колонтитул Заголовок отчета Заголовки столбцов Область данных Итог отчета Нижний колонтитул
Рис. 7.30. Элементы отчета I
В форме QuickRep можно настраивать шрифт, размеры отчета и другие параметры с помощью соответствующих свойств. Отчет связывается с набором данных Table или Query, для которого он создается, с помощью компонента DataSet. Таблица 7.1 содержит перечень основных свойств данного компонента, отображаемых в окне инспектора объектов, и их описание. Таблица 7.1. Основные свойства компонента QuickRep Название свойства
Краткое описание
Bands
Свойство типа TQuickRepBands служит для выбора полос, которые будут отображаться в отчете. Содержит шесть подчиненных свойств, отвечающих за отображение: HasColumnHeader — заголовков столбцов; HasDetail — области данных; HasPageFooter — нижнего колонтитула; HasPageHeader — верхнего колонтитула; HasSummaгу — итоговых данных; HasTitle — названия отчета. Все эти свойства имеют булевский тип. Если значение подчиненного свойства равно true, то полоса будет отображаться в отчете
Cursor
Данное свойство указывает, какой вид будет принимать указатель мыши, когда он окажется над компонентом QuickRep. По умолчанию курсор имеет вид обычной стрелки. Программист может выбрать нужный вид курсора в выпадающем списке, который отображается при нажатии на стрелку справа от значения свойства в окне инспектора объектов продолжение #
138
Зянятие 7. Отчеты в Delphi 7
Таблица 7.1 (продолжение) Название Краткое описание свойства
DataSet
Указывает имя набора данных, с которым связан отчет и данные из которого будут включаться в отчет Description Свойство может содержать описание вашего отчета или какие-либо комментарии, касающиеся отчета. Это свойство не задействуется самим компонентом QuickRep, но может использоваться вашим приложением, например, для отображения дополнительной информации Font Устанавливает параметры шрифта, выбранного для отображения текстовой информации внутри отчета. Содержит несколько вложенных свойств, которые отвечают за тип шрифта, начертание, цвет и т. д. Frame Указывает, будет ли вокруг данных отчета выводиться рамка. Содержит в свою очередь несколько свойств: Color — определяет цвет рамки; DrawBottom — определяет, нужно ли рисовать нижнюю линию (по умолчанию имеет значение false, то есть линия не рисуется); DrawLeft — определяет, нужно ли рисовать линию слева; DrawRight — определяет, нужно ли рисовать линию справа; DrawTop — определяет, нужно ли рисовать линию сверху; Style — задает стиль линий (сплошная, пунктирная и т. д.); Width — устанавливает толщину линий в пикселах Functions Это свойство позволяет программисту добавлять собственные функции, благодаря которым отчет будет рассчитывать какие-либо значения и отображать их Height Высота компонента QuickRep в форме Left Положение компонента QuickRep в форме по горизонтали Name Название компонента, по которому он будет идентифицироваться в коде приложения. По умолчанию присваиваются имена QuickRepl, QuickRep2 и т. д. Options Используется для установки дополнительных опций отчета. Содержит три подчиненных свойства булевского типа: FirstPageHeader — указывает, будет ли печататься колонтитул первой страницы отчета (по умолчанию true — то есть будет); LastPageFooter — указывает, будет ли печататься колонтитул последней страницы отчета (по умолчанию — true — будет); Compression — определяет, нужно ли делать сжатие отчета в памяти перед его генерацией (по умолчанию false — сжатие не производится) Page Применяется для хранения информации о свойствах страниц отчета. Содержит в свою очередь одиннадцать свойств: BottomMargin — минимальное чистое пространство, которое должно присутствовать внизу каждой страницы отчета; Columns — используется для печати отчетов, содержащих большое количество колонок с данными и определяет число этих колонок; ColumnSpace — определяет расстояние между колонками многоколоночного отчета; LeftMargin — указывает минимальное чистое пространство, которое должно присутствовать слева у каждой страницы отчета; Length — высота каждой страницы; Orientation — ориентация страниц: poPortrait — книжная, принята по умолчанию; poLandScape — альбомная. PaperSize — формат страницы. По умолчанию принято стандартное значение А4; RightMargin — минимальное чистое пространство, которое должно присутствовать справа у каждой страницы отчета; Ruler — указывает, будет ли отображаться разметочная сетка в процессе разработки отчета. По умолчанию имеет значение true, то есть сетка будет отображаться; TopMargin — минимальное чистое пространство, которое должно присутствовать вверху каждой страницы отчета; Width — ширина страницы PrinterSettings Определяет некоторые настройки принтера. Содержит пять свойств: Copies — количество копий каждой страницы отчета, которые должны быть напечатаны. По умолчанию имеет значение 1; Duplex — признак двусторонней печати. По умолчанию имеет значение false, то есть печать будет производиться только с одной стороны бумаги; FirstPage — номер первой печатаемой страницы отчета; LastPage — номер последней печатаемой страницы; OutputBin — способ подачи бумаги в принтер. По умолчанию имеет значение Auto — автоматическая подача бумаги
Конструктор отчетов Quick Report Название свойства
139
Краткое описание
PrintlfEmpty
Свойство регламентирует способ, каким будет генерироваться отчет, если набор данных пуст. Если значение данного свойства true (по умолчанию), то отчет будет сгенерирован и отпечатан. Если значение свойства false, то отчет не будет генерироваться ReportTitle Заголовок отчета. Данное свойство имеет тип String ShowProgress Указывает, будет ли отображаться индикатор выполнения процесса при выводе отчета на печать. По умолчанию имеет значение true, то есть шкала выполнения отображаться будет Тор Положение компонента QuickRep на форме по вертикали Units Определяет единицы измерения размеров страниц, полос, полей и других элементов отчета. Может принимать следующие значения: Inches — дюймы; ММ — миллиметры (по умолчанию); Pixels — пикселы; Native — десятые доли миллиметра; Characters — единицы, настраиваемые в соответствии с размерами символов, установленными свойством Font.Size Width Ширина компонента QuickRep на форме Zoom Степень увеличения или уменьшения размеров отчета в процессе его просмотра. По умолчанию имеет значение 100 (процентов). При установке значения свойства, например, в 200 размеры элементов отчета увеличатся в 2 раза. При установке свойства в 50 размеры элементов отчета уменьшатся также в 2 раза
Второй компонент вкладки QReport палитры компонентов Delphi 6 называется QRSubDetail. Названный компонент предназначен для создания связанных отчетов данных. Рассмотрим его основные свойства, которые перечислены в табл. 7.2. Таблица 7.2. Основные свойства компонента QRSubDetail Название свойства
Краткое описание
Bands
Определяет, будут ли у групп данных подчиненного набора отображаться нижний и верхний колонтитулы. Имеет два дочерних свойства булевского типа: HasHeader — верхний колонтитул; HasFooter — нижний колонтитул; Указывает имя набора данных, с которым связан данный компонент Используется для установки связи «главный—подчиненный». Может принимать значения, соответствующие имени отчета
DataSet Master
Следующий компонент называется QRStringsBand. Этот компонент служит для вставки в отчет дополнительных текстов. При добавлении данного компонента в отчет появляется новая полоса. Мы не будем рассматривать его свойства. Скажем лишь, что одно из них — Items — может содержать строки текста, выводимые на печать. Следующий в рассматриваемой последовательности компонент вкладки QReport называется QRBand. Он представляет собой простую полосу отчета, на которой могут размещаться другие компоненты. С помощью свойства BandType можно определить назначение добавляемой полосы в отчете. Рассмотрим возможные значения этого свойства: • rbTitle — полоса будет напечатана на первой странице отчета, сразу после верх- . него колонтитула; • rbPageHeader — полоса будет печататься на каждой странице отчета вверху (на месте верхнего колонтитула);
140
Зянятие 7. Отчеты в Delphi 7
• rbDetail — печатается для каждой записи или колонки из связанного с полосой набора данных; • rbPageFooter — будет печататься на каждой странице отчета внизу (на месте нижнего колонтитула); • rbSummary — печатается в конце отчета после всех полос перед нижним колонтитулом; • RbSubDetail — зарезервировано для использования компонентом QRSubDetail; • rbColumnHeader — печатается вверху каждой колонки на каждой странице многоколоночного отчета. В одноколоночном отчете выводится один раз после полосы типа rbPageHeader; • rbGroupFooter — полоса нижнего колонтитула для компонентов QRGroup или QRSubDetail. Печатается после завершения вывода группы данных; • rbGroupHeader — полоса верхнего колонтитула для компонентов QRGroup или QRSubDetail. Печатается перед полосой типа rbDetail для каждой группы данных; • rbOverlay — используется для обеспечения обратной совместимости с QuickReport версии 1. Не используйте это значение в других случаях; • rbChild — зарезервировано для компонента QRChildBand. Следующий компонент имеет название QRChildBand. Он позволяет вам создавать дочерние полосы, которые могут содержать внутри себя другие полосы или компоненты вкладки QReport. У этого компонента два интересных свойства: • свойство LinkBand служит для того, чтобы связать любые две полосы отчета для их совместной печати на одной странице отчета; • свойство ParentBand позволяет указать родительскую полосу для полосы QRChildBand. ПРИМЕЧАНИЕ Одним из самых простых способов определения дочерних полос отчета является установка соответствующего значения в свойстве HasChild любой полосы отчета.
Мы не будем детально рассматривать каждый компонент, расположенный на вкладке Qreport, — это потребует слишком много бумаги и типографской краски. Да и не так актуально, поскольку большинство из этих компонентов не требуются для создания простых отчетов. Расскажем лишь о назначении всех компонентов этой вкладки и рассмотрим наиболее важные из них «крупным планом». Компонент QRGroup используется для группировки данных отчета. С его помощью можно разбивать компоненты отчета на логические группы. Компонент QRLabel предназначен для размещения в отчете произвольного текста. Этот компонент является полным аналогом компонента Label, только применяется внутри отчета. Для определения текста, который будет выводиться в отчет, используется свойство Caption. Компонент QRDBText позволяет отображать текстовые данные, связанные с содержимым одного из полей набора данных, в отчете. Свойство DataSet дает возможность связать компонент с набором данных. После выбора значения этого свойства можно выбрать название поля набора данных, делается это с помощью свойства Data Field.
Конструктор отчетов Quick Report
141
Следующий компонент называется QRExpr. Он позволяет строить математические выражения и отображать результаты вычислений над полями данных и системными величинами (временем, датой и т. п.). С помощью свойства Expression можно вызвать окно построителя выражений (Expression Builder), которое служит для визуального построения математических выражений. Компонент QRSysData отвечает за отображение в отчете системных данных. С помощью его свойства Data можно выбрать, какая системная информация будет включена в отчет. Возможны следующие значения свойства Data: • qrsColumnNo — номер текущей колонки (для одноколоночного отчета всегда равен 1); • qrsDate — текущая системная дата; • qrsDateTime — текущие системные дата и время; • qrsDetailCount — число записей в наборе данных; • qrsDetailNo — номер текущей записи (или текущей записи главной таблицы); • qrsPageNumber — номер текущей страницы отчета; • qrsPageCount — количество страниц в отчете; • qrsTime — текущее системное время (это значение установлено в свойстве Data по умолчанию). СОВЕТ Будьте внимательны при установке значения qrsPageCount, так как это требует при формировании отчета двойного прохода по набору данных, что может занять много времени при подготовке отчета в случае большого количества записей.
Следующий компонент называется QRMemo. Он используется для размещения внутри отчета многострочного текста и является аналогом компонента Memo. Текст, который должен быть напечатан, необходимо занести в свойство Lines. Компонент QRExprMemo применяется для размещения в отчете текстов, содержащих математические выражения. Компонент QRRichText служит для отображения в отчете текста с возможностью форматирования. Таким образом, этот компонент является близким аналогом компонента RichEdit. Компонент QRDBRichText применяется для отображения форматированного текста, хранящегося в одном из полей набора данных. Компонент QRShape используется для добавления в отчет графических фигур. Является аналогом компонента Shape. Компонент QRImage служит для вставки в отчет графических изображений. Является аналогом компонента Image. Компонент QRDBImage позволяет вставлять в отчет значения графических полей набора данных. Компонент QRCompositeReport нужен для построения составных отчетов. Компонент QRPreview предназначен для предварительного просмотра на экране подготовленного к печати отчета.
142
Зянятие 7. Отчеты в Delphi 7
Компонент QRTextFHter используется для установки фильтра текста. Если вы поместите этот компонент на форму, то отчет будет преобразован в ASCII-текст и сохранен в файле на диске. Данный компонент — не визуальный. Компонент QRCSVFilter используется для установки символа разделителя в текстовом файле. По умолчанию в качестве разделителя фигурирует символ запятой. Данный компонент не визуальный. Компонент QRHTMLFHter применяется для установки фильтра преобразования данных отчета в формат HTML. Если вы поместите рассматриваемый компонент на форму, то отчет будет преобразован в HTML-формат и сохранен в файле на диске. Этот компонент также не визуальный. Последний компонент, QRChart применяется для печати в отчете диаграмм, составленных на основе записей набора данных. Итак, мы более или менее подробно рассказали о средствах и их компонентах, из которых строятся отчеты в среде Delphi 7. Выбор — за вами. •
Что нового мы узнали? На этом занятии мы рассмотрели следующие темы: • что такое отчеты и зачем они нужны; • основные виды отчетов; • компоненты для работы с отчетами; • создание отчетов разных видов.
:
Занятие 8 Создание простых баз данных Ваша первая локальная база данных
На этом занятии мы создадим первую базу данных, которая будет полностью функциональна. Мы постараемся использовать все уже изученное в теории на практике. В процессе создания программы мы рассмотрим основные принципы организации удобного интерфейса пользователя.
Ваша первая локальная база данных Давайте попробуем применить все полученные на ранее пройденных занятиях знания и построить локальную базу данных — напишем программу для приема объявлений в «бегущую строку», которую мы нередко наблюдаем в эфире местных телекомпаний. Сначала создадим две таблицы для нашей базы данных. Первая будет хранить сведения о заказчике, текст объявления и другую информацию. Вторая предназначена для настроек и будет содержать цены за одно слово объявления для физических и юридических лиц. Итак, структура первой таблицы изображена на рис. 8.1. Таблица OBJAV.DBF состоит из семи полей: • FIO — поле символьного типа (Char), которое может содержать максимум 40 символов. Предназначено для хранения фамилий заказчиков или названий организаций. Это поле является индексным; • TEXT — прле произвольного размера (Memo-поле). Необходимо для хранения текста объявления; • SOBST — тип собственника (Boolean). Принимает значение True для физических лиц или False для юридических; • SUMMA — числовое поле (Numeric). Содержит значение суммы, выплаченной заказчиком за объявление;
144
Занятие 8. Создание простых баз данных Sbucttne Information ctBASE ioi Window» Table: OBJAV DBF
J! Рис. 8.1. Структура таблицы OBJAV.DBF
• DATAP — поле типа дата (Date). Фиксирует дату приема объявления; • DATASTART — поле типа дата (Date). Содержит дату выхода объявления в эфир; • DATAEXP — поле типа дата (Date). Отражает срок окончания публикации объявления в эфире. Структура второй таблицы показана на рис. 8.2.
Рис. 8.2. Структура таблицы Cena.dbf
Ваша первая локальная база данных
145
Таблица OBJAV.DBF состоит из двух полей: • FCENA — числовое поле со значением стоимости одного слова объявления для физических лиц; • UCENA — числовое поле. Содержит значение цены за одно слово объявления для юридических лиц. Пусть таблицы созданы и сохранены в одном каталоге. Теперь проектируем формы. Их будет три: • главная форма — для приема объявлений; • форма настройки — для задания цены одного слова текста для физических и юридических лиц; • форма поиска — для поиска (с помощью фильтрации) записей по фамилии или по наименованию организации; Главная форма выглядит так, как показано на рис. 8.3.
вещ
f Прием объявлений Поиск Печать Вы»»
г объявления;
Рис. 8.3. Главная форма
Мы не будем подробно останавливаться на описании каждого компонента, расположенного в форме. Отметим только, что поля для ввода фамилии и суммы — это поля DBEdit. Они привязаны к таблице Tablel через компонент DataSourcel с помощью свойства DataSource. Поле для ввода текста объявления — компонент DBMemo. Он также привязан к таблице Tablel. Таблица Tablel изначально активна (для этого установите ее свойство Active в True). Также свойству TableName таблицы Tablel нужно присвоить значение, указывающее на путь к таблице OBJAV.DBF. Кроме того, для отображения отчета добавим в форму два компонента:
146
Занятие 8. Создание простых баз данных
• RvDataSetConnectionl — для установки связи будущего отчета, который мы с вами создадим далее, с таблицей Tablel. Для этого установите свойство DataSet компонента RvDataSetConnectionl в Tablel; • RvProjectl — для указания файла отчета, который мы создадим с помощью дизайнера отчетов Rave Designer позже. Пока отметим, что файл отчета будет называться MyReport.rav и именно его нужно будет указать в свойстве ProjectFile компонента RvProjectl. Приведем текст программы модуля Unitl, который сопоставлен с главной формой Forml (листинг 8.1). В него включены подробные комментарии, и он не должен вызвать затруднений при изучении. Листинг 8.1. Модуль Unitl
unit Unitl: i nterfасе uses Windows. Messages. SysUtils, Classes, Graphics. Controls. Forms. Dialogs. ComCtrls. Db. DBTables. Menus. StdCtrls. Grids. DBGrids. ExtCtrls. Buttons. DBCtrls. Mask: type TForml = class(TForm) MainMenul: TMainMenu: N1: TMenuItera;
N2: TMenuItem: DataSourcel: TDataSource: Tablel: liable: N5: TMenuItem: PageControl 1: TPageControl: TabSheetl: TTabSheet: Label 1: TLabel: Label2: TLabel: Label3: TLabel: Label4: TLabel: Label5: TLabel: Bevel 1: TBevel: Bevel 3: TBevel; BeveH: TBevel: DateTimePickerl: TDateTimePicker: Label6: TLabel: Label7: TLabel: DateTimePicker2: TDateTimePicker: Bevel 5: TBevel: Label8: TLabel: Bevel6: TBevel: BitBtnl: TBitBtn: BitBtn2: TBitBtn: BitBtnS: TBitBtn: N7: TMenuItem: N8: TMenuItem:. N10: TMenuItem; DBEditl: TDBEdit: DBRadi oGroupl: TDBRadi oGroup; Bevel2: TBevel: DBMetnol: TDBMemo: DBEdit2: TDBEdit: N4: TMenuItem:
Ваша первая локальная база данных
147
procedure BitBtn3Click(Sender: TObject): procedure N2Click(Sender: TObject): procedure FormCreate(Sender: TObject): procedure BitBtnlClick(Sender: TObject): procedure BitBtn2Click(Sender: TObject): procedure N4Click(Sender: TObject): procedure N8Click(Sender: TObject): procedure N10Click(Sender: TObject): private { Private declarations } public { Public declarations } end: var Forml: TForml; implementation
'
uses UnitZ. Unit3. Unit4: {$R *.OFM} procedure TForml.BitBtn3Click(Sender: TObject): var s:string: i.summ:integer: // Определяем переменную для текущей даты SystemT: TSystemTime: // Определяем две строковые и одну целую переменную S.Sl:String: i:Integer: begin // Считаем сумму за объявление s:=OBMemol.Li nes.Text: sumra:=l: for i:=l to length(s) do begin if s[i]=' " then summ:=summ+l: end: // Для физических и юридических лиц - разные цены if DBRadioGroupl.ItemIndex=0 then // Физическое лицо DeEdit2.text:=IntToStr(Form2.Tablel.FieldByName("FCena").AsInteger*summ); if DBRadioGroupl.ItemIndex=l then // Юридическое лицо DBEdit2.text:=IntToStr(Form2.Tablel.FieldByName("UCena").AsInteger*summ): end: procedure TForml.N2Click(Sender: TObject): begin // Показываем форму настройки в монопольном режиме Form2.ShowModal: end; procedure TForml.FormCreateCSender: TObject): begin продолжение &
148
Занятие 8. Создание простых баз данных
Листинг 8.1 (продолжение) II При запуске приложения добавляем новую пустую // запись в конец таблицы Tab! el. Append: end: procedure TForml.BitBtnlClick (Sender: TObject): // Определяем переменную для хранения системной даты var SystemTime: TSystemTime: begin // Записываем измененные данные в таблицу // Заносим дату выхода объявления в эфир Tablel. FieldByName("DataStart").AsDateTime:=DateTimePickerl. Date; // Заносим дату прекращения выхода объявления Tablel.FieldByName("DataExp").AsDateTime:=DateTimePicker2.Date; // Получаем текущую дату GetLocalTime(SystemTime) : // Заносим текущую дату > Tablel. Fie1dByName("DataP").AsDateTirne:=SystemTimeToDateTime(SystemTime): // Записываем измененные данные в таблицу Tablel .Post: // Добавляем новую запись в конец таблицы Tablel. Append: end: procedure TForml.BitBtn2C1ick( Sender: TObject): begin // Отмена сделанных изменений Tabl el. Cancel: // Добавляем новую запись в конец таблицы Tablel. Append:
end:
procedure TForml.N4C1ick( Sender: TObject);
begin
// Завершение работы приложения Forml. Close: end: procedure TForml.N8Click( Sender: TObject): begin // Вывод формы поиска в монопольном режиме Form3.ShowModal: end: procedure TForml.NlOClicktSender: TObject);
begin
// Предварительный просмотр или печать отчета // Получаем текущую дату GetLocalTime(SystemT): SI :=DateTimeToStr(SystemTimeToDateTime(SystemT) ) : // Вырезаем первые 8 символов из запрошенного значения // и получаем только дату без времени for i:=l to 8 do begin
end: // Теперь переменная S содержит текущую дату // Устанавливаем фильтр Tablel.Filter:='DATAP=' + ""• + S + "'•;
Ваша первая локальная база данных
149
// Активизируем фильтр Tablel.Filtered:=true: RvProjectl.Execute: end:
end. Внешний вид второй формы показан на рис. 8.4.
Цена т «но сяш»дя»*и»«еж« smf 5'...,А :.:>•:: '.:•>.• ::..;,,: • • «™ < - г
Рис. 8.4. Форма настройки
Эта форма называется Form2 и содержит небольшое количество компонентов. Отметим, что таблица Tablel должна в свойстве TableName содержать путь к таблице CENA.DBF. Компоненты DBEditl и DBEdit2 привязаны к полям FCENA и UCENA таблицы Tablel соответственно. Текст программы модуля UnitZ приведен в листинге 8.2. Он тоже достаточно понятен. Листинг 8.2. Модуль Unit2 unit Unit2: Interface uses Windows. Messages. Syslltils. Variants. Classes. Graphics. Controls. Forms. Dialogs. StdCtrls. ExtCtrls. Buttons. Mask. DBCtrls. DB. DBTables: type TForm2 - class(TForm) Bevel 1: TBevel: Label 1: TLabel: Bevel2: TBevel: Label2: TLabel: Label3: TLabel: BitBtnl: TBitBtn: DataSourcel: TDataSource: Tablel: TTable:
^
DBEditl: TDBEdit: DBEdit2: TDBEdit:
Label4: TLabel: procedure FormCreatetSender: TObject): private { Private declarations } public { Public declarations }
продолжение &
;
150
Занятие 8. Создание простых баз данных
Листинг 8.2 (продолжение) var Form2: TForm2;
implementation {$R *.dfm} procedure TForm2.FormCreate(Sender: TObject); begin
// Активизируем таблицу Tab1el.Active:=true: // Переходим на первую запись Tablel.First: end:
end. Форма поиска представлена на рис. 8.5. "v :;;"-sr
' ' '" .
.
'
,
..
. • ..
Рис. 8.5. Форма поиска
Форма поиска носит имя Form.3 и содержит компоненты DBGridl и DBNavigatorl. Они предназначены для отображения результатов поиска и редактирования данных. Поиск осуществляется с помощью установки фильтра и ведется по полю FIO. Текст программы модуля Unit3 приведен в листинге 8.3. Все необходимые для понимания программы комментарии в листинг включены. Листинг 8.3. Модуль Unit3 unit Unit3:
..
interface uses Windows, Messages. SysUtils. Variants. Classes, Graphics. Controls, Forms. Dialogs, ExtCtrls. DBCtrls. DB. Grids. DBGrids. DBTables. StdCtrls. Buttons: type TFormS = class(TForm)
Ваша первая локальная база данных
151
Bevel I: TBevel: Label 1: TLabel: Editl: TEdit: BitBtnl: TBItBtn: Bevel 2: TBevel: Tablel: TTable: DBGridl: TDBGrid: DataSourcel: TDataSource: BitBtn2: TBItBtn; DBNavigatorl: TDBNavigator; procedure BitBtnlClickCSender: TObject): private { Private declarations } public { Public declarations } end:
var Form3: TForm3: implementation {$R *.dfm} procedure TForm3.BitBtnlClick(Sender: TObject): begin // Активизируем набор данных Tablel.Active:=true: // Устанавливаем фильтр в соответствии с введенным • // текстом в текстовое поле Editl Tablel. Filter-'FlO-1 + — + Editl.Text + "*"":; // Включаем фильтр Tablel.Fi1tered:=true; end:
end. Теперь осталось создать файл отчета, который будет выводить информацию о поступивших за день объявлениях. Запустите дизайнер отчетов Tools > Rave Designer (Инструменты > Дизайнер отчетов). Затем выберите пункт меню File > New Report (Файл > Новый отчет) (рис. 8.6). Теперь выбираем File > New Data Object (Файл > Новый объект данных) и в открывшемся окне — Direct Data View (Непосредственный просмотр данных) (рис. 8.7). Нажимаем Next (Далее) и в следующем окне — Finish (Готово) (рис. 8.8). Если вы обратите внимание на дерево проекта, то, раскрыв в нем блок Data View Dictionary (Словарь просмотра данных), а затем DataViewl, вы увидите перечень всех полей, содержащихся в таблице Tablel (рис. 8.9). Теперь с помощью Мастера простого отчета создаем отчет. Выбираем пункт меню Tools > Report Wizards > Simple Table (Инструменты > Мастер отчетов > Простой отчет). В первом шаге Мастера простого отчета выбираем единственное представление данных DataViewl (рис. 8.10) и нажимаем кнопку Next.
152
Занятие 8. Создание простых баз данных
Рис. 8.6. Окно дизайнера отчетов
Data Lookup Security Controller Database Connection
Driver Data View Simple Security Controller
Рис. 8.7. Окно установки связи с данными
Ваша первая локальная база данных
Рис. 8.8. Окно установки связи с набором данных Q f? RavePioject [рф Report Library : ф Global Page Catalog Q • D ata View 0 ictionaty
В -®DataView1TEXT liDalaViewlSOBST -JiDataVrewlSUMMA • ®DalaView1DATAP Ш DataViewlDATASTART
Рис. 8.9. Панель дерева проекта с полями таблицы
Рис. 8.10. Первый шаг Мастера простого отчета
.
153
154
Занятие 8. Создание простых баз данных
На втором шаге мастера выбираем поля, которые необходимо поместить в наш отчет. В нашем случае это FIO, SUMM А и DAT AST ART (рис. 8.11). После выбора нажимаем Next
Setec* The Field» you
foe thi» report
НТО DTEXT
QSOBST gjSUMMA
DDATAP
DDATAEXP fjFIVEPROC DUFIVEPROC
Рис. 8.11. Второй шаг Мастера
На третьем шаге выстраиваем порядок следования (слева направо) полей, то есть порядок их расположения в отчете (рис. 8.12).
.Arrange Held* Ш The OrtJer Vou V«*h Them Printed
Рис. 8.12. Третий шаг Мастера
Следующий шаг мастера позволит нам задать имя для отчета, которое будет отображаться в начале отчета (рис. 8.13).
Ваша первая локальная база данных
155
Report Layout Options
объявлениям! irt Title
«gpck
I
i!je:st>
I
Sfncei 1 '
Рис. 8.13. Четвертый шаг Мастера
Последний шаг мастера позволяет установить шрифты для разных элементов отчета (рис. 8.14).
elect the desired fonts to use for this report Change Font |
мятым за день с The Caption Font Will Look Like This
The Printed Data Will Look Like This
Рис. 8.14. Последний шаг Мастера г-
Все, теперь нажимаем кнопку Generate (Создать) и получаем готовый отчет (рис. 8.15). Осталось исправить подписи к полям на панели DataViewlBand. Для этого выбираем нужную подпись, например FIO, и сперва щелкаем на ней мьплью, а затем в окне свойств исправляем свойство Text на нужный текст, например Фамилия/Организация (рис. 8.16).
156
Занятие 8. Создание простых баз данных
Э jTR
Отчет по принятым за день объявлениям! ' I В ШЬ
la
,
.31
Рис. 8.15. Готовый отчет
Отчет по принятым за день объявлениям! Ц'ЭМилияЮрганшация
Дата выхода в эфир
Сумма
QS^^
1
: ! 8 Daw
tiDaiai
fjame property mfxinmt ranurtyсдамапIhe 5-':rv-i. A.Z, 04and"v: S; ;i' : : <. ....
ЩЖЩ
Рис. 8.16. Исправленные подписи к полям
Что нового мы узнали?
157
Теперь сохраняем файл отчета под именем MyReport.rav с помощью пункта меню File > Save As (Файл > Сохранить как). Итак, мы создали полноценную программу, которая работает с локальной базой данных. Теперь пришло время для разговора об особенностях создания клиентсерверных приложений, работающих с базами данных.
Что нового мы узнали? На этом занятии вы: • закрепили полученные ранее знания; • создали приложение для работы с локальной базой данных
•
•
Занятие 9 Построение клиент-серверных баз данных Основы технологии «клиент-сервер» Использование хранимых процедур Язык хранимых процедур и триггеров Использование триггеров Генераторы Работа с транзакциями
На этом занятии мы дадим определение, технологии «клиент-сервер», выясним, где и для чего она применяется. Вы узнаете, что такое транзакции, триггеры и хранимые процедуры.
Основы технологии «клиент-сервер» До настоящего момента мы рассматривали только локальные базы данных, не затрагивая многопользовательского доступа. Целью данного занятия является обсуждение особенностей, присущих удаленным базам данных. Напомним, что при использовании технологии «клиент-сервер» база данных располагается на удаленном компьютере (сервере) и называется удаленной базой данных. ПРИМЕЧАНИЕ .
:
Сервером называется не только компьютер (сервер сети), но и специализированная программа, которая в нашем случае управляет базой данных.
Приложение, обеспечивающее доступ к базе данных с компьютера пользователя, называется приложением-клиентом. Взаимодействие клиента и сервера можно описать двумя фразами (рис. 9.1):
Основы технологии «клиент-сервер»
159
клиент формирует SQL-запрос серверу, на котором расположена база данных, и отправляет его по сети; сервер выполняет запрос и возвращает клиенту запрашиваемые данные. Запрос '
>
(^Обработка запроса"^)
Результат Сервер базы данных выполнения запроса Рис. 9.1. Схема взаимодействия клиента и сервера
Приложение-клиент
. Преимущества такого метода работы очевидны:
• обработка запроса происходит на сервере, клиент же получает только необходимые данные; • поскольку посылаются только необходимые данные, снижается сетевой трафик; • приложение-клиент не может напрямую обратиться к файлам, расположенным на сервере, — таким образом обеспечивается высокая степень защиты данных; • управление базой данных производит сервер, поэтому код приложения-клиента значительно уменьшается и упрощается. В основе взаимодействия клиента и сервера лежит язык SQL. Именно поэтому сервер базы данных называют еще и SQL-сервером, а базу данных — базой данных SQL. К SQL-серверам относятся: • InterBase; • Oracle; • Sybase; • DB2; • Microsoft SQL Server. Есть еще множество программ SQL-серверов. Каждая из них имеет свои особенности, которые необходимо учитывать при разработке приложения-клиента. Некоторые из них мы рассмотрим на следующем, десятом занятии. Далее в книге сервер будет называться программой SQL-сервера. Установленную на компьютере-сервере базу данных будем именовать удаленной базой данных. В изложенной простой схеме взаимодействия приложения-клиента и сервера мы еще не упомянули несколько важных функций, которые должно выполнять приложение-клиент. Вот эти функции (включая и упомянутые ранее): • осуществление соединения с сервером и отключения от него; • формулировка запроса и посылка его серверу; • прием результата выполнения запроса от сервера; • обработка полученных данных. Удаленная база данных представляет собой совокупность взаимосвязанных таблиц. Отличие ее от локальной заключается в том, что данные связанных таблиц содержатся в одном общем файле. В остальном структуры практически идентичны.
160
Глава 9. Построение клиент-серверных баз данных
Для управления базой данных сервер может задействовать следующие механизмы: • триггеры; • генераторы; • хранимые процедуры; • функции, определяемые пользователем; • транзакции; • кэшированные изменения; • события. Многие из этих механизмов зависят от установленного SQL-сервера и его языка. Далее на этом занятии мы рассмотрим некоторые из перечисленных средств на примере их использования в InterBase.
Использование хранимых процедур Хранимая процедура — это небольшая программа, которая расположена на сервере базы данных и которую можно вызвать из приложения-клиента. Хранимые процедуры позволяют ускорить работу с данными на сервере базы данных благодаря следующим преимуществам: • при использовании хранимых процедур вместо длинного текста SQL-запроса серверу отправляется короткое обращение к хранимой процедуре. Таким образом уменьшается сетевой трафик; • хранимая процедура выполняется непосредственно па сервере. В результате скорость доступа к данным не зависит от производительности машины-клиента; • хранимая процедура, в отличие от SQL-запроса, не требует предварительной проверки синтаксиса; • хранимые процедуры являются общими для всех приложений-клиентов и реализуют единые правила работы с базой данных. Для выполнения хранимой процедуры в Delphi был введен компонент TStoredProc. Рассмотрим его основные свойства. Свойство DatabaseName типа String указывает на компонент TDatabase, используемый для установления соединения с базой данных. Это свойство аналогично одноименному свойству компонентов ТТаЫе и TQuery. Свойство StoredProcName типа String определяет хранимую процедуру, которая должна вызываться. Имя хранимой процедуры выбирается в выпадающем списке с помощью инспектора объектов. ПРИМЕЧАНИЕ Если при попытке выбора хранимой процедуры соединение с базой данных отсутствует, будет выдан запрос на его установление.
После выбора хранимой процедуры можно устанавливать два других свойства. Свойство Params типа TParams определяет массив параметров компонента TStoredProc.
Язык хранимых процедур и триггеров
161
Свойство ParamBindMode типа TParamBindMode определяет, как будет установлено соответствие между параметрами компонента TStoredProc и параметрами процедуры, и может принимать одно из следующих значений: • pbByName — соответствие будет установлено по именам, то есть имена параметров компонента TStoredProc и соответствующих параметров процедуры должны совпадать. Данное значение принимается по умолчанию; • pbByNumber — соответствие будет установлено в порядке перечисления, то есть первый параметр компонента TStoredProc сопоставлен первому параметру процедуры и т. д. Выполнение выбранной хранимой процедуры осуществляется с помощью вызовов методов Prepare и ЕхесРгос: • метод Prepare осуществляет подготовку хранимой процедуры, которая заключается в связывании параметров процедуры и компонента TStoredProc в соответствии с установленным значением свойства ParamBindMode; • метод ЕхесРгос непосредственно выполняет хранимую процедуру. Листинг 9.1 иллюстрирует вызов хранимой процедуры из приложения при нажатии кнопки Buttonl. Листинг 9.1. Вызов хранимой процедуры procedure TForml.ButtonlClicktSender: TObject): begin // Определение хранимой процедуры StoredProcl.StoredProcName:='pMyProc': // Подготовка хранимой процедуры к выполнению StoredProcl.Prepare: // Выполнение хранимой процедуры StoredProcl.ЕхесРгос: end:
Язык хранимых процедур и триггеров Для написания хранимых процедур и триггеров используется специальный язык хранимых процедур. Разные серверы используют разные диалекты. Мы не будем изучать их все, а кратко рассмотрим язык хранимых процедур, использующийся сервером InterBase, который имеет много общего с языком Pascal. Язык хранимых процедур включает в себя операторы для управления ходом вычислительного процесса (ветвления, цикла), а также некоторые функциональные возможности языка SQL. Хранимая процедура создается оператором CREATE PROCEDURE <Икя процедуры> [«писок входных параметров>)] [RETURNS «писок выходных параметров*)] AS <Тело процедуры> После имени процедуры следует необязательный список входных параметров, с помощью которых из приложения в процедуру могут передаваться исходные данные. Список выходных параметров, посредством которых в приложение возвращаются результаты выполнения процедуры, указывается после слова RETURNS. Каждый параметр описывается своим именем и типом, разделенными пробелом. Между различными параметрами должны стоять запятые. б Зак. 956
162
Глава 9. Построение клиент-серверных баз данных
При использовании параметра в теле процедуры перед его именем необходимо ставить двоеточие. В текст хранимой процедуры допускается вставлять комментарии. Для вставки комментариев используются комбинации символов /* и */. Вновь созданную процедуру можно удалить или изменить. Для удаления процедуры служит оператор DROP PROCEDURE <Имя процедуры> Для изменения существующей процедуры используется оператор ALTER PROCEDURE Его список параметров идентичен списку параметров оператора CREATE PROCEDURE
Рассмотрим некоторые из основных элементов языка хранимых процедур. Заметим, что все операторы обязательно должны заканчиваться точкой с запятой (кроме составного оператора). Оператор объявления переменных имеет следующий вид: DECLARE VARIABLE <Имя переменной> <Тип переменной>: Переменные могут быть только того типа, который допускается в InterBase. Объявленные переменные являются локальными, то есть видимы исключительно внутри процедуры, в которой они были объявлены. Приведем пример объявления переменных: DECLARE VARIABLE First INTEGER: DECLARE VARIABLE Second DATE:
Оператор присваивания описывается следующим образом: <Имя переменной> = <Выражение>:
Перед знаком равенства двоеточие не ставится! Переменная и выражение должны иметь одинаковый или совместимый тип, иначе возможна ошибка. ВНИМАНИЕ Ошибка возникает не при создании хранимой процедуры, а во время ее выполнения.
Проиллюстрируем сказанное несколькими примерами: DECLARE VARIABLE First INTEGER: DECLARE VARIABLE Second VARCHAR(IO); First:=233: Second:="3io пример": Оператор ветвления имеет вид: IF (<Условие>) THEN <0ператор1> [ELSE Оператор2>];
Этот оператор аналогичен оператору ветвления, использующемуся в Delphi. Оператор цикла оформляется аналогично такому же оператору в Delphi: WHILE (<Условие>) DO <0ператор>: Оператор выбора записи похож на инструкцию SELECT языка SQL, но дополнен следующим операндом:
Использование триггеров
163
INTO :<Имя1>. _.[:<Иня№>]
Каждое имя после двоеточия указывает переменную или выходной параметр, которому должно быть присвоено значение столбцов строки, полученной в результате выполнения команды SELECT. Например: CREATE PROCEDURE pSelect RETURNS (opSum FLOAT. opSred FLOAT) AS BEGIN SELECT SUM(Zarplata). AVG(Zarplata) FROM MyTable INTO :opSum. :opSred:
END
Здесь создается хранимая процедура pSelect, в которой для сотрудников из таблицы МуТаЫе подсчитываются общая сумма заработной платы (по полю Zarplata) и среднее значение по организации. Полученные в результате выполнения процедуры значения будут присвоены выходным параметрам opSum и opSred. Входных параметров процедура не имеет. Оператор выхода из процедуры служит для досрочного выхода из процедуры и передачи управления вызывающей программе или процедуре. Оператор выхода представляет собой ключевое слово EXIT
Оператор вызова процедуры применяется для вызова из одной хранимой процедуры другой хранимой процедуры и записывается в общем виде так: EXECUTE PROCEDURE <Имя процедуры> [«писок входных паранетров>)] [RETURNING_VALUES «писок выходных параметров>)] Оператор вызывает хранимую процедуру с указанным именем и параметрами. Приведем пример вызова хранимой процедуры: CREATE PROCEDURE pCall RETURNS (opSum FLOAT) AS BEGIN EXECUTE PROCEDURE pSelect RETURNINGJ/ALUES (opSum): END Оператор посылки сообщения предназначен для уведомления о событии всех приложений-клиентов, связанных с сервером. Данный оператор имеет следующий вид: POST EVENT "<Имя события>":
Использование триггеров Триггер представляет собой процедуру, которая постоянно размещена на сервере базы данных (как и хранимая процедура) и вызывается автоматически при изменении записей базы данных. В отличие от хранимых процедур, триггеры нельзя вызывать из приложений-клиентов, а также передавать им параметры и получать от них результаты. По определению триггер похож на обработчик событий BeforeEdit, AfterEdit, BeforeDelete, AfterDelete, Beforelnsert и Afterlnsert.
164
Глава 9. Построение клиент-серверных баз данных
Триггеры в основном используются для программной реализации бизнес-правил. С помощью триггеров накладываются различные ограничения (например, на значения столбцов). Для создания триггера применяется оператор CREATE TRIGGER, который имеет следующий вид: CREATE TRIGGER <Имя триггера> FOR <Имя таблицы> [ACTIVE | INACTIVE] {BEFORE j AFTER} {UPDATE | INSERT | DELETE} [POSITION <Число>] AS <Тело триггера* Операнды ACTIVE и INACTIVE определяют, будет ли триггер активен сразу после его создания. По умолчанию он будет активен (ACTIVE), то есть при наступлении определенного события триггер будет выполняться. Неактивный триггер (INACTIVE) при наступлении определенного события выполняться не будет. Таким образом, созданный триггер можно включать или выключать. Операнды BEFORE и AFTER указывают, когда будет выполняться триггер: до наступления определенного события (BEFORE) или после (AFTER). Операнды UPDATE, INSERT и DELETE определяют тип события, при возникновении которого будет выполняться триггер. Это такие типы событий, как изменение (UPDATE), добавление (INSERT) и удаление (DELETE) записей. Для каждого события можно создать несколько триггеров, которые будут выполняться (если они активны). Порядок их выполнения определяется операндом POSITION. Триггеры будут срабатывать в порядке возрастания чисел, указанных в данном операнде. Созданный триггер можно изменить или удалить. Удаление триггера осуществляется оператором DROP TRIGGER <Имя триггера> Изменить уже существующий триггер можно с помощью оператора ALTER TRIGGER, который имеет такой же формат, что и оператор CREATE TRIGGER. Тело триггера программируется так же, как и тело хранимой процедуры.
Генераторы В таблицах InterBase отсутствует автоинкрементный тип. Для обеспечения уникальности значений ключевых столбцов совместно с триггерами используются генераторы. Генератор применяется для создания уникальных целочисленных значений. Генератор можно создать с помощью приведенного ниже оператора: CREATE GENERATOR <Имя генератора> Кроме непосредственного создания генератора, необходимо присвоить ему начальное значение. Для этого используется следующий оператор: SET GENERATOR <Имя генератора> ТО Начальное значение^
Работа с транзакциями
165
Начальное значение — это число, начиная с которого будут генерироваться уникальные значения. К созданному генератору можно обращаться с помощью функции GEN_ID (<Имя генератора>. <Шаг>) Данная функция возвращает значение, увеличенное на целочисленный шаг относительно последнего сгенерированного значения. ВНИМАНИЕ После определения начального значения и шага их изменять нельзя. В противном случае уникальность генерируемых значений может быть нарушена.
Приведем пример создания генератора: CREATE GENERATOR MyGen: SET GENERATOR MyGen TO 2: Здесь создается генератор с именем MyGen, начальное значение которого равно 2. Пример обращения к этому генератору может быть таким: GEN_ID(MyGen. 1):
Работа с транзакциями Все операции, выполняемые приложением-клиентом с данными на SQL-сервере, происходят в виде транзакций. Транзакцией называется группа из нескольких операций над данными из таблиц удаленной базы данных. Основным принципом транзакций является «.либо все, либо ничего». Если во время выполнения набора действий (транзакции) на каком-то этапе невозможно произвести очередное действие, то нужно выполнить возврат базы данных к начальному состоянию (произвести откат транзакции). Таким образом (при правильном планировании транзакций) обеспечивается целостность базы данных. Далее мы расскажем, как начинать, завершать транзакции и управлять ими с помощью SQLвыражений. А также рассмотрим вопрос об использовании транзакций в приложениях, разработанных в Delphi. Вся приведенная информация относится к InterBase. Для управления транзакциями в Delphi имеются три основные команды: • SET TRANSACTION — начинает транзакцию и определяет ее поведение; • COMMIT — сохраняет изменения, внесенные транзакцией, в базе данных и завершает транзакцию; • ROLLBACK — отменяет изменения, внесенные транзакцией, и завершает транзакцию. Рассмотрим эти команды более подробно. Команда для запуска транзакции в общем виде выглядит следующим образом: SET TRANSACTION [Access mode] [Lock Resolution] [Isolation Level] [Table Reservation] Команда содержит четыре необязательных параметра (перечисленные в квадратных скобках). Если эти параметры опустить, то получившаяся инструкция SET TRANSACTION
166
Глава 9. Построение клиент-серверных баз данных
равносильна выражению SET TRANSACTION READ WRITE WAIT ISOLATION LEVEL SNAPSHOT Перечислим параметры команды и их возможные значения. Параметр Access mode (тип доступа) определяет тип доступа к данным. Он может принимать одно из двух значений: • READ ONLY — транзакция может только читать данные и не в состоянии модифицировать их; • READ WRITE — указывает, что транзакция может читать и модифицировать данные. Это значение устанавливается по умолчанию. Параметр Isolation Level (уровень изоляции) определяет порядок взаимодействия данной транзакции с другими в рабочей базе данных. Может принимать значения: • SNAPSHOT — значение по умолчанию. Внутри транзакции будут доступны данные в том состоянии, в каком они находились на момент начала транзакции. Если по ходу дела в базе данных появились изменения, внесенные другими завершенными транзакциями, то начатая транзакция их не увидит. При попытке модифицировать такие записи будет выдано сообщение о конфликте; • SNAPSHOT TABLE STABILITY — предоставляет транзакции исключительный доступ к таблицам, которые она использует. Другие транзакции смогут только читать данные из этих таблиц; • READ COMMITTED — позволяет транзакции видеть текущее состояние базы данных. ВНИМАНИЕ Обратите особое внимание на уровень изоляции транзакции. При неправильно установленном уровне могут возникать проблемы. Эти проблемы имеют место в одном из двух случаев: транзакция пытается модифицировать запись, которая была изменена или удалена уже после ее старта; транзакция пытается модифицировать таблицу, заблокированную другой транзакцией с уровнем изоляции SNAPSHOT TABLE STABILITY.
Параметр Lock Resolution (разрешение блокировки) управляет интерпретацией событий при обнаружении конфликта блокировки. Может принимать одно из двух значений: • WAIT — значение по умолчанию. Ожидает разблокирования требуемой записи. После этого пытается продолжить работу; • NO WAIT — немедленно возвращает ошибку блокировки записи и прекращает выполнение транзакции. Параметр Table Reservation (уровень доступа к таблице) позволяет транзакции получить гарантированный доступ необходимого уровня к указанным таблицам. Существует четыре уровня доступа: • PROTECTED READ — запрещает обновление таблицы другими транзакциями, но позволяет им выбирать данные из таблицы; • PROTECTED WRITE — блокирует обновление таблицы другими транзакциями, читать данные из таблицы могут только транзакции типа SNAPSHOT или READ COMMITTED; • SHARED READ — самый либеральный уровень. Читать могут все, модифицировать — транзакции типа READ WRITE;
Что нового мы узнали?
167
• SHARED WRITE - транзакции типа SNAPSHOT или READ COMMITTED и READ WRITE могут модифицировать таблицу, остальные способны только выбирать данные. Если все действия, составляющие транзакцию, успешно выполнены или возникла ошибка, транзакция должна быть завершена, для того чтобы база данных оказалась в непротиворечивом состоянии. Для этого в Delphi есть две SQL-команды: • COMMIT — сохраняет внесенные транзакцией изменения в базу данных. Это означает, что транзакция завершена успешно; • ROLLBACK — откат транзакции. Транзакция завершается и никаких изменений в базу данных не вносится. Операция выполняется в случае возникновения ошибки при выполнении операции (например, при невозможности обновить запись). Все транзакции в Delphi можно условно разделить на явные и неявные. Явная транзакция — это транзакция, начатая и завершенная с помощью методов компонента TDataBase: StartTransaction, Commit и RollBack. После начала явной транзакции все изменения, вносимые в данные, относятся к этой транзакции. Другого способа начать явную транзакцию, кроме использования компонента TDataBase, нет. Следовательно, в рамках одного соединения нельзя начать две транзакции. ПРИМЕЧАНИЕ На самом деле такая возможность есть, но это потребует обращения к функциям API InterBase. В данной книге мы не будем останавливаться на вопросах программирования на низком уровне с использованием API.
Неявная транзакция стартует при модификации данных, если в текущий момент нет явной транзакции. Неявная транзакция возникает, например, при выполнении метода Post для компонентов наборов данных ТТаЫе и TQuery. Например, если вы отредактировали запись в TDBGrid и переходите на другую запись, то это влечет за собой выполнение метода Post, что, в свою очередь, приводит к началу неявной транзакции, обновлению данных внутри транзакции и ее завершению. Важно отметить, что неявная транзакция, начатая с помощью методов Post, Delete, Insert, Append и т. д., заканчивается автоматически.
Что нового мы узнали? На этом занятии мы разобрались, что такое: • основные понятия технологии клиент-сервер; • хранимые процедуры и зачем они нужны; • язык хранимых процедур и триггеров; • триггеры и генераторы и в каких случаях они применяются; • работа с транзакциями.
••
Занятие 10 Сервер InterBase Что нового в InterBase 6.5 Организация данных Настройка InterBase-сервера Графический интерфейс программы IBConsole Регистрация локального сервера InterBase Соединение с базой данных из приложения •
На этом занятии мы кратко рассмотрим особенности сервера InterBase 6.5, который поставляется вместе с Delphi 7 и был создан специально для этой среды разработки. Вы узнаете, как организована информация в базах данных сервера InterBase. Кроме того, мы проанализируем особенности соединения с сервером InterBase из различных программ и из вашего приложения.
Что нового в InterBase 6.5 .
В новую версию InterBase были внесены значительные изменения по сравнению с предыдущими версиями программы: • заменена графическая среда конфигурирования и поддержки InterBase-сервера IBConsole. Она заменила Server Manager и InterBase Windows ISQJL GUI, которые присутствовали в ранних версиях InterBase; • появилась возможность указания диалекта языка SQL, используемого при работе с базами данных; • добавлена возможность перевода баз данных в режим только для чтения. Используется для обеспечения большей безопасности и для работы с устройствами типа CD-R, где данные могут только считываться, но не записываться; • предложены новые элементы языка, включающие новые ключевые слова, типы данных и многое другое;
Организация данных
169
расширена функциональность средств, работающих из командной строки; расширен API InterBase; введены дополнительные средства для обеспечения соединения с сервером. В частности, драйверы ODBC, поставляемые с более ранними версиями InterBase, заменены на EasySoft — специализированный сервер InterBase, который позволяет получить доступ к нескольким серверам баз данных, использующим различные операционные системы и сетевые инфраструктуры; сделаны изменения в арифметических операциях и SQL-функциях; внесены обновления в системные таблицы сервера (RDBSFIELDS и RDB$FUNCTION_ARGUMENTS); в состав InterBase 6.5 включен IBReplicator, позволяющий копировать и синхронизировать данные в различных базах данных InterBase, имеющих схожую структуру.
Организация данных Информация всей базы данных сервера InterBase содержится в одном файле, имеющем расширение GDB. Размер этого файла может быть очень большим (несколько десятков гигабайтов). Удаленная база данных кроме таблиц включает в себя множество других элементов. Такие элементы получили название метаданных. ПРИМЕЧАНИЕ Приставка мета в данном случае обозначает над. Таким образом, метаданные — это надстройка, описывающая структуру базы данных.
К метаданным относятся: • • таблицы; • индексы; , • ограничения; • домены; • представления; • генераторы; • триггеры; • функции пользователей; • хранимые процедуры; • исключения; • BLOB-фильтры; • привилегии. В InterBase существуют ограничения на число таблиц в одной базе данных, а также на количество столбцов в одной таблице. Максимальное значение для столбцов в таблице равно 1000, а число таблиц в базе данных не должно быть больше 65 536.
Занятие 10. Сервер InterBase
170
ПРИМЕЧАНИЕ Количество допустимых столбцов в таблицах InterBase имеет меньшее значение, чем, например, в таблицах Paradox.
В таблице 10.1 приведены типы данных, поддерживаемые InterBase. Таблица 10.1. Типы данных, поддерживаемые в таблицах InterBase Тип данных
Краткое описание
SMALUNT INTEGER
Целое число. Диапазон допустимых значений: от -32 768 до 32 767 Целое число. Диапазон допустимых значений: от -2 147 483 648 до 2 147 483 647 38 Число с плавающей запятой. Диапазон допустимых значений: от 3,4хЮ' 38 до 3,4х10 . Точность — 7 знаков после запятой 308 Число с плавающей запятой. Диапазон допустимых значений: от 1,7х10308 до 1,7хЮ . Точность — 15 цифр после запятой Строка символов длиной N. Число N не должно превышать 32767 Строка символов длиной до N. Число N не должно превышать 32767 Дата. Диапазон допустимых значений: от 01.01.0100 до 11.12.5941 Двоичные данные любого типа
FLOAT DOUBLE PRECISION CHARACTER(N) VARCHAR(N) DATE BLOB
ПРИМЕЧАНИЕ В таблицах InterBase нет логического и автоинкрементного типов. Вместо автоинкрементного типа применяются генераторы и триггеры, а взамен логического типа используется CHARACTER(l).
Настройка InterBase-сервера Сервер InterBase требует отдельной установки. После инсталляции Delphi 7 будет выдан запрос на установку InterBase. Основные файлы сервера по умолчанию помещаются в папку C:\Program Files\Borland\Interbase. После установки сервер InterBase будет автоматически запущен, о чем свидетельствует значок Щ в системном лотке. По умолчанию сервер теперь будет стартовать одновременно с Windows. Завершить работу сервера можно, щелкнув правой кнопкой мыши на пиктограмме и выбрав в появившемся контекстном меню пункт Shutdown (Завершение работы). Повторный запуск сервера осуществляет исполняемый файл ibserver.exe, который находится в папке C:\Program Files\Borland\Interbase\BIN. Остальные команды контекстного меню предназначены для просмотра текущих свойств сервера (пункт Properties) и конфигурирования некоторых параметров сервера (пункт InterBase Properties). При выборе пункта InterBase Properties открывается окно свойств InterBase-сервера (рис. 10.1). Это окно позволяет изменить значения параметров: • Database Cache (pages) — количество страниц памяти, используемых сервером для кэширования данных; • Client map size (bytes) — количество памяти в байтах, которое резервируется для каждого отдельного соединения с клиентом.
Графический интерфейс программы IBConsole
171
Рис. 10.1. Окно свойств InterBase-сервера
Изменения этих параметров может производить только системный администратор сервера. Имя пользователя системного администратора — SYSDBA. Пароль администратора — masterkey.
Графический интерфейс программы IBConsole В InterBase 6.5 введен новый интегрированный графический пользовательский интерфейс под названием IBConsole. С помощью данной программы вы можете: • управлять локальными и удаленными серверами баз данных; • управлять безопасностью сервера, в том числе: Q авторизацией новых пользователей; а назначением и сменой паролей пользователей: О удаленной авторизацией пользователей; • управлять сертификатами сервера; • управлять файлами баз данных, в том числе создавать новые базы данных и устанавливать свойства баз данных; • сохранять и восстанавливать базы данных; • обеспечивать поддержку баз данных: Q проверять целостность информации; Q восстанавливать поврежденные таблицы; Q развертывать базы данных; • завершать работу баз данных и перезагружать их;
172
Занятие 10. Сервер InterBase
выполнять SQL-запросы в интерактивном режиме; просматривать метаданные базы данных в формате SQL script.
Л Рис. 10.2. Главное окно программы IBConsole при первом запуске
Главное окно программы IBConsole (рис. 10.2) состоит из следующих элементов: • строка меню; • панель инструментов, расположенная под строкой меню; • строка состояния, расположенная внизу окна и показывающая имена текущих выбранного сервера и базы данных, а также пользователей, подключенных к серверу; • область, отображающая зарегистрированные серверы и базы данных (слева), а также их подкатегории в стиле Проводника Windows; • область, отображающая данные различного характера (справа).
Регистрация локального сервера InterBase Для регистрации локального сервера InterBase можно воспользоваться программой IBConsole. Запустите ее и выберите в меню программы пункт Server > Register (Сервер > Зарегистрировать). После этого появится диалоговое окно регистрации сервера. Заполните его, как показано на рис. 10.3. Таким образом, мы выбрали локальный сервер, назвали его MyServer и соединились с сервером под именем и с паролем администратора. Напомним, что пароль администратора — masterkey. После регистрации сервера в левой области окна отобразится информация о составе вновь созданного сервера Теперь можно регистрировать базу данных сервера. Для этого нужно выбрать пункт меню Database > Register (База данных > Зарегистрировать). При этом откроется диалоговое окно регистрации базы данных (рис. 10.4).
I Регистрация локального сервера InterBase мд.гелр.нжгегдж
iMySetver
Рис. 10.3. Окно регистрации сервера
'f R«gister Database ami Connect
:
т
'•
•:"'•" -
Рис. 10.4. Окно регистрации базы данных
173
174
Занятие 10. Сервер InterBase
Мы уже заполнили в этом окне некоторые поля, Поле File (Файл) должно содержать путь к файлу базы данных (имеющей расширение GDB). Поле Alias Name (Псевдоним) заполнится автоматически после заполнения поля File. В поля User Name (Имя пользователя) и Password (Пароль) мы ввели имя пользователя и пароль администратора сервера соответственно. После нажатия кнопки ОК мы подключимся к демонстрационной базе данных isc4.gdb, поставляемой вместе с InterBase (рис. 10.5). i .
••
Oiiconnoct Databa» S(*tehci
Disconnect Irom the cunent database Ditplay dalabCM statistics
Shutdown
Shutdown the databm
Sweep
Part am a database tweep
Tramaction Recovwy
Recover bnbo bantactioni
View Metadata
V«« D*tab«» Metadata
D«tabate Rnlwt
Retiart « detabaw
DIOD Databate
Diop the curtnt databata
Database Backiv
Backm an inteiBstt database
Coonecied Users
View * fet of utatt curanlV connected to !>>
Reitwe Oatabata
Restate an IrtwBeie databasa
Рис. 10.5. Окно IBConsole после подключения к базе данных
Соединение с базой данных из приложения Перед соединением с базой данных из собственного приложения необходимо создать псевдоним базы данных. Воспользуемся для этого программой BDE Administrator, которую мы рассматривали ранее. Запустим BDE Administrator и создадим новый объект с помощью команды Object > New (Объект > Создать). Назовем его PROBA и установим тип базы данных INTERBASE. После этого зададим путь к серверу базы данных в свойстве SERVER NAME и имя пользователя в свойстве USER NAME, как показано на рис. 10.6. Теперь можно приступать к созданию приложения, работающего с базой данных с помощью сервера InterBase. Для этого в форме приложения расположим компоненты Databasel, Queryl, DataSourcel и DBGridl (рис. 10.7).
•
175
Соединение с базой данных из приложения • ••;
Тя» 3В 4 OBOEMOS
.4; ;J Оешлоо т: И IBLocal
«в—
41 ? E«»««««ViiuJIF Ш "в Файлы ЛАЗЕ
BATCH COUNT BLOB SIZE BLOBS TO CACHE COMMIT RETAIN .FALSE IFALSE ENABLE BCD ENABLE SCHEMA CACHE'" IFAISE LANGORIVER PdovAHS! CyJl!!.' MAX ROWS OPENMODE ROLE NAME SCHEMA CACHE DIR SCHEMA CACHE SIZE SCHEMA CACHE ТIMF SERVER КАМЕ С \PioQram SHAflEDAUTOCOMMIT SOLPASSTHRU MODE SOLORYMODE USER NAME WAIT ON LOCKS
Рис. 10.6. Параметры псевдонима базы данных
Рис. 10.7. Заготовка формы приложения
ВНИМАНИЕ В качестве набора данных может использоваться только компонент Query или подобный ему. Использование компонента типа Table в клиент-серверных приложениях не допускается.
Осталось установить свойства перечисленных компонентов. Эти свойства представлены в табл. 10.2.
176
Занятие 10. Сервер InterBase
Таблица 10.2. Свойства компонентов формы приложения Компонент
Свойство
Значение
Database! Database! Query! Query! DataSourcel DBG rid!
AliasName DatabaseName DatabaseName
PROBA isc4.gdb isc4.gdb SELECT * FROM USERS Queryl DataSourcel
SQL DataSet DataSource
Итак, мы указали в компоненте Database! псевдоним и название базы данных. В компоненте Queryl мы определяем имя базы данных и формируем запрос на выборку всех данных из всех полей таблицы USERS (эта таблица хранит информацию о каждом из пользователей, зарегистрированных на сервере). Далее обычным способом устанавливаем связь между компонентами Queryl и DBGridl с помощью компонента DataSourcel. Осталось активировать запрос в компоненте Queryl. Для этого установим его свойство Active в true, после чего будет выдан запрос на ввод имени пользователя и пароля (рис. 10.8). I Database Login Diabase: 1'SDBii
Рис. 10.8. Ввод имени пользователя и пароля
Указываем пароль администратора и можем запускать приложение. Результат наших трудов показан на рис. 10.9.
Рис. 10.9. Результат выполнения программы
Что нового мы узнали?
177
Что нового мы узнали? На этом занятии вы узнали: • какие новшества введены в версию InterBase 6.5; т как организованы базы данных сервера InterBase; • как осуществлять простейшую настройку сервера InterBase; • как работать с программой IBConsole; • как осуществлять соединение с локальной базой данных сервера InterBase с помощью программы IBConsole и из вашего собственного приложения.
Занятие 11 Основы языка SQL Основные сведения о языке SQL Функции языка SQL Операторы определения данных Операторы манипулирования данными Навигатор SQL Explorer Отладчик SQL Monitor Конструктор запросов SQL Builder
На этом занятии вам предстоит знакомство с языком SQL. Вы узнаете основные операторы и функции языка, а в конце занятия прочитаете обзорную характеристику программ SQL Explorer, SQL Builder и SQL Monitor, входящих в стандартную поставку Delphi.
Основные сведения о языке SQL Язык структурированных запросов SQL (Structured Query Language) существует в нескольких стандартах. Наиболее распространенными являются стандарты SQL-89 и SQL-92. Последний также называют стандартом ANSI. Из-за частичной несовместимости стандартов языка существует множество его диалектов. Мы рассмотрим только основные команды SQL для простых операций с таблицами баз данных. В языке SQL нет многих типов команд, которые присущи большинству языков программирования. Так, в нем отсутствуют операторы цикла, перехода и т. д. SQL-запрос — это команда на языке SQL. Язык SQL по своей сути ориентирован на доступ к данным, и его обычно включают в состав различных средств разработки. Безусловно, разработчики Delphi не могли остаться в стороне. Многие компоненты Delphi для работы с базами данных поддерживают язык SQL.
Основные сведения о языке SQL
179
Все SQL-запросы можно условно разделить на два вида: • статический SQL-запрос — включается в код приложения во время его разработки и не изменяется во время выполнения. Единственным способом поправить что-либо в запросе такого типа является включение в SQL-запрос параметров и их дальнейшая модификация в ходе работы приложения; • динамический SQL-запрос — создается и изменяется в процессе выполнения приложения. Такие запросы являются самыми гибкими и могут более адекватно отвечать конкретным желаниям пользователя. Все операторы и команды языка SQL можно разделить на три группы. Рассмотрим эти группы, а также операторы, входящие в каждую из групп. Операторы определения данных предназначены для создания, удаления и изменения структуры данных. Основные из них перечислены в табл. 11.1. Таблица 11.1. Основные операторы определения данных Оператор
Описание
CREATE TABLE
Предназначен для создания таблицы базы данных
ALTER TABLE
Изменяет структуру таблицы
DROP TABLE CREATE INDEX
Удаляет таблицу Создает индекс
DROP INDEX
Удаляет индекс
CREATE VIEW DROP VIEW
Создает представление Удаляет представление
Операторы управления данными служат для управления привилегиями доступа к данным. Основные операторы этой группы представлены в табл. 11.2. Таблица 11.2. Основные операторы управления данными Оператор
Описание
GRAND REVOKE
Назначает привилегии пользователям Отменяет привилегии пользователей
Операторы манипулирования данными осуществляют работу с записями таблиц. Наиболее часто используемые операторы кратко описаны в табл. 11.3. Таблица 11.3. Основные операторы манипулирования данными Оператор
Описание
SELECT UPDATE INSERT DELETE
Производит выборку записей по определенному формату Предназначен для изменения и обновления записей Вставляет новые записи в таблицу Удаляет записи из таблицы
Применение приведенных в табл. 11.1-11.3 операторов мы рассмотрим далее на этом занятии. ВНИМАНИЕ Обратите внимание на тот факт, что проверка синтаксиса запроса происходит только во время работы программы. Компилятор Delphi не обрабатывает SQL-запросы на этапе разработки приложения.
180
Занятие 11. Основы языка SQL
Результатом выполнения запроса обычно является набор данных, который называется результирующим набором данных. Осталось отметить, что регистр букв команд SQL-запросов не влияет на их выполнение. Мы воспользуемся этим удобством и для наглядности будем применять прописные буквы для операторов языка SQL. По соглашениям, принятым в SQL, точка с запятой также не требуется в конце каждой команды. Элементы списков, такие как имена таблиц и полей, обязательно разделяются запятыми. Имена таблиц и полей заключаются в апострофы или кавычки, например, 'Number', "Table I". В случае, если имя не содержит пробелов и других специальных символов, его можно не заключать в кавычки.
Функции языка SQL В языке SQL, кроме операторов, имеется несколько функций, основные из которых будут рассмотрены далее. Статистические функции — функции, предназначенные для статистической обработки данных. Наиболее часто используемые статистические функции перечислены в табл. 11.4. Таблица 11.4. Основные статистические функции Функция
Описание
AVG() COUNT() COUNT(*) МАХ() MIN() SUM()
Получение среднего значения Определяет количество значений Определяет количество ненулевых значений Максимальное значение Минимальное значение Сумма значений
Строковые функции — функции, предоставленные для работы со строковыми значениями. Наиболее часто задействуемые из них представлены в табл. 11.5. Таблица 11.5. Основные строковые функции Функция Описание 11 СА5Т(<Выражение> AS <Тип>) LOWER(S) SUBSTRING(S FROM N1 ТО N2) TRIM(S) UPPER(S)
Слияние (конкатенация) двух строк Приводит выражение <Выражение> к типу <Тип> Преобразует символы строки 5 в символы нижнего регистра Выделяет из строки S подстроку, начиная с символа N1 и заканчивая символом N2 Удаляет в начале и конце строки S лишние пробелы Преобразует символы строки S в символы верхнего регистра
Операторы определения данных Оператор CREATE TABLE служит для создания новой таблицы базы данных и имеет следующий формат:
Операторы определения данных
181
CREATE TABLE <Имя таблицы> (<Имя поля> <Тип данных>. <Имя поля> <Тип данных>):
Обязательное условие — указание хотя бы одного имени поля и его типа данных. Приведем пример объявления простой таблицы: CREATE TABLE MyTable (Number INTEGER. Name CHAR(20). Surname CHAR(20)): Здесь в каталоге текущей базы данных будет создана новая таблица МуТаЫе, состоящая из полей Number, Name и Surname. Первое поле имеет целочисленный тип (INTEGER), остальные поля — символьного типа и ограничены 20 символами. Если при выполнении этого запроса выяснится, что таблица с таким именем уже существует, будет сгенерирована исключительная ситуация. Оператор DROP TABLE <Имя таблицы> служит для удаления имеющейся таблицы. Если таблицы с указанным именем не существует, будет сгенерирована исключительная ситуация. Пример: DROP TABLE MyTable:
При выполнении этой операции будут удалены все файлы, относящиеся к таблице МуТаЫе. Оператор ALTER TABLE предназначен для добавления или удаления полей существующей таблицы базы данных. Во время выполнения этого оператора никакие другие приложения не должны обращаться к таблице. Оператор записывается следующим образом: ALTER TABLE <Имя таблицы> ADD <Имя поля> <Тип данных>. DROP <Имя поля>. ADD <Имя поля> <Тип данных>. DROP <Имя поля>: При этом операнд ADD добавляет к таблице новое поле, а операнд DROP удаляет из таблицы существующее поле. Операнды могут располагаться внутри оператора ALTER TABLE произвольно. Пример: ALTER TABLE МуТаЫе ADD Telefon'INTEGER. ADD Address CHAR(50). DROP Number; , . При выполнении кода примера в таблицу МуТаЫе добавятся два поля: Telefon и Address, целочисленного и символьного типа соответственно. Кроме того, будет удалено поле Number.
182
Занятие 11. Основы языка SQL
Операторы манипулирования данными «Краеугольным» оператором манипулирования данными является оператор SELECT. Этот оператор используется для отбора данных, удовлетворяющих сложным условиям. Оператор SELECT имеет вид: SELECT [DISTINCT] <Список полей> или * FROM <Список таблиц> [WHERE <Условия выбора записей>] [ORDER BY <Список полей для сортировки>] [GROUP BY <Список полей для группировка] [HAVING <Условия группировки полей>] [UNION Сложенный оператор SELECT>] Параметр DISTINCT определяет, будут ли включаться в результирующий набор данных повторяющиеся записи. Если он присутствует в операторе SELECT, то повторяющиеся записи будут исключены из набора данных. Если в список полей входят поля нескольких таблиц, для указания принадлежности поля к той или иной таблице используют составной оператор, включающий имя таблицы и, через точку, имя поля: <Имя таблицы>.<Имя поля>
Операнд WHERE определяет критерии, которым должны удовлетворять записи в результирующем наборе данных. Операнд GROUP BY позволяет группировать записи. Иногда бывает необходимо выполнить какие-либо действия над группой записей. Операнд HAVING используется вместе с GROUP BY и позволяет выбирать записи внутри групп. Операнд ORDER BY содержит список полей, определяющих порядок сортировки записей результирующего набора данных. По умолчанию сортировка выполняется в порядке возрастания значений. Для сортировки в порядке убывания значений необходимо после имени поля поставить параметр DESC. Приведем несколько примеров выбора записей с использованием оператора SELECT. Пример 1. Выбор всех полей таблицы SELECT * FROM MyTable
В результате выполнения этого запроса будут выбраны все поля и записи из таблицы МуТаЫе. Символ * как раз и означает, что нас интересует таблица в целом. Вместо него можно просто перечислить через запятую все имена полей таблицы. Пример 2. Выбор данных из трех полей таблицы SELECY Number. Surname. Telefon FROM MyTable
Будут возвращены все значения из полей Number, Surname и Telefon таблицы МуТаЫе. Пример 3. Выбор уникальных значений SELECT DISTINCT Surname FROM МуТаЫе
Операторы манипулирования данными
183
В ответ на запрос мы получим набор данных, который содержит все фамилии (Surname), входящие в таблицу МуТаЫе. В этом наборе данных одна и та же фамилия не появится дважды (по умолчанию), то есть будут исключены все однофамильцы. Пример 4. Выбор данных из двух таблиц SELECT * FROM MyTablel, My Table? Выбирает все данные из таблиц MyTablel и МуТаЫе2. Первыми будут располагаться поля таблицы MyTablel, а затем — поля второй таблицы. Пример 5. Выбор записей по значениям числового поля SELECT Name. Surname FROM MyTable WHERE (Number>l) and (Number<100): В результирующий набор данных войдут имена и фамилии первых ста человек, занесенных в таблицу МуТаЫе. Пример 6. Выбор записей по значению символьного поля SELECT Name FROM МуТаЫе WHERE Surname-'Иванов': Результатом будет столбец имен, учтенных нами, с фамилией Иванов. Пример 7. Проверка частичного совпадения по символьному полю SELECT Name. Surname FROM MyTable WHERE Surname LIKE 'И 1 : Будут выбраны имена и фамилии людей, занесенных в таблицу МуТаЫе, фамилии которых начинаются с буквы И. В выражениях операции LIKE можно использовать подстановочные символы, а именно: % — замещает любое количество символов, в том числе и нулевое; _ — замещает один символ. Пример 8. Проверка частичного совпадения по шаблону SELECT Name. Surname FROM MyTable WHERE Surname LIKE Т || 'ов' || '%': Будут выбраны имена и фамилии людей, в фамилиях которых найдутся символьные сочетания ов. Операнд ORDER BY служит для упорядочения (сортировки) значений полей. Пример 9. Сортировка записей по полю SELECT * FROM МуТаЫе ORDER BY Name Набор данных будет упорядочен в порядке возрастания значений по полю Name. Пример 10. Сортировка по двум полям
SELECT * FROM MyTable ORDER BY Name. Surname DESC
184
Занятие 11. Основы языка SQL
Будет произведена сортировка данных сначала по полю Name в порядке возрастания, затем — по полю Surname в порядке убывания. Оператор UPDATE служит для изменения значений полей в группе записей и имеет следующий формат: UPDATE <Имя таблицы> SET <Имя поля> = <Выражение>. SET <Иня поля^ = <Выражение> [WHERE <Условия выбора>]:
Во всех записях, которые удовлетворяют условию отбора, будут изменяться значения полей. Пример 11. Изменение значений поля UPDATE MyTable SET Oklad = Oklad + 1000: WHERE Oklad < 1000:
Изменит сумму оклада (Oklad) сотрудника, если оклад составляет менее 1000 рублей. Заработная плата такого сотрудника в результате удвоится, Оператор INSERT служит для вставки записей в таблицу и записывается следующим образом: 'INSERT INTO <Иия таблицы> (Описок попей>) VALUES «писок значений>);
Это означает, что к таблице <Имя таблицы> будет добавлена одна запись. Пример 12. Добавление записи в таблицу
INSERT INTO My Table (Name. Surname. Telefon) VALUES ('Иван 1 . 'Иванов'. 2341234):
В таблицу MyTable будет вставлена новая запись, содержащая имя и фамилию нового сотрудника, а также номер его телефона. Оператор DELETE служит для удаления записей из таблицы и имеет следующий формат: DELETE FROM <Иня таблицы> [WHERE <Условия выбора^] : В результате его действия из таблицы будут удалены все записи, удовлетворяющие критерию отсева. Пример 13. Удаление записей из таблицы DELETE FROM MyTable
WHERE Surname = 'Иванов':
Удаляет из таблицы MyTable все записи, содержащие фамилию Иванов. На этом мы закончим обзор основных операторов и функций языка SQL Дополнительную информацию вы можете почерпнуть из специальной литературы, посвященной данному языку.
Навигатор SQL Explorer
185
Навигатор SQL Explorer SQL Explorer похож на Проводник (Explorer) среды Windows. Средствами SQL Explorer можно просматривать или редактировать реляционные базы данных. Ранние версии данной программы носили такие названия, как Explorer и Database Explorer. Новая среда разработки Delphi 7 поставляется с SQL Explorer версии 4.00. Запустить эту программу можно либо из главного меню Delphi: Database > Explore (База данных > Проводник), либо с помощью главного меню Windows: Пуск > Программы > Borland Delphi 7 > SQL Explorer. Но можно это сделать и напрямую. Для этого нужно запустить файл dbexplor.exe, который находится в подкаталоге BIN главного каталога Delphi 7. Интерфейс SQL Explorer похож на интерфейс BDE Administrator (рис. 11.1). |T>SQL Exploier
,,. , offfeMs Databases &:i» DBDEMOS : В -|Ш1 Tables Ш--ЩВ animals dbf ' Й- ШЯ biolife.db ; Ш Bffl clients.dbf Й- ШВ counliy.db
Name ALPHA ED Capital ALPHA Ш Continent ALPHA HlAiea NUMBER ED Population NUMBER
24 24 24
24
24 24 8 8
; т Ш I ф-gj Validity Checks . SI Щ Refeiential Constraints • Ш Ш Security Specs ! Я Й Fami^r Members Ш ПШ custoly-db ЕЙ Щ] customer db Ш ВЩ employee db ЕЙ-Н events, db ШШ holdings, dbf E& |H1 industiy.dbl fS И items, db Й- H (nastet.dbl
•
Рис. 11.1. Главное окно SQL Explorer
Если в левой части окна программы выбрать требуемый объект (например, таблицу), то в правой части окна можно будет просмотреть или отредактировать свойства этого объекта. На рисучке 11.1 показаны свойства полей таблицы country.db, выбранной в качестве де\. нстрационного примера. С помощью SQL Explorer вы можете: • работать с псевдонимами; • просматривать структуру баз данных или таблиц; • просматривать и редактировать записи, содержащиеся в таблицах;
186
Занятие 11. Основы языка SQL
• создавать, редактировать и выполнять SQL-запросы; • оперировать со словарями данных. Работа с псевдонимами ничем не отличается от таковой в программе ВОЕ Administrator, которую мы рассмотрели ранее. Для просмотра структуры базы данных или таблицы нужно в левой части окна SQL Explorer выбрать интересующую базу данных или таблицу. После выбора таблицы имеется возможность просматривать ее объекты. К объектам таблицы относятся: • поля (Fields); • индексы (Indices); • ограничения значений полей (Validity Checks); • ограничения ссылочной целостности (Referential Constraints); • права доступа (Security Specs); • файлы, входящие в состав таблицы (Family Members). Если для базы данных или таблицы установлен режим ограничения доступа, при попытке открыть ее будет запрошено имя пользователя и его пароль. Для просмотра и редактирования содержимого таблицы следует выделить название таблицы и в правой области окна SQL Explorer выбрать вкладку Data (Данные), как показано на рис. 11.2. .г**4.
,*'эп1...
• • ; •,
В «а Database» Ь !f( DBDEMOS Tables ft; ПИ mmab.dbl ЕЕ В ЬюМе.* К -Ш dents.*!
йивВ
Indtm VaMji Checks
И И Referential Constiainl Security Specs Family Members $!• Gffl cutfdy.db ffi Ш customs db ^ ПЯ empJoyeedb ffi -ЛЯ eventidb ущ holdings. ОЫ Ё П9 nduitiy.dbt ff ПЗ item» db ПЯ mastei dbf Ш М>ТаЫе DB Ш ИВ nextcujldb ffl -ПИ nexWemdb tt- Ш nextoid db
Kingston Mexico Ckji Managua Asuncion Peru United S tales of America Uruguay enezuela
Ш Л oitb! * db
Рис. 11.2. Просмотр и редактирование записей таблицы
Записи таблицы отображаются в сетке, аналогичной компоненту DBGrid. Для перемещения по записям и внесения в них изменений можно воспользоваться аналогом компонента DBNavigator, расположенным в верхней правой области окна SQL Explorer.
Навигатор SQL Explorer
187
Кнопка Explore BLOBs (Просмотр полей BLOB), находящаяся на панели инструментов и имеющая вид конверта с картинкой, позволяет просматривать BLOB-поля. При этом содержимое каждого BLOB-поля будет выводиться в отдельном окне. Для редактирования и запуска SQL-запросов применяется текстовый редактор, расположенный на вкладке Enter SQL (Ввод SQL-запроса). Выполнение запроса происходит при нажатии кнопки Execute Query (Выполнение запроса), обозначенной желтой молнией. Результат будет отображен в области окна непосредственно под текстовым редактором. В программе допускается работать одновременно с несколькими запросами. Переключение между запросами осуществляется с помощью кнопок с изображением синих треугольников — Next Query (Следующий запрос) и Previous Query (Предыдущий запрос). Результат выполнения демонстрационного запроса показан на рис. 11.3. : л
Qj Databases В 18 OBDEMOS В ИT*les № fgg animals dW ffi И bralfedb [Я ПЯ cterts.dbf
:
: ; :
{£ -ЛД Fields ж §Д Indices ffi §3 Vainly Checks ffiffl Referential Conslrartj : §J3 Security Specs ffi ИД Family Members ft; -GUI cusloly db Щ ШЦ custom» db К ES! employee db Ш" И events db Гй И holdngs dbf и) ® industiy.dbf I+: ШЯ items db ffi flffl master dbf g ШП W vT able 08 ffi -ЩЯ nextcusldb li [Щ] nextitemdb Ш Ш nextorddb It; H ordeis db Ш ЕШЗ p»ts db
SouthAmenca South America iSouth America North Ameiica South America South America North America South America North America South Ameiica , North Атегюа North America Nofth America South America South America North America •South America (
• : ; ' I
Ottawa Santiago Bagola Havana Quito
ElSalvadra Guyana Jameice Mrait» Nicaagua Pataguay Peru Unrted Stales of Arnica Uruguay
SanSalvada Seoigetomn Kingston Мюосо ply Managua Asuncion Lrma Washington Montevideo
х
Рис. 11.3. Результат выполнения запроса
Для работы со словарями данных нужно перейти на вкладку Dictionary (Словарь) в левой части окна SQL Explorer. При этом структура выбранного словаря данных будет отображена в виде иерархического дерева. Если словарей данных нет, то программа выдаст соответствующее сообщение. Со словарем данных можно выполнять следующие операции (рис. 11.4): • выбор нового словаря (Select); • регистрация словаря в хранилище объектов (Register); • исключение словаря из хранилища объектов (Unregister); • создание нового словаря (New);
188
Занятие 11. Основы языка SQL
удаление выбранного словаря (Delete); вставка в словарь данных из базы данных (Import from Database); вставка в словарь данных из файла (Import from File); экспортирование данных из словаря в файл (Export to File).
Рис. 11.4. Допустимые операции над словарями данных
Отладчик SQL Monitor Программа SQL Monitor позволяет отслеживать выполнение SQL-запросов к удаленным базам данных. Запуск программы осуществляется с помощью команды главного меню Delphi Database > SQL Monitor (База данных > SQL Monitor). Кроме того, программу можно запустить из главного меню Windows: Пуск > Программы > Borland Delphi 7 > SQL Monitor. Ну и, конечно, с помощью простого запуска файла sqlmon.exe, который расположен в папке BIN главного каталога Delphi 7. Для локальных баз данных эта программа не применима, так как она отслеживает операции доступа к удаленным базам данных с помощью драйверов SQL Links, а в локальных базах данных работают другие, локальные драйверы. Кроме того, SQL Monitor не может быть использован, если в вашем приложении имеются компоненты с закладки InterBase, так как в этом случае драйверы SQL Links не задействованы и осуществляется прямой доступ к базе данных через BDE. После запуска программа автоматически следит за порядком выполнения SQLзапросов и ведет журнал работы с удаленной базой данных. Запросы отслеживаются для указанного клиента. При отладке Delphi-приложения клиентом становится Delphi 7. Строки журнала выводятся в верхней части окна программы. В нижней области окна отображается строка состояния (рис. 11.5).
Отладчик SQL Monitor
189
Рис. 11.5. Окно SQL Monitor
Если вы хотите сохранить журнал работы с удаленной базой данных в текстовом файле, можно воспользоваться командой File > Save Log (Файл > Сохранить журнал) и указать имя файла. Очистка журнала выполняется с помощью команды Edit > Clear Log (Файл > Очистить журнал). Параметры программы SQL Monitor устанавливаются в окне Trace Options (Параметры трассировки), как показано на рис. 11.6.
.
Рис. 11.6. Окно Trace Options
190
Занятие 11. Основы языка SQL
Это окно вызывается через пункт меню Options > Trace Options (Параметры > Параметры трассировки) или комбинацией клавиш Ctrl+0. Параметры, доступные в окне через элементы управления (табл. 11.6), задают степень детализации информации, сохраняемой в журнале. Таблица 11.6. Параметры программы SQL Monitor Параметр
Русское название
Prepared Query Statements
Подготовленные запросы, передаваемые на сервер Выполненные на сервере запросы Выполненные запросы Данные, передаваемые на сервер в качеВходные параметры стве параметров запросов Данные, возвращенные сервером Возвращенные данные Операции ALLOCATE, PREPARE, EXECUTE Утверждение операций и FETCH Соединение-отсоединение Операции соединения с сервером и отключения от него Операции управления транзакциями Транзакции Операции с BLOB-данными Ввод-вывод BLOB Другие операции Другие Ошибки сервера Сообщения об ошибках, возвращаемые сервером Вызовы сервера Вызовы API-функций сервера
Executed Query Statements Input Parameters Fetched Data Statement Operations Connect/Disconnect Transactions BLOB I/O Miscellaneous Vendor Errors Vendor Calls
Описание
Готовые запросы
По умолчанию все перечисленные параметры включены. Для облегчения чтения журнала рекомендуется отключать некоторые из них. Например, достаточно оставить только первый, второй и седьмой параметры (готовые и выполненные запросы, а также транзакции).
Конструктор запросов SQL Builder Программа SQL Builder предназначена для упрощения процесса создания SQLзапросов. С помощью этого средства вы сможете достаточно легко конструировать запросы и сохранять их в виде текстового файла с расширением SQL. SQL Builder вызывается с помощью контекстного меню компонента Query. Расположите в форме компонент Query с закладки ВОЕ палитры компонентов. Щелкните на компоненте правой кнопкой мыши и выберите пункт SQL Builder. Перед вами появится главное окно SQL Builder (рис. 11.7). Окно программы разделено на две части: в верхней находятся таблицы, необходимые для построения запроса, внизу расположена область с настройками. На рисунке 11.7 показан пример отбора записей из таблицы Animals базы данных DBDEMOS. По нему будут отобраны записи, значения поля WEIGHT у которых больше десяти. Для отработки запроса нажмите клавишу F9 или выполните команду меню Query > Run Query (Запрос > Выполнить запрос). Результат выполнения запроса можно увидеть на рис. 11.8.
-жившие
Конструктор запросов SQL Builder
191
Рис. 11.7. Окно программы SQL Builder Ш Uueiy iMMtl
20: Screen Savers 20: Screen Saver»
[(BLOB)
20 Screen Severs 20:Screen Savers 20: Screen Savers 35: Mice and AM 35: Africa aid Ana
:|BLOB ;(BLOB] . ilBLOB)
Davis
Jennifer
1023495 :Ja
Jones
Aithur
2094056:
'Parker
Debra
1209395'
Sawyer
Dave
3094095
While Davis
Cindy Jennifer
Jones
Altar
1024034! 1023495
''
"[(BLOB)"" :(BLOB)
Parker
Debra
1209395:
35; Africa and Asia
Sawyer
JDave"'
3094095;;
35 Africa and Asia
IlBLOB)
White
35! Africa and Asia
Cindy
1024034 :
Рис. 11.8. Результат выполнения запроса
Кратко опишем закладки в последовательности их расположения в нижней части окна SQL Builder: • закладка Criteria (Условия) предназначена для задания условий отбора записей. Каждое условие вводится в отдельной строке и состоит из двух названий полей или значений, между которыми находится знак сравнения. Имена полей можно выбирать из выпадающего списка либо перетаскивать из таблиц в верхней части окна. Если условие содержит ошибку, то будет выдано соответствующее сообщение. Удалить строку условия можно с помощью пункта Delete Row (Удалить ряд) контекстного меню; • закладка Selection (Выбор) позволяет изменять названия заголовков столбцов при отображении результирующего набора данных. Кроме того, она предоставляет возможность включения в запрос статистических функций;
Занятие 11. Основы языка SQL
192
закладка Grouping (Группирование) предназначена для группирования записей; закладка Group Criteria (Критерии группирования) содержит условия, на которых будет основано группирование записей; закладка Sorting (Сортировка) определяет порядок упорядочения записей (по полям и по убыванию-возрастанию); закладка Output Fields (Выходные поля) содержит поля, которые можно использовать для сортировки записей; закладка Joins (Связи) предназначена для установки отношений между таблицами.
Что нового мы узнали? На этом занятии вы узнали: • что такое язык SQL и где он применяется; • каковы основные операторы и функции языка SQL; • как работать с SQL-запросами; • как применять программы SQL Explorer, SQL Builder и SQL Monitor.
'
-
.-
•
Занятие 12
.
•
Технология ADO Обзор ADO Компоненты ADO в Delphi 7 * События в ADO Асинхронная работа с сервером Создание простейшего приложения, использующего ADO
• На последнем занятии вы познакомитесь с технологией ADO и узнаете, как с помощью данной технологии работать с удаленными базами данных. Мы рассмотрим технологию доступа к данным, работу с транзакциями и асинхронное взаимодействие с сервером. В конце занятия мы создадим простое приложение, использующее технологию ADO.
Обзор ADO Компоненты для работы с Microsoft ActiveX Data Objects (ADO) впервые появились в среде Delphi версии 5. ADO — это технология стандартного обращения к реляционным структурам данных от Microsoft. Она аналогична BDE по назначению и сродни ему по возможностям. В основе архитектуры ADO лежит объектная модель компонентов COM (Component Object Model). Все объекты и интерфейсы ADO представляют собой интерфейсы и объекты СОМ. Модель СОМ является базовой для технологий ActiveX и OLE. Проиллюстрировать это отношение можно на примере объекта TObject, как базового объекта для VCL Delphi. Технология СОМ работает с так называемыми СОМ-объектами. Во многом СОМобъекты похожи на обычные объекты визуальной библиотеки компонентов Delphi. 7 Зах. 95
lllllllllllilMiimiiMiiiiiiM" MI
194
Занятие 12. Технология ADO
Но, в отличие от последних, СОМ-объекты не содержат поля, в них находятся лишь свойства и методы, а также интерфейсы. Интерфейсы — это группы логически или семантически связанных процедур, которые обеспечивают связь между поставщиком услуги (сервером) и его клиентом. Названия интерфейсов начинаются с буквы I. Обычный СОМ-объект включает в себя один или несколько интерфейсов. Кроме того, СОМ-объект содержит методы, которые позволяют приложению пользоваться им. Технология СОМ имеет два явных плюса: • создание СОМ-объектов не зависит от языка программирования. Таким образом, СОМ-объекты могут быть написаны на различных языках; • СОМ-объекты пригодны для использования в любой среде программирования под Windows. В число этих сред входят Delphi, Visual C++, C++ Builder, Visual Basic и многие другие. ПРИМЕЧАНИЕ Хотя технология СОМ имеет очевидные достоинства, ей свойственны также и минусы, среди которых можно выделить зависимость от платформы. Эта технология применима только в операционной системе Windows и на платформе Intel.
Технология СОМ реализуется с помощью СОМ-библиотек (такие файлы операционной системы, как OLE32.DLL и OLEAUT32.DLL). СОМ-библиотеки содержат набор стандартных интерфейсов, которые отвечают за функциональность СОМ-объекта, а также небольшой набор функций API, обеспечивающих создание СОМ-объектов и управление ими. В Delphi воплощение и поддержка технологии СОМ называется Delphi ActiveX framework, DAX. Реализация DAX описана в модуле AxCtrls. Рассмотрим особенности архитектуры ADO (рис. 12.1). Браузер приложения (Application Browser)
. ~ - '
Рис. 12.1. Архитектура ADO
Компоненты ADO в Delphi 7
195
Перечислим основные интерфейсы ADO и кратко поясним их назначение: • интерфейс IConnection выполняет следующие функции: Q осуществляет связь с сервером; Q управляет транзакциями; Q получает информацию о произошедших ошибках (свойство Errors); О получает информацию о схеме данных (таблицы, поля и т. д.); • интерфейс IRecordset (на нижнем уровне ADO это IRowset) является аналогом TDataSet в Delphi и поддерживает текущее положение и перемещение курсора, закладки (Bookmarks), чтение, изменение и удаление записей и т. п.; • интерфейс IField позволяет получать значение поля, его тип, длину и другие сведения о поле данных; • интерфейсы ICommand и IParameter обеспечивают работу с командами источника данных. Синтаксис команд для каждого из источников свой собственный; • интерфейс IProperty позволяет получать и устанавливать параметры, специфические для провайдера данных.
Компоненты ADO в Delphi 7 Для работы с механизмом ADO в Delphi 7 предназначены семь стандартных компонентов, расположенных на закладке ADO палитры компонентов (рис. 12.2).
Рис. 12.2. Закладка ADO
Первый компонент называется ADOConnection. Функционально он аналогичен компоненту Database закладки ВОЕ. С помощью компонента ADOConnection можно указывать местоположение базы данных и работать с транзакциями. Рассмотрим основные свойства компонента ADOConnection, отображаемые в окне инспектора объектов (табл. 12.1). Таблица 12.1. Основные свойства компонента ADOConnection Название свойства
Тип свойства
Краткое описание
Attributes
TXactAttributes
Установка данного свойства позволяет определить, как ведет себя соединение с базой данных, то есть будет ли открываться новая транзакция автоматически. Содержит два подчиненных свойства булевого типа (по умолчанию имеют значение false): xaCommitRetaining — определяет, будет ли новая транзакция открываться автоматически при подтверждении транзакции, и прекращает выполнение других транзакций; xaAbortRetaining — определяет, будет ли новая транзакция открываться автоматически при подтверждении транзакции, и отменяет с откатом (RollBack) выполнение других транзакций продолжение &
196
Занятие 12. Технология ADO
Таблица 12.1 (продолжение) Название свойства
Тип свойства
CommandTimeout Integer
Connected
Boolean
ConnectionString
WideString
ConnectionTimeout Integer
ConnectOptions
TConnectOption -
CursorLocation
TCursorLocation
DefaultDatabase
WideString -
IsolationLevel
TIsolationLevel
KeepConnection
Boolean
LoginPrompt
Boolean
Краткое описание Определяет время (в секундах) на выполнение команды. По истечении заданного интервала команда будет считаться невыполнившейся. По умолчанию длительность выполнения команды равна 30 Применяется для установления соединения с набором данных. По умолчанию имеет значение false, то есть связь с набором данных не установлена Содержит строку с информацией о месте хранения данных (о сервере базы данных) Определяет время в секундах, необходимое на попытку соединения с базой данных. По истечении этого времени будет выдано сообщение о невозможности соединения с сервером. По умолчанию имеет значение 15 Указывает тип соединения — синхронное или асинхронное: coConnectUnspecified — синхронный тип соединения (по умолчанию); coAsyncConnect — асинхронный тип соединения. Полезен, когда сервер базы данных очень медленный, но необходимо помнить, что не все данные будут доступны сразу после установки соединения Определяет тип курсора — клиентский или серверный. Может принимать два значения: clUseClient — наиболее затребуемый (по умолчанию). Все записи из набора данных копируются на компьютер-клиент; clUseServer — используемый намного реже, но удобный для работы с наборами данных, содержащими большое число записей Определяет базу данных, которая используется для соединения по умолчанию. В случае, когда соединение с базой данных, указанной в свойстве ConnectionString, невозможно установить, будет произведено подключение к базе данных, указанной в данном свойстве Уровень изоляции транзакций. Может принимать одно из следующих значений: ilUnspecified — неопределенный уровень изоляции; ilChaos — изменения, произведенные транзакциями с более высоким уровнем изоляции, не могут быть отменены с помощью транзакций данного уровня; ilReadUncommitted — незавершенные изменения других транзакций видимы в заданной; ilBrowse — то же, что и ilReadUncommitted; ilCursorStability — изменения, созданные другими транзакциями видны только после их завершения (по умолчанию); ilReadCommitted — то же, что и ilCursorStability; ilRepeatableRead — изменения, внесенные иными транзакциями, не видны, но их можно просмотреть с помощью повторного запроса -данных; ilSerializable — транзакции проводятся в полной изоляции от других транзакций; illsolated — то же, что и ilSerializable Определяет, будет ли сохраняться подключение к базе данных, даже если ни один набор данных не открыт. По умолчанию имеет значение true, то есть подключение будет сохраняться Указывает, будет ли диалог ввода имени пользователя и пароля отображаться непосредственно перед соединением с базой данных. По умолчанию имеет значение true, то есть диалог появляться будет
Компоненты ADO в Delphi 7
197
Название свойства
Тип свойства
Краткое описание
Mode
TConnectMode
Name
TComponentName
Provider
WideString
Назначает уровень доступа к данным в текущем соединении. Может принимать одно из перечисленных значений: cmUnknown — права доступа не установлены или не могут быть определены (по умолчанию); cmRead — доступ только для чтения данных; cmWrite — доступ только для записи данных; cmReadWrite — определены права для чтения и записи данных; cmShareDenyRead — запрет чтения данных для других пользователей, у которых имеется право на чтение данных; cmShareDenyWrite — запрет доступа к данным другим пользователям, обладающим правом записи данных; cmShareExclusive — режим, запрещающий всем другим пользователям получение доступа к данным; cmShareDenyNone — блокирует доступ к данным для всех пользователей с любыми правами Определяет имя компонента ADOConnection, которое будет использоваться в тексте программы Определяет провайдера соединения
Следующий компонент закладки ADO называется ADOCommand. Он предназначен для выполнения SQL-команды без возврата результирующего набора данных. Основные свойства этого компонента представлены в табл. 12.2. Таблица 12.2. Основные свойства компонента ADOCommand Название свойства
Тип свойства
Краткое описание
Сюда непосредственно записывается SQL-команда, которую необходимо выполнить CommandTimeout Integer Определяет допустимую задержку выполнения команды в секундах. По умолчанию имеет значение 30 Тип SQL-команды. Может принимать одно из перечисленных CommandType TCommandType значений: cmdUnknown — неизвестный тип команды; cmdText — текстовая команда или вызов хранимой процедуры; cmdTable — имя таблицы; cmdStoredProc — имя хранимой процедуры; cmdFile — имя файла набора данных; cmdTableDirect — имя таблицы, все столбцы будут возвращены Имя компонента типа ADOConnection для соединения с базой Connection TADOConnecHon данных ConnectionString WideString Определяет строку с информацией о месте хранения данных (о сервере базы данных). Может применяться вместо свойства Connection ExecuteOptions TExecuteOptions Включает в себя четыре подсвойства булевского типа. Значения по умолчанию (все — false): eoAsyncExecute — команда будет выполнена асинхронно; eoAsyncFetch — команда будет выполняться- асинхронно после указания значения в свойстве Cache; eoAsyncFetchNonBlocking — потоки при отработке • команды не блокируются; eoExecuteNoRecords — команда •* будет выполнена без возврата какого-либо значения Name TComponentName Определяет имя компонента ADOCommand, которое будет использоваться в тексте программы Prepared Word Bool Определяет, будет ли SQL-команда подготовлена перед вызовом метода Execute, непосредственно выполняющего команду ___ CommandText
WideString
1
198
Занятие 12. Технология ADO
Третий компонент закладки ADO носит имя ADODataSet. Его назначение — получение набора данных из одной или нескольких таблиц базы данных. Кроме того, он также позволяет работать с возвращенным набором данных визуальным компонентам, предназначенным для отображения данных. Это наиболее общий компонент для работы с набором данных, который может использоваться вместо компонентов ADOTable, ADOQuery или ADOStoredProc. В таблице 12.3 приведены основные свойства указанного компонента. Таблица 12.3. Основные свойства компонента ADODataSet Название свойства
Тип свойства
Краткое описание
Определяет, является ли набор данных открытым. По умолчанию имеет значение false, то есть набор данных закрыт Регламентирует, как будет осуществляться работа с автомаAutoCalcFields Boolean тически вычисляемыми полями. Если значение свойства true, то значения таких полей будут автоматически вычисляться в случае открытия набора данных, перевода набора данных в режим редактирования (dsEdit) или переключения фокуса с одного визуального компонента на другой, или из одной колонки визуального компонента в другую Integer Определяет размер кэша, выделенного для набора данных. CacheSize По умолчанию имеет значение 1 (минимальное). То есть будет кэшироваться одна запись набора данных В свойство записывается текст SQL-запроса, который будет CommandText WideString выполнен Определяет допустимую задержку выполнения SQL-запроса CommandTimeout Integer в секундах. По умолчанию разрешенная задержка равна 30 CommandType TCommandType Определяет тип SQL-запроса. Может принимать одно из следующих значений: cmdUnknown — неизвестный тип команды; cmdText — текстовая команда или вызов хранимой процедуры; • • cmdTable — имя таблицы; cmdStoredProc — имя хранимой про. цедуры; cmdFile — имя файла набора данных; cmdTableDirect — i имя таблицы, все столбцы будут возвращены Connection TADOConnection Здесь указывается имя компонента типа ADOConnection для соединения с базой данных ConnectionString WideString Строка, содержащая информацию о месте хранения данных (о сервере базы данных). Может применяться вместо свойства Connection CursorLocation TCursorLocation Определяет тип курсора — клиентский или серверный, то есть указывает, где будет выполняться работа с данными: dUseClient — наиболее используемый (по умолчанию). Все записи из набора данных копируются на компьютер-клиент; dUseServer — наименее используемый, но удобный для работы с наборами данных, содержащими большое количество записей. Работа с данными осуществляется на сервере Тип курсора набора данных. Может принимать одно из переCursorType TCursorType численных значений: ctUnspecified — тип курсора не был определен; ctOpenForwardOnly — однонаправленный курсор, с помощью которого можно переходить только на запись вперед. Имеет большое быстродействие; ctKeyset — курсор не позволяет видеть записи, добавленные другими пользователями. Записи, удаленные другими пользователями, становятся недоступными. Данный тип курсора устанавливается Active
Boolean
н
пни
iiiiiiiiiiiiiiiiiiiiiiimiiiiiilllllllllllHIl
Компоненты ADO в Delphi 7 Название свойства
Тип свойства
199
Краткое описание
DataSetField
TDataSetField
ExecuteOptions
TExecuteOptions
Filter
String
Filtered
Boolean -
IndexFieldNames String IndexName LockType
String TADOLockType
MarshalOptions
TMarshalOption
MasterFields
String
MaxRecords
Integer
Name StoreDefs
•TComponentName Boolean
•
по умолчанию; ctDynamic — динамический курсор. Изменение, удаление и вставка записей, произведенные другими пользователями, видимы. Возможно перемещение по записям вперед и назад; ctStatic — статический курсор. Доступна простая статическая копия данных. Изменения данных другими пользователями не видны. Применяется в основном для создания отчетов Используется для организации вложенных наборов данных и содержит название поля из главного набора данных Определяет параметры выполнения SQL-команды. Содержит, в свою очередь, четыре свойства булевого типа — по умолчанию все они имеют значение false: eoAsyncExecute — команда будет выполнена асинхронно; eoAsyncFetch — команда будет выполняться асинхронно после указания значения в свойстве Cache; eoAsyncFetchNonBlocking — команда будет выполнена без блокировки потоков; eoExecuteNoRecords — команда будет выполнена без возврата какого-либо значения Содержит текст текущего фильтра для набора данных. В визуальных компонентах отображаются только те данные, которые соответствуют условиям фильтра Определяет, будет ли учитываться значение свойства Filter при отображении данных в визуальных компонентах. Если значение данного свойства установлено в true — данные будут фильтроваться, иначе — фильтр игнорируется Содержит список столбцов таблицы, используемых в качестве индексных Определяет альтернативные индексы для таблицы Тип защиты (блокировки) набора данных. Может принимать одно из перечисленных значений: ItUnspecified — защита данных не используется; ItReadOnly — данные доступны только для чтения; ItPessimistic — «пессимистическая» блокировка. Запись блокируется сразу после начала редактирования и до сохранения; ItOptimistic — «оптимистическая» блокировка. Запись недоступна только во время сохранения изменений. Этот тип блокировки установлен по умолчанию; ItBatchOptimistic — то же самое, что и ItOptimistic, но используется отложенное сохранение изменений записей Определяет, будут ли отправлены на сервер те поля, которые не были обновлены. Может принимать следующие значения: moMarshalAII — неизмененные поля будут отправлены; moMarshalModifiedOnly — неизмененные поля отправке не подлежат Указывает одно или несколько полей главной таблицы (master table) для установления связи с соответствующими полями подчиненной таблицы, то есть типа master—detail Определяет количество записей, которые могут быть возвращены в результирующем наборе данных. По умолчанию равно 0, что означает неограниченное число записей Имя компонента набора данных Указывает, сохраняются ли определения полей и индексов в модуле данных или в форме. Если значение данного свойства — true, то определения полей и индексов будут сохраняться в модуле данных или в форме. Если значение свойства false (по умолчанию), то информация размещается в соответствующих файлах базы данных
200
Занятие 12. Технология ADO
Следующий компонент закладки ADO называется ADOTable. Он является аналогом компонента Table, расположенного на закладке BDE, и предназначен для доступа к таблице с помощью механизма ADO. Компонент ADOTable имеет свойства, которые мы уже рассматривали ранее в компонентах Table и ADODataSet, поэтому мы не будем возвращаться к ним еще раз. Компонент ADOQuery представляет собой запрос к базе данных. Это может быть как запрос, в результате которого возвращаются данные из базы (например, SELECT), так и запрос, не формирующий результирующего набора данных (например, INSERT). Компонент аналогичен компоненту Query из BDE. Все основные его свойства мы уже рассматривали в описании свойств компонентов Query и ADODataSet. Компонент ADOStoredProc предназначен для вызова процедуры, хранимой на сервере базы данных. В отличие от BDE и InterBase хранимые процедуры в ADO могут возвращать набор данных, поэтому компонент такого типа является потомком DataSet и может выступать источником данных в компонентах типа DataSource. Последний компонент закладки ADO называется RDSConnection. Этот компонент управляет маршалингом данных, когда набор записей переносится из одного компьютера на другой. ПРИМЕЧАНИЕ Маршалингом данных называется механизм, который позволяет клиенту получать доступ к объектам, расположенным в другом адресном пространстве или на другом компьютере.
События в ADO
•
.
На события в ADO возлагаются те же задачи, что и на события в VCL. Многие из событий ADO имеют аналоги в VCL, и соответствующие компоненты вызывают из событий ADO события VCL. Все события в ADO условно разделим на несколько групп: события соединения, события транзакции, события выполнения команд. События соединения: • OnWillConnect — вызывается перед установкой соединения; • OnConnectComplete — вызывается после установки соединения; • OnDisconnect — активируется при разрыве соединения. Эти события инкапсулированы в компоненте ADOConnection. События транзакции: • OnBegiriTransComplete — происходят при выполнении BeginTrans; • OnCommitTransComplete — происходят при выполнении CommitTrans; • OnRollbackTcansComplete — вызываются при выполнении RollbackTrans. События данной группы инкапсулированы в компоненте ADOConnection. События выполнения команд OnWillExecute и OnExecuteComplete вызываются перед выполнением команды и после него соответственно. Эти события «зашиты» в компоненте ADOConnection, а не в ADOCommand, как можно было бы предположить. Указанная «странность» связана с тем, что в ADO объекта команды как такового нет, и по этой причине он не может получать сообщения.
Асинхронная работа с сервером
201
В компонент ADOConnection также встроено событие OnlnfbMessage, которое вызывается по факту прихода с сервера дополнительной информации. Формат и назначение зависят от сервера, с которым вы работаете. В ADO есть и события, связанные с набором данных, а не с соединением, как вышеописанные. Они инкапсулированы в компоненты, представляющие наборы данных: ADODataSet, ADOTable, ADOQuery и ADOStoredProc. Эти события можно условно разбить на три группы. • События выборки данных: Q OnFetchProgress — многократно вызывается в процессе выборки данных; Q OnFetchComplete — завершение выборки. • Уведомления об изменении положения текущей записи в наборе: a OnWillMove — вызывается до изменения положения текущей записи. Позволяет отменить действие; Q OnMoveComplete — вызывается после изменения положения текущей записи; Q OnEndOfRecordset — генерируется при достижении конца набора данных. Позволяет добавить новую запись. • Уведомления об изменении набора данных: Q OnWillChangeField, OnFieldChangeComplete — вызываются до и после изменения текущей записи набора; О OnWillChangeRecord, OnRecordChangeComplete — вызываются до и после изменения, добавления, удаления строки набора и при отмене этих действий; Q OnWillChangeRecordset, OnRecordsetChangeComplete — вызываются до и после открытия, закрытия, повторного запроса и синхронизации набора данных. Многие события допускают прерывание действия. Эта возможность полезна при асинхронной работе с сервером, например, для прерывания слишком длинного запроса.
Асинхронная работа с сервером В ADO есть возможность, не имеющая аналогов ни в BDE, ни в InterBase. Это асинхронное выполнение операций с сервером. Асинхронно могут выполняться: • установка соединения с сервером (Connection); • выполнение команды (Execute); • выборка данных (Fetch).
Асинхронное соединение Для включения этого режима необходимо присвоить свойству ConnectOptions компонента ADOConnection значение coAsyncConnect. При установлении соединения происходит следующее: • вызывается обработчик события OnWillConnect;
202
Занятие 12. Технология ADO
• управление передается программе. После завершения соединения, как успешного, так и ошибочного, вызывается обработчик события OnConnectComplete. •
Асинхронное выполнение команды
Надо заметить, что многие компоненты ADO при активизации или выполнении отрабатывают команду на языке SQL. Это такие компоненты, как ADOCommand, ADODataSet, ADOTable, ADOQuery и ADOStoredProc. Для асинхронного выполнения команды установите в свойстве ExecuteOptions значение coAsyncExecute. При выполнении команды будет происходить следующее: • вызовется обработчик события OnWillExecute; • управление передастся программе. После окончания выполнения команды, как успешного, так и ошибочного, вызывается обработчик события OnExecuteComplete.
Асинхронная выборка данных Асинхронная выборка данных поддерживается в компонентах ADODataSet, ADOTable, ADOQuery и ADOStoredProc. Для ее включения установите в свойстве ExecuteOptions значение coAsyncFetch. После исполнения команды происходит передача данных. В процессе передачи многократно вызывается обработчик сообщения OnFetchProgress. В его параметрах указывается как количество уже переданных записей, так и общее количество предназначенных для передачи записей. Это очень удобно для создания индикаторов типа ProgressBar. После того как выборка с сервера закончена, вызывается обработчик события OnFetchComplete.
Создание простейшего приложения, использующего ADO В заключение создадим простое приложение, которое будет содержать только одну таблицу. Итак, в форме разместим три компонента с палитры компонентов: • ADOTable закладки ADO; • DataSource закладки Data Access; . • DBGrid закладки Data Controls. Свяжем эти компоненты между собой. Для этого установим значение свойства DataSource компонента DBGridl в DataSourcel. Вторым шагом значение свойства DataSet компонента DataSourcel установим в ADOTablel. Все три компонента теперь связаны. Осталось указать базу данных — в свойстве ConnectionString компонента ADOTablel нажмем кнопку с многоточием. Появится диалоговое окно редактора параметров соединения (рис. 12.3). Данное окно предоставляет вам право решать, каким образом будет указана строка связи с базой данных, расположенной на сервере. Один из вариантов — интерактивный ввод строки в поле Use Connection String. Кроме того, можно использовать
Создание простейшего приложения, использующего ADO
203
заранее подготовленный файл, содержащий такую строку связи (Use Data Link File). Установим переключатель в положение Use Data Link File и нажмем кнопку Browse. В открывшемся окне выбора файлов связи с данными выберем файл DBDEMOS.UDL (рис. 12.4).
Рис. 12.3. Окно редактора параметров соединения
Рис. 12.4. Окно выбора файлов связи с данными
Этот файл входит в дистрибутив Delphi и указывает на базу данных формата Microsoft Access, которая также поставляется вместе с Delphi. Нажмем кнопку Открыть, и в поле Use Data Link File появится строка C:\Program Files\Common Files\SYSTEM\ole db\Data Links\DBDEMOS.udl. Нажимаем OK — база данных выбрана. Теперь осталось определить таблицу базы данных. Для этого в свойстве TableName компонента ADOTablel указываем, например, таблицу COUNTRY. Наконец, мы можем активировать набор данных — присвоим свойству Active компонента ADOTablel значение true. Все, приложение готово, и его можно запускать (рис. 12.5).
204
Занятие 12. Технология ADO
Рис 12.5. Простое приложение, использующее ADO
Что нового мы узнали? Вот мы и подошли к концу этой книги, в которой рассмотрели различные возможности работы с базами данных. Дать вам представление о технологии ADO было последней моей задачей. На этом моя просветительская миссия заканчивается, вы готовы к самостоятельному более углубленному изучению предмета. А я еще раз напомню, что вы должны были извлечь для себя из материалов занятия: • что такое механизм ADO; • основные интерфейсы ADO; • компоненты ADO в Delphi 7 и их основные свойства; • основные события в ADO; • что такое асинхронная работа с сервером; • и, наконец, как создать простейшее приложение, использующее в своей работе механизм ADO. Удачи в дальнейших разработках!
'
•
•
Приложение Коды ошибок Borland Database Engine • При работе с BDE может появиться диалоговое окно с сообщением об ошибке. Как правило, такое окно содержит шестнадцатеричный код ошибки и ее описание. Описание выводится на английском языке. Чтобы вы не тратили время на перевод, здесь приводится таблица, которая содержит коды ошибок и их описание на английском и русском языках. В таблицу включены сведения далеко не обо всех ошибках BDE, но мы постарались выделить из них наиболее часто встречающиеся. Таблица П. Коды ошибок BDE
Код ошибки О 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34
Оригинальное сообщение Successful completion System error . Object of interest not found Physical data corruption I/O related error Resource or limit error Data integrity violation Invalid request Lock violation Access/security violation Invalid context OS error Network error Optional parameter Query processor Version mismatch Capability not supported System configuration error Warning Miscellaneous Compatibility error
Перевод Успешное завершение Системная ошибка Интересующий объект не найден Физическое повреждение данных Ошибка ввода-вывода Ошибка ресурса или ограничений Нарушение целостности данных Некорректный запрос Нарушение блокировки Нарушение системы доступа/безопасности Неверный контекст Ошибка операционной системы Сетевая ошибка Необязательный параметр Процессор запросов Несоответствие версии Совместимость не поддерживается Ошибка конфигурации системы Предупреждение Разное Ошибка совместимости продолжение #
206
Приложение. Коды ошибок Borland Database Engine
Таблица П (продолжение)
Код ошибки
Оригинальное сообщение
Перевод
ЗЕ
Driver specific error Internal symbol
Ошибка драйвера Внутренний символ
100
KEYVIOL
Неверный ключ
101
PROBLEMS
102
CHANGED
200
Production index file missing, corrupt or cannot interpret index
Внутренние неполадки Критические изменения Индексный файл отсутствует или поврежден, либо ошибка интерпретации индекса
201
Open read only
Открыто только для чтения
202
Open the table in read only mode Открытие таблицы в режиме только для чтения Открытие и отсоединение Open and detach
3F
key
203 204
Open the table and detach the production index file
205 206
Fail open Do not open the table Convert non-dBASE index Convert production index to dBASE format
Открытие таблицы и отсоединение индексного файла Ошибка открытия Таблица не открыта Попытка преобразования не dBASE-индекса Преобразование индекса в формат dBASE :
209
BLOB file not found
BLOB-файл не найден
20A 20B
Open without BLOB file Open the table without the BLOB file Empty all BLOB fields
Открытие без BLOB-файла Открытие таблицы без BLOB-файла
20C 20D 20E 20F 210 211 212 213 214
Все BLOB-поля пусты
Reinitialize BLOB file and LOSE all BLOBS Fail open Do not open the table
Повторная инициализация BLOB-файла с потерей всех объектов Ошибка открытия Невозможно открыть таблицу Импортируемый BLOB-файл не dBASE формата Import non-dBASE BLOB file Import BLOB file to dBASE format Импортирование BLOB-файла в формат dBASE Open as non-dBASE table Открытие таблицы как не dBASE-формата Открытие таблицы и BLOB-файла в их «родном» Open table and BLOB file in its native format формате Production index language driver Драйвер языка, не соответствует индексу mismatch
215
Production index damaged
216 217
Rebuild production index Перестройка индекса Rebuild all the production indexes Перестройка всех индексов
400
Индекс поврежден
Lookup table not found or corrupt Искомая таблица не найдена или повреждена BLOB-файл не найден или поврежден
401
Blob file not found or corrupt
402 403
Open read only Открытие в режиме только для чтения Open the table in read only mode Открытие таблицы возможно только в режиме для чтения
404
Fail open
Ошибка открытия
Коды ошибок Borland Database Engine
207
Код ошибки
Оригинальное сообщение
Перевод
405 406
Do not open the table Remove lookup
407 500
Remove link to lookup table Doctionary object exist
Невозможно открыть таблицу Искомый файл был удален Связь с искомой таблицей была удалена
501
Данный объект будет пропущен Skip importing this object and its Импортирование данного объекта и ассоциированassociated relationship ных с ним связей будет пропущено Использование существующего объекта Use existing object Использование существующего объекта словаря для Use existing dictionary object установки связей for relationship
502 503 504
«
Объект словаря уже существует
Skip this object
505
Abort
Действие прервано
506 507
Abort the operation Dictionary object import failed
Операция прервана Ошибка импорта объекта словаря
134E
Unmapped SQL error code
Неожиданная ошибка SQL
2101 2102
Cannot open a system file I/O error on a system file
Невозможно открыть системный файл
2103 2104
Data structure corruption Cannot find engine configuration file Cannot write to engine configuration file
2105
Ошибка ввода-вывода при работе с системным файлом Структура данных повреждена Невозможно найти конфигурационный файл ВОЕ Невозможно произвести запись в конфигурационный файл BDE Невозможно инициализировать приложение с другим конфигурационным файлом Произведен некорректный повторный вход в систему
2106
Cannot initialize with different configuration file
2107
System has been illegally reentered
2108
Невозможно найти файл IDAPI32.DLL Cannot locate IDAPI32.DLL Невозможно загрузить файл IDAPI32.DLL Cannot load IDAPI32.DLL Невозможно загрузить библиотеку IDAPI Cannot load an IDAPI service library Cannot create or open temporary Невозможно создать или открыть временный файл
2109 210A 210B 2203 2204 2205
file
Record moved because key value Запись была перемещена из-за смены значения ключа changed Запись/ключ удалены Record/key deleted No current record
Текущая запись отсутствует
2206
Could not find record
Невозможно найти запись
2207
End of BLOB
Конец BLOB-объекта
2208 2209 220A
Could not find object Could not find family member BLOB file is missing
Невозможно найти объект Невозможно найти члена семейства
220B
Could not find language driver
BLOB-файл отсутствует Невозможно найти драйвер языка
2301
Corrupt table/index header
Заголовок таблицы/индекса поврежден продолжение #
МПП111ШМ11111
208
Приложение. Коды ошибок Borland Database Engine
Таблица П (продолжение)
Код) ошибки 2302 2303 2305 2306 2307 2308 2309 2401 2402 2403 2404 2405 2406 2501 2502 2503 2504 2505 2506 2507 2508 2509 250A 250B 250C 250D 250E 250F 2510 2511 2512 2513 2514 2515 2516 2517 2518 251A 251B
Оригинальное сообщение Corrupt file - other than header Corrupt memo/BLOB file Corrupt index Corrupt lock file Corrupt family file Corrupt or missing .VAL file Foreign index file format Read failure Write failure Cannot access directory File delete operation failed Cannot access file Access to table disabled because of previous error Insufficient memory for this operation Not enough file handles Insufficient disk space Temporary table resource limit Record size is too big for table Too many open cursors Table is full Too many sessions from this workstation Serial number limit Some internal limit Too many open tables Too many cursors per table Too many records locks on table Too many clients Too many indexes on table Too many sessions Too many open databases Too many passwords Too many active drivers Too many fields in table create Too many table locks Too many open BLOBs Lock file has grown too large Too many open queries Too many BLOBs Filename is too lonafor a Paradox version 5.0 table
Перевод Поврежденный файл не соответствует заголовку Файл Memo/BLOB поврежден Индекс поврежден Блокированный файл поврежден Файл семейства поврежден Файл с расширением VAL поврежден или отсутствует Неверный формат файла внешнего индекса Ошибка чтения Ошибка записи Ошибка доступа к каталогу Ошибка удаления файла Доступ к файлу невозможен Доступ к таблице закрыт из-за предыдущей ошибки Недостаточно памяти для выполнения операции Недостаточно дескрипторов файлов Недостаточно дискового пространства Достигнут предел ресурса временной таблицы Размер записи слишком велик для таблицы Слишком много открытых курсоров Таблица заполнена Слишком много сессий для данной рабочей станции Достигнут предел серийного номера (для Paradox) Внутреннее ограничение Слишком много открытых таблиц Слишком много курсоров для одной таблицы Слишком много блокированных записей в таблице Слишком много клиентов Слишком много индексов в таблице Слишком много сессий Слишком много открытых баз данных Слишком много паролей Слишком много активных драйверов Слишком много полей в создаваемой таблице Слишком много блокировок таблицы Слишком много открытых BLOB-объектов Блокированный файл слишком быстро растет Слишком много открытых запросов Слишком много BLOB-объектов Имя файла слишком велико для таблицы Paradox
версии 5.0
Коды ошибок Borland Database Engine Код ошибки
Оригинальное сообщение
251С
Row fetch limit exceeded
Превышен предел двойников в строке
251D
Long name not allowed for this
Длинные имена не разрешены на данном уровне таблицы
table level
Перевод
2601
Key violation
Нарушение ключа
2602
Minimum validity check failed
Ошибка минимальной проверки корректности Ошибка максимальной проверки корректности
2603 2604 2605
Maximum validity check failed Field value required Master record missing
209
Требуется задать значение поля Отсутствует основная запись
2606
Master has detail records. Cannot Удаление или изменение основной записи невозdelete or modify можно, так как она имеет подчиненные записи
2607
Master table level is incorrect
2608
Field value out of lookup table Значение поля вне области поиска внутри таблицы range Lookup table open operation failed Ошибка открытия таблицы поиска
2609 260А 260В 260С 260D
Уровень главной таблицы некорректен
Detail table open operation failed Ошибка открытия подчиненной таблицы Master table open operation failed Ошибка открытия главной таблицы Поле пусто
Field is blank Link to master table already defined
Связь с главной таблицей уже определена
260Е 260F 2610
Главная таблица открыта Master table is open Detail table(s) exist Подчиненные таблицы существуют Master has detail records. Cannot Удалить главную запись невозможно, так как она empty it имеет подчиненные записи
2611
Self referencing referential integrity must be entered one at a time with no other changes to the table Detai table is open Cannot make this master a detail of another table if its detail are not empty
2612 2613
Ссылка на себя должна быть введена без других изменений в таблице
Подчиненная таблица открыта Главную таблицу невозможно сделать подчиненной для другой таблицы, так как ее собственная подчиненная таблица не пуста Поля ссылочной целостности должны быть индексированы Таблица, связанная при помощи ссылочной целостности, требует пароль для открытия
2614
Referential integrity fields must be indexed
2615
A table linked by referential integrity requires password to open
2616
Field(s) linked to more than one master
Поля связаны более чем с одной главной таблицей
2701 2702 2703 2704 2705 2706
Number is out of range Invalid parameter
Число за пределами диапазона Неверный параметр
Invalid file name
Неправильное имя файла Файл не существует
File does not exist Invalid option Invalid handle to the function
Неверная опция Неверный дескриптор функции продолжение &
210
Приложение. Коды ошибок Borland Database Engine
Таблица П (продолжение)
Код ошибки
Оригинальное сообщение
Перевод
2707 2708 2709 270C 270D 270E 270F 2710 2711 2712 2713 2714 2715 2716
Unknown table type Cannot open file Cannot redefine primary key Invalid modify request Index does not exist Invalid offset into the BLOB Invalid descriptor number Invalid field type Invalid field descriptor Invalid field transformation Invalid record structure Invalid descriptor Invalid array of index descriptors Invalid array of validity check descriptors Invalid array of referential integrity descriptors Invalid ordering of tables during restructure Name not unique in this context Index name required Invalid session handle Invalid restructure operation Driver not known to system Unknown database Invalid password given No callback function Invalid callback buffer length Invalid directory Value out of bounds Cannot set cursor of one table to another Bookmarks do not match table Invalid index/tag name Invalid index descriptor Table does not exist Table has too many users Cannot evaluate key or key does not pass filter condition Index already exists Index is open Invalid BLOB length Invalid BLOB handle in record buffer
Неизвестный тип таблицы Невозможно открыть файл Невозможно переопределить первичный ключ Неправильный запрос на изменение Индекс не существует Неправильное смещение внутри BLOB-объекта Неправильный номер дескриптора Неправильный тип поля Неверный дескриптор поля Неправильное преобразование поля Неверная структура записи Неправильный дескриптор Некорректный массив дескрипторов индексов Некорректный массив дескрипторов проверки
2717 2718 2719 271A 271B 271C 27ID 271E 271F 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 272A 272B 272C 272D 272E
Некорректный массив дескрипторов ссылочной целостности Неправильный порядок таблиц во время реструктуризации Имя не уникально в данном контексте Требуется имя индекса Некорректный дескриптор сессии Некорректная операция реструктуризации Драйвер не известен системе Неизвестная база данных Некорректный пароль Нет функции обратного вызова Некорректная длина буфера обратного вызова Неверный каталог Значение вышло за пределы допустимого Невозможно установить курсор одной таблицы в другой Закладка не соответствует таблице Неверное имя индекса или тега Некорректный дескриптор индекса Таблица не существует У таблицы слишком много пользователей Вычислить ключ невозможно или ключ не удовлетворяет условиям фильтра Индекс уже существует Индекс открыт Некорректная длина BLOB-поля Некорректный дескриптор BLOB в буфере записи
Коды ошибок Borland Database Engine
211
Код ошибки
Оригинальное сообщение
Перевод
272F 2730 2731 2732 2733 2734 2735
Table is open Need to do restructure Invalid mode Cannot close index Index is being used to order table Unknown user name or password Multi-level cascade is not supported Invalid field name Invalid table name Invalid linked cursor expression Name is reserved Invalid file extension Invalid language driver Alias is not currently opened Incompatible record structures Name is reserved by DOS Destination must be indexed Invalid index type Language drivers of table and index do not match Filter handle Is invalid Invalid filter Invalid table create request Invalid table delete request Invalid index create request Invalid index delete request Invalid table specified Invalid time Invalid date Invalid datetime Tables in different directories Mismatch in the number of arguments Function not found in service library Must use base order for this operation Invalid procedure name The field map is invalid Record locked by another user
Таблица открыта Требуется реструктуризация Неверный режим Невозможно закрыть индекс Индекс используется таблицей Неизвестное имя пользователя или пароль Многоуровневое каскадирование не поддерживается
2736 2737 2738 2739 273А 273В 273С 273D 273Е 273F 2740 2741 2742 2743 2744 2745 2746 2747 2748 274А 274В 274С 274D 274Е 274F 2750 2751 2752 2801 2802
2803
Unlock failed Table is busy
^___
Неверное имя поля Неверное имя таблицы Неверное выражение для связанного курсора Имя зарезервировано Неверное расширение файла Неверный драйвер языка Псевдоним в настоящее время не открыт Несовместимая структура записи • Имя зарезервировано для использования DOS Приемник должен быть индексирован Неверный тип индекса Драйверы языка таблицы и индекса не совпадают Некорректный дескриптор фильтра Некорректный фильтр Неверный запрос создания таблицы Неверный запрос удаления таблицы Неверный запрос создания индекса Неверный запрос удаления индекса Определена некорректная таблица Неверное время Неверная дата Неверные дата и время Таблицы находятся в разных каталогах Несобтветствие по количеству аргументов •
Функция не найдена в библиотеке
•
Для данной операции должен использоваться базовый порядок Неверное имя процедуры \ Карта поля неверна \ Запись блокирована другим пользователем Попытка деблокирования неудачна Таблица занята продолжение &
212
Приложение. Коды ошибок Borland Database Engine
Таблица П (продолжение)
ошибки
Код
Оригинальное сообщение
Перевод
2804
Directory is busy
2805 2806
File is locked Directory is locked
Каталог занят Файл заблокирован
2807
Record already locked by this session
Запись уже заблокирована в этой сессии
2808
Object not locked
Объект не заблокирован Время блокировки истекло Группа ключей заблокирована •
2809
Lock time out
280A 280B 280C
Key group is locked Table lock was lost Exclusive access was lost
280D
Table cannot be opened for exclusive use Conflicting record lock in this session A deadlock was detected A user transaction is already in progress No user transaction is currently In progress
280E 280F 2810 2811 2812 2813 2814
2901 2902 2903 2904 2905 2906 2907 2908
Каталог заблокирован I
Блокировка таблицы снята Исключительный доступ к данным был деактивирован Таблица не может быть открыта в режиме исключительного пользования Конфликтная запись была заблокирована в данной сессии Взаимоблокировка Пользовательская транзакция уже в процессе выполнения В настоящее время пользовательские транзакции не выполняются Ошибка блокировки поля
Record lock failed Couldn't perform the edit because Невозможно выполнить редактирование, так как another user changed the record запись была изменена другим пользователем Couldn't perform the edit because Невозможно выполнить редактирование, так как запись была удалена или перемещена другим another user deleted or moved пользователем the record Недостаточно прав поля для выполнения операции Insufficient field rights for operation Недостаточно прав таблицы для выполнения операInsufficient table rights for operation. Password required ции. Требуется пароль Недостаточно прав семейства для выполнения опеInsufficient family rights for operation рации Используемый каталог только для чтения This directory is read-only База данных только для чтения Database is read-only Попытка изменения поля только для чтения Trying to modify read-only field Зашифрованные таблицы dBASE не поддерживаются Encrypted dBASE tables not supported Недостаточно прав SQL для выполнения операции Insufficient SQL rights for operation Не BLOB-поле Reid is not a BLOB
2A01 2A02 2A03 2A04
BLOB already opened BLOB not opened Operation not applicable
2A05
Table is not indexed
2A06 2A07
Engine not initialized Attempt to re-initialize engine
BLOB-поле уже открыто BLOB-поле не открыто Операция не применима Таблица не индексирована BDE не инициализирован Попытка повторной инициализации BDE
Коды ошибок Borland Database Engine
213
Код ошибки
Оригинальное сообщение
2А08
Попытка смешивания объектов разных сессий Attempt to mix objects from different sessions Paradox driver not active Драйвер Paradox не активирован Driver not loaded Драйвер не загружен Нет сопоставленного индекса No associated index Table open. Cannot perform this Таблица открыта. Выполнение данной операции operation невозможно Таблица не поддерживает данную операцию Table does not support this operation • Таблица не поддерживает операцию, так как не Table.does not support this operation because it is not имеет уникального индекса uniquely indexed Operation must be performed on Операция должна быть выполнена в текущей сессии the current session Неправильное использование ключевого слова Invalid use of keyword Connection is in use by another Соединение используется другим оператором statement Проходящее SQL-соединение должно быть раздеPass-through SQL connection must be shared ляемым Неверный номер функции Invalid function number File or directory does not exist Файл или каталог не существует Path not found Путь не найден Слишком много открытых файлов. Вам следует Too many open files. You may need to increase MAXFILEHANDLE увеличить значение MAXFILEHANDLE в настройках limit in IDAPI configuration IDAPI . Permission denied Доступ закрыт -• • Bad file number Неверный номер файла Уничтожены блоки памяти Memory blocks destroyed Not enough memory Недостаточно памяти Неверно указан адрес блока памяти Invalid memory block address Invalid environment Некорректное окружение Invalid format Неверный формат Неверный код доступа Invalid access code Invalid data Неверные данные Device does not exist Устройство не существует Попытка удаления текущего каталога Attempt to remove current directory Попытка использовать различные устройства Not same device No more files Файлов больше нет Invalid argument Неверный аргумент Argument list is too long Список аргументов слишком велик Execution format error Ошибка исполняемого формата Cross-device link Использование связи с пересечением устройств Результат слишком велик Result is too large продолжение &
2A09 2AOA 2AOC 2AOD 2AOE 2A10 2A11 2A12 2A13 2A14 2B01 2B02 2B03 2B04 2B05 2B06 2B07 2B08 2B09 2BOA 2BOB 2BOC 2BOD 2BOF 2B10 2B11 2B12 2B13 2B14 2B15 2B16 2B22
Перевод уи!
214
Приложение. Коды ошибок Borland Database Engine
Таблица П. (продолжение) Код ошибки
Оригинальное сообщение
Перевод
2В27
Unknown internal operation system error Share violation Lock violation Drive not ready Not exact read/write Operation system network error Record already locked by this workstation Record not locked Network initialization failed Network user limit exceeded Wrong .NET file version Cannot lock network file Unknown network error Not initialized for accessing network flies SHARE not loaded. It is required to share local flies Lost communication with SQL server Cannot locate or connect to SQL server Optional parameter is required Invalid optional parameter Only numeric and date/time fields can be averaged Invalid expression Invalid OR expression CALC expression cannot be used
Неизвестная внутренняя ошибка операционной системы Ошибка совместного использования Нарушение блокировки Накопитель не готов Неточное чтение-запись Сетевая ошибка операционной системы Запись уже заблокирована с данной рабочей станции
2B32 2B33 2B35 2B64 2B65 2B68 . 2B69 2C01 2C02 2C03 2C04 2C07 2C08 2C09 2COB 2COD 2D01 2D02 2E07 2E08 2E09 2EOC
in INSERT, DELETE, CHANGETO and SET rows 2EOD
Type error in CALC expression
2EOE
CHANGETO can be used in only one query form at a time A field cannot contain more than one expression to be inserted Expression in this field has the wrong type Extra comma found Extra OR found One or more query rows do not contribute to the ANSWER Use only one INSERT, DELETE, SET or FIND per line
2E11 2E1E 2E1F 2E20 2E21 2E27
Запись не заблокирована Ошибка инициализации сети Превышен предел количества пользователей сети Некорректная версия файла .NET Невозможно заблокировать сетевой файл Неизвестная сетевая ошибка Сетевые файлы не были инициализированы для доступа Программа SHARE не загружена. Она необходима для разделения локальных файлов Потеря соединения с SQL-сервером SQL-сервер не обнаружен или с ним невозможно соединиться Требуется указать необязательный параметр Некорректный необязательный параметр Усреднены могут быть только числовые поля и поля даты/времени Некорректное выражение Некорректное выражение OR Выражение CALC не может быть использовано операторами INSERT, DELETE, CHANGETO и SET Ошибка типа в выражении CALC CHANGETO может быть использован только в одной форме запроса одновременно Поле не может содержать более одного выражения для вставки Выражение в поле имеет неверный тип -
Найдена лишняя запятая Найдено лишнее слово OR Одна или более строк запроса не входят в ANSWER В строке может находиться только один оператор: INSERT, DELETE, SET или FIND
Коды ошибок Borland Database Engine
215
Код ошибки
Оригинальное сообщение
Перевод
2Е28 2ЕЗО
Syntax error in expression
Синтаксическая ошибка в выражении Строки образцов в выражении CALC должны быть связаны '
2Е31
2Е32 2ЕЗЗ
2Е34 2Е35 2Е36 2Е37 2Е38 2Е39 2ЕЗВ 2ЕЗС 2E3D 2ЕЗЕ 2E3F 2Е43 2Е46 2Е47 2Е48 2Е49 2Е4В 2Е4С 2Е4Е 2Е50 2Е51
2Е52 2Е53 2Е55 2Е56 2Е57
Rows of example elements in CALC expression must be linked Variable name is too long Query may take a long time to process Reserved word or one that can't be used as a variable name Missing comma Missing)
Имя переменной слишком велико Запрос может потребовать много времени для выполнения Зарезервированное слово не может быть использовано в качестве имени переменной Пропущена запятая
Missing right quote
Пропущена закрывающая скобка Пропущена правая кавычка
Cannot specify duplicate column names
Недопустимо наличие столбцов с одинаковыми именами
Query has no checked fields Example element has no defining occurrence Query makes no sense Cannot use patterns in this context
Запрос не проверяет поля Образец не имеет определения Запрос не понятен В данном контексте нельзя использовать шаблоны
Date does not exist Variable has not been assigned
Дата не существует Переменной не присвоено значение
Invalid use of example element in summary expression Row cannot contain expression
Некорректное использование примера в итоговом выражении Строка не может содержать выражение Недостаточно прав для вставки или удаления записи
a value
No permission to insert or delete record No permission to modify field Field not found in table Expecting a column separator in table header Expecting column name in table Expecting table name
Недостаточно прав на изменение полей Поле в таблице не найдено В заголовке таблицы ожидается разделитель столбцов Ожидается имя столбца таблицы
Ожидается имя таблицы Cannot opeg table Невозможно открыть таблицу This DELETE, CHANGE or INSERT Запрос DELETE, CHANGE или INSERT не имеет ответа query has no answer Query is not prepared. Properties Запрос не подготовлен. Свойства неизвестны unknown DELETE rows cannot contain quantifier expression
Строки DELETE не могут содержать числовых выражений Invalid expression in INSERT row Некорректное выражение в строке INSERT Invalid expression in SET definition Некорректное выражение в определении SET Row use Строка уже используется SET keyword expected Ожидается ключевое слово SET продолжение &
216
Приложение. Коды ошибок Borland Database Engine
Таблица П (продолжение) Код ошибки
Оригинальное сообщение
Перевод
2Е58
Ambiguous use of example element Only numeric fields can be summed Table is write protected Type mismatch in expression Query appears to ask two unrelated questions Unused SET row Lock failure Expression is too long Refresh exception during query
Неоднозначное использование примера
2Е5В 2Е5С 2E5F 2Е60
2Е61 2Е65 2Е66 2Е67 2Е68 2Е69 2Е6А 2Е6В 2E6D 2Е6Е 2E6F 2Е70
2Е71 2Е72 2Е75 2Е76 2Е77 2Е78 2Е79 2Е9С 2E9D
2Е9Е 2E9F 2ЕАО 2ЕА1
Суммироваться могут только числовые поля Таблица защищена от записи Неправильный тип в выражении Запрос включает два несвязанных вопроса
Неиспользуемая строка SET Ошибка блокировки Выражение слишком длинное Исключительная ситуация обновления во время исполнения запроса Query canceled Запрос отменен Unexpected Database Engine error Неожиданная ошибка BDE Not enough memory to finish Недостаточно памяти для завершения операции operation . Unexpected exception Неожиданное исключение Формат запроса не поддерживается Query format is not supported Query string is empty Строка запроса пуста Attempted to prepare an empty Попытка подготовки пустого запроса query Buffer too small to contain query Буфер слишком мал для размещения строки запроса string Query was not previously parsed Запрос не был предварительно разобран или or prepared подготовлен Function called with bad query Функция вызвана с неправильным дескриптором запроса handle Reid name in sort or field clause В выражении сортировки или поиска не найдено имя поля not found Table name in sort or field clause В выражении сортировки или поиска не найдено имя not found таблицы Данная операция не применима к BLOB-полям Operation is not supported on BLOB fields General BLOB error Общая ошибка BLOB Query must be restarted Запрос должен быть перезапущен Unique index required to delete Для удаления записей требуется наличие уникальноrecords го индекса Update of table on the server Ошибка обновления таблицы на сервере failed Cant process this query remotely Удаленная обработка запроса невозможна Unexpected end of command Неожиданный конец команды Parameter not set in query string Не установлены параметры в строке запроса Query string is too long Строка запроса слишком велика
Коды ошибок-Borland Database Engine Код ошибки 2ЕАА 2ЕАВ 2ЕАС 2ЕАЕ 2ЕВО 2ЕВ1 2ЕВ2 2EB3 2F01 2F02 2F05 2F06 2F07 2F08 3001 3002 3005 3006 3101 3102 3103 3104 3106 320А 320В 3302 3303 3304 3305 3306 3401 3402
217
Оригинальное Перевод сообщение No such table or correlation name Таблицы с таким именем не существует Expression has ambiguous data Выражение содержит неоднозначные типы данных type Field in order by must be in result В результирующем наборе данных поля должны set быть отсортированы Record or field constraint failed Ошибка ограничения записи или поля User defined function is not Пользовательская функция не определена defined Unknown error from user defined Неизвестная ошибка в пользовательской функции function Single row subquery produced Однострочный подзапрос выдает более одной строки more than one row Expression in group by are not Выражения при группировании не поддерживаются supported Interface mismatch. Engine Несоответствие интерфейсов из-за различий version different в версиях ВОЕ Index is out of date Индекс за пределами данных BLOB file version is too old Слишком старая версия BLOB-файла Query and engine DLLs are Запрос и DLL не соответствуют друг другу mismatched Server is incompatible version Несовместимая версия сервера Higher table level required Требуется более высокий уровень таблицы Capability not supported Совместимость не поддерживается Not implemented yet Данная функция пока не реализована Multiple connections not Множественные соединения не поддерживаются supported Full dBASE expressions not Нет полной поддержки выражений dBASE supported Invalid database alias specification Неверная спецификация псевдонима базы данных Unknown database type Неизвестный тип базы данных Corrupt system configuration file Поврежден системный файл конфигурации Network type unknown 'Неизвестный тип сети Invalid configuration parameter Неверный параметр конфигурации Validity check will not be enforced Проверка корректности не выполнена Multiple records found, but only Найдены множественные записи, в то время как one was expected ожидается только одна BLOB has been modified BLOB-объект был изменен General SQL error Общая ошибка SQL Table already exists Таблица уже существует Paradox 1.0 table' ve not Таблицы Paradox 1.0 не поддерживаются supported Update aborted Обновление прекращено Different sort order Неверный порядок сортировки Directory in use by earlier version Каталог используется более ранней версией Paradox of Paradox продолжение &
-
-—
218
Приложение. Коды ошибок Borland Database Engine
Таблица П (продолжение)
\.
Код ошибки
Оригинальное сообщение
Перевод
3403
Needs Paradox 3.5-compatible language driver
Требуется драйвер языка, совместимый с Paradox 3.5
3501 3505 3506 3507 3508 3509 350B 350C
Data dictionary is corrupt Invalid object type Invalid relation type View already exists No such view exists Invalid record constraint Dictionary already exists Dictionary does not exists
350D
Dictionary database does not exists Dictionary info is out of date needs refresh Invalid dictionary name Dependent objects exists Too many relationship for this object type Cannot access data dictionary Cannot create data dictionary Cannot open database Wrong driver name Wrong system version Wrong driver version Wrong driver type Cannot load driver Cannot load language driver Your application is not enabled for use with this driver
Словарь данных поврежден Неверный тип объекта Неверный тип отношения Представление уже существует Представление не существует Содержится неверная запись Словарь уже существует Словарь не существует База данных словаря не существует
350E 3510 3511 3512 3518 3519 351A 3E01 3E02 3E03 3E04 3E05 3E06 3E08
Информация словаря за пределами данных. Требуется обновление Неверное имя словаря Найдены зависимые объекты Слишком много связей для данного типа объекта Доступ к словарю данных невозможен Невозможно создать словарь данных Невозможно открыть базу данных Неверное имя драйвера Неверная версия системы Неверная версия драйвера Неверный тип драйвера Невозможно загрузить драйвер Загрузить драйвер языка невозможно Ваше приложение не может использоваться с этим драйвером
•
.
:
'
...
I '
..
. 1
Литература 1. Бобровский С. Delphi 5: Учебный курс. — СПб.: Питер, 2000. 2. Елманова Н., Трепалин С., Тенцер A. Delphi 6 и технология СОМ. — СПб.: Питер, 2002. 3. Жуков А. Изучаем Delphi. - СПб.: Питер, 2000. 4. Карпов Б. Delphi 5: Учебный курс. — СПб.: Питер, 2001. 5. Карпова Т. Базы данных: модели, разработка, реализация. — СПб.: Питер, 2001. 6. Кэнтпу М. Delphi 6 для профессионалов. — СПб.: Питер, 2002. 7. Свиридов Ю., Тюкачев Н. Delphi 5. Создание мультимедийных приложений: Учебный курс. - СПб.: Питер, 2001. 8. Фаронов В. Delphi 6. Учебный курс. - СПб.: Питер, 2002. 9. Фаронов В. Программирование баз данных в Delphi 6. Учебный курс. — СПб.: Питер, 2002. 10. Фаронов В. Профессиональная работа в Delphi 6. Библиотека программиста. - СПб.: Питер, 2002. .' • •
КНИГА-ПОЧТОЙ
i—»—=•••
ЗАКАЗАТЬ КНИГИ ИЗДАТЕЛЬСКОГО ДОМА «ПИТЕР» МОЖНО ЛЮБЫМ УДОБНЫМ ДЛЯ ВАС СПОСОБОМ: по телефону: (812) 103-73-74;
по электронному адресу: [email protected]; на нашем сервере: www.piter.com; по почте: 197198, Санкт-Петербург, а/я 619
ЗАО «Питер Пост».
ВЫ МОЖЕТЕ ВЫБРАТЬ ОДИН ИЗ ДВУХ СПОСОБОВ ДОСТАВКИ И ОПЛАТЫ ИЗДАНИЙ:
<Ц5 Наложенным платежом с оплатой заказа при получении посылки на ближайшем почтовом отделении. Цены на издания приведены ориентировочно и включают в себя стоимость пересылки по почте (но без учета авиатарифа). Книги будут высланы нашей службой «Книга-почтой» в течение двух недель после получения заказа или выхода книги из печати. & Оплата наличными при курьерской доставке (для жителей Москвы и Санкт-Петербурга). Курьер бесплатно доставит заказ по указанному адресу в удобное для вас время в течение трех дней. Такой заказ лучше оформлять по телефону. ПРИ ОФОРМЛЕНИИ ЗАКАЗА УКАЖИТЕ:
• фамилию, имя, отчество, телефон, факс, e-mail; • почтовый индекс, регион, район, населенный пункт, улицу, дом, корпус, квартиру; • название книги, автора, код, количество заказываемых экземпляров. ;П>
• • • - /г,
Вы можете заказать бесплатный журнал «Клуб Профессионал».
•
пзалтЕпьскпп аом
•
Нет времени ходить по магазинам?
www.piter.com Здесь вы найдете: Все книги издательства сразу Новые книги — в момент выхода из типографии Информацию о книге — отзывы, рецензии, отрывки Старые книги — в библиотеке и на CD И, наконец, вы нигде не купите наши книги дешевле!
пзалтЕпьскпп аом \*^ ЩИТКП® * "* * tmi1" WWW.PITER.COM
СПЕЦИАЛИСТАМ КНИЖНОГО БИЗНЕСА! •
ПРЕДСТАВИТЕЛЬСТВА ИЗДАТЕЛЬСКОГО ДОМА «ПИТЕР» предлагают эксклюзивный ассортимент компьютерной, медицинской, психологической, экономической и популярной литературы
Москва
РОССИЯ
м. «Калужская», ул. Бутлерова, д. 176, офис 207, 240; тел./факс (095) 777-54-67; e-mail: [email protected] Санкт-Петербург м. «Выборгская», Б. Сампсониевский пр., д. 29а; тел. (812) 103-73-73, факс (812) 103-73-82; e-mail: [email protected]
Воронеж
ул. Ленинградская, д. 138; тел. (0732) 49 68 86; e-mail: [email protected]
Екатеринбург
ул. 8 Марта, д. 2676; тел./факс (3432) 25-39-94; e-mail: [email protected]
Нижний Новгород ул. Премудрова, д. 31а; тел. (8312) 58-50-15,58-50-25; e-mail: [email protected] Ростов-на-Дону ул. Калитвинская, д. 17в; тел. (8632) 95-36-31, (8632) 95-36-32; e-mail: [email protected] Самара
ул. Новосадовая, д. 4; тел. (8462)37-06-07; e-mail: [email protected]
УКРАИНА
Харьков ул. Энгельса, д. 29а, офис 610; тел. (0572) 23-75-63, (0572) 28-20-04, (0572) 28-20-05, факс (0572) 14-96-09; e-mail: [email protected] Киев пр. Красных Казаков, д. 6, корп. 1; тел./факс (044) 490-35-68,490-35-69; e-mail: [email protected] • Минск Кишинев
БЕЛАРУСЬ
ул. Бобруйская д., 21, офис 3; тел./факс (37517) 226-19-53; e-mail: [email protected]
МОЛДОВА
«Ауратип-Питер»; ул. Митрополит Варлаам, 65, офис 345; тел. (3732) 22-69-52, факс (3732) 27-24-82; e-mail: [email protected] '
Ищем зарубежных партнеров или посредников, имеющих выход на зарубежный рынок. Телефон для связи: (812) 103-73-73. E-mail: [email protected] Издательский дом «Питер» приглашает к сотрудничеству авторов. Обращайтесь по телефонам: Санкт-Петербург - (812) 103-73-72, Москва - (095) 777-54-67. Заказ книг для вузов и библиотек: (812) 103-73-73. Специальное предложение - e-mail: [email protected]
пзалтЕпьскпп аом WWW.PITER.COM
Башкортостан
Уфа, «Азия», ул. Зенцова, д. 70 (оптовая продажа), маг. «Оазис», ул. Чернышевского, д. 88, тел./факс (3472) 50-39-00. E-mail: [email protected]
Дальний Восток
Владивосток, «Приморский торговый дом книги», тел./факс (4232) 23-82-12. E-mail: [email protected] Хабаровск, «Мире», тел. (4212) 30-54-47, факс 22-73-30. E-mail: sale_ [email protected] Хабаровск, «Книжный мир», тел. (4212) 32-85-51, факс 32-82-50. E-mail: [email protected]
Европейские регионы России
Архангельск, «Дом книги», тел. (8182) 65-41 -34, факс 65-41 -34. E-mail: [email protected] Калининград, «Вестер», тел./факс (0112) 21-56-28,21-62-07. E-mail: [email protected] http://www.vester.ru
УВАЖАЕМЫЕ ГОСПОДА! КНИГИ ИЗДАТЕЛЬСКОГО ДОМА «ПИТЕР» ВЫ МОЖЕТЕ ПРИОБРЕСТИ ОПТОМ И В РОЗНИЦУ У НАШИХ РЕГИОНАЛЬНЫХ ПАРТНЕРОВ.
Иркутск, «Антей-книга», тел./факс (3952) 33-42-47. E-mail: [email protected] Красноярск, «Книжный мир», тел./факс (3912) 27-39-71. E-mail: [email protected] Нижневартовск, «Дом книги», тел. (3466) 23-27-14, факс 23-59-50. E-mail: [email protected] Новосибирск, «Топ-книга», тел. (3832) 36-10-26, факс 36-10-27. E-mail: [email protected] http://www.top-kniga. ru Тюмень, «Друг», тел./факс (3452) 21-34-82. E-mail: [email protected] Тюмень, «Фолиант», тел. (3452) 27-36-06, факс 27-36-11. E-mail: [email protected] Челябинск, ТД «Эврика», ул. Барбюса, д. 61, тел./факс (3512) 52-49-23. E-mail:[email protected]
Ростов-на-Дону, ПБОЮЛ Остроменский, пр. Соколова, д. 73, тел./факс (8632) 32-18-20. E-mail: [email protected]
Татарстан
Северный Кавказ
Урал
Ессентуки, «Россы», ул. Октябрьская, 424, тел./факс (87934) 6-93-09. E-mail: [email protected] Сибирь
Иркутск, «ПродаЛитЪ», тел. (3952) 59-13-70, факс 51-30-70. E-mail: [email protected] http://www.prodalit.irk.ru
Казань,«Таис», тел. (8432) 72-34-55, факс 72-27-82. E-mail: [email protected] Екатеринбург, магазин № 14, ул. Челюскинцев, д. 23, тел./факс (3432) 53-24-90. E-mail: [email protected] Екатеринбург, «Валео-книга», ул. Ключевская, д. 5, тел./факс (3432) 42-56-00. E-mail: [email protected]
•
' ,
' *
.
'
.
'
/
<
• ' Понамарев Вячеслав Александрович
Базы данных в Delphi 7. Самоучитель Главный редактор Заведующий редакцией Ведущий проекта Литературные редакторы Художник Корректоры Верстка
Е. Строганова И. Корнеев А. Васильев Е. Васильев. Е. Вауяина М. Сахалинская Н. Лукина, И. Тимофеева А. Круглова
•'
• • Лицензия ИД №05784 от 07.09.01.
Подписано к печати 03.03.03. Формат 70x100/16. Усл. п. л. 18,06. Доп. тираж 4500. Заказ 95 ООО «Питер Принт», 196105, Санкт-Петербург, ул. Благодатная, д. 67в. Налоговая льгота — общероссийский классификатор продукции ОК 005-93, том 2; 95 3005 — литература учебная. Отпечатано с готовых диапозитивов в ФГУП ордена Трудового Красного Знамени «Техническая книга» Министерства РФ по делам печати, телерадиовещания и средств массовых коммуникаций. 198005, Санкт-Петербург, Измайловский пр., 29.