    17 ГЛАВА 
    InterBase 

    В этой главе в общих чертах рассматривается система управления 
реляционными базами данных InterBase. Здесь обсуждается диалект языка SQL СУБД 
InterBase, а также вопросы совместного использования InterBase и Delphi. Будут 
также рассмотрены основные операции по управлению базами данных на серверах 
InterBase. Итак, маршрут нашего путешествия определен. Начнем с запуска сервера. 

    Запуск сервера 

    Метод запуска сервера InterBase в значительной степени варьируется от 
платформы к платформе. Здесь будет рассмотрен запуск сервера в системах 
Windows 95 и Windows NT. Для запуска сервера InterBase в других операционных 
системах следует обращаться к документации по данной СУБД. 
    Обычно InterBase устанавливается так, чтобы автоматически запускаться при 
вместе с Windows. Если же это не так, то для запуска сервера достаточно 
выбрать пункт InterBase Server 4.2 из папки InterBase 4.2 (щелкнуть на 
пиктограмме InterBase Server 4.2 в группе InterBase Server 4.2 системы Windows 
NT 3.51). Когда сервер активен, его пиктограмма отображается на панели задач 
Windows 95 или Windows NT (в Windows NT 3.51 это будет пиктограмма 
минимизированного диспетчера программ). 
    Для просмотра и изменения основных параметров сервера можно щелкнуть 
правой кнопкой мыши на пиктограмме панели задач. Сервер можно настроить, 
например, на автоматический запуск при каждом запуске Windows, выбрав из 
всплывающего меню пункт Startup Configuration. Выбрав пункт Properties, можно 
увидеть значения максимально допустимого и текущего количества подключений к 
серверу. Наконец, выбрав из всплывающего меню пункт Shutdown, можно завершить 
работу сервера. 

    Подключение к серверу 

    В отличие от серверов, рассмотренных до сих пор, сервер InterBase не 
требует для подключения к базе данных специально определенных элементов. 
Фактически, при подключении к локальному серверу InterBase клиентные программы 
(WISQL, BDE и т.д.) могут обращаться непосредственно к нужной базе данных. В 
посредничестве сервера нет никакой необходимости. 
    При подключении к удаленному серверу информация, которая требуется для 
установления связи, варьируется в зависимости от используемого протокола. Так, 
если используется протокол TCP/IP, то файл HOSTS должен содержать TCP/IP-адрес сервера: 

    100.10.15.12     marketing 

    Необходимо также добавить в файл определения параметров TCP/IP SERVICES 
строку, определяющую протокол доступа к InterBase: 

    gds_db  3050/tcp 

    При установке InterBase это делается автоматически (хотя впоследствии эту 
строку можно добавить самостоятельно). После настройки протокола TCP/IP можно 
обращаться к серверу с помощью утилиты 

    Глава 17. InterBase 343 

    WISQL и других программ из комплекта поставки InterBase. Обратите 
внимание, что эти пункты в упомянутых файлах являются необходимыми только для 
TCP/IP — для протоколов NetBEUI и IPX/SPX такие требования отсутствуют. 

    Настройка псевдонима ВОЕ 

    После настройки параметров подключения к серверу баз данных наступает 
очередь создания псевдонима BDE для обращения к серверу из приложений Delphi. 
Эта тема освещается в главе 9, однако здесь приводится ее краткий обзор — для 
удобства и для раскрытия взаимосвязи между настройкой драйверов баз данных и 
настройкой псевдонимов BDE. 
    Псевдонимы BDE создаются либо с помощью утилиты BDE Administrator, либо с 
помощью приложения Delphi Database Explorer. Приведенные ниже инструкции 
относятся к программе BDE Administrator. 
    1.   Запустите утилиту BDE Administrator, щелкните правой кнопкой на 
вкладке Databases и выберите из меню пункт New. После появления диалогового 
окна New Database Alias выберите в раскрывающемся списке Database Driver Name 
пункт INTRBASE и щелкните на кнопке ОК. 
    2.    После добавления нового псевдонима введите его имя. 
    3.    Настройте параметры нового псевдонима на вкладке Definition. 
    4.    Щелкните на параметре SERVER NAME и установите его значение равным 
имени нужного сервера и файла базы данных. По умолчанию этот файл имеет 
расширение GDB. Введенная строка должна выглядеть примерно следующим образом: 

    MIS:/data/interbase/accounting.gdb 

    где MIS — имя сервера, a /data/interbase/accounting.gdb — полный путь к 
файлу, содержащему базу данных. 
    При подключении к локальному серверу InterBase его имя в поле SERVER NAME 
можно не указывать. Вместо этого достаточно указать полный путь к файлу базы 
данных: с: \DATA\INTERBASE\ACCOUNT . GDB. 
    5.    По желанию можно указать в качестве значения параметра USER NAME имя 
пользователя сервера, автоматически регистрируемого на сервере по умолчанию. 
Введенное имя будет отображаться по умолчанию при каждом появлении встроенного 
диалогового окна регистрации Delphi. 
    В данном окне можно устанавливать еще ряд параметров. Один из них для 
псевдонимов InterBase следует устанавливать всегда. Это параметр ENABLE BCD, 
значение которого влияет на способ обработки определенных типов числовых 
данных. Несмотря на его название, его действие не ограничивается только 
десятичными числами в двоичном коде (Binary-Coded Decimal — BCD) — он влиет 
также на обработку данных с плавающей точкой типа DECIMAL и NUMERIC. Если 
параметр ENABLE BCD имеет значение FALSE (по умолчанию), то поля типа DECIMAL 
и NUMERIC будут обрабатываться в Delphi как целочисленные, и средства контроля 
типов данных не будут допускать ввод дробных чисел. Это вряд ли можно назвать 
удобным, поэтому следует установить значение параметра ENABLE BCD равным TRUE. 
    Для сохранения изменений и выхода из программы BDE Administrator щелкните 
на кнопке Apply. 

    Устранение проблем при подключении к серверу InterBase 

    Если при попытке подключения к серверу InterBase из приложения Delphi 
возникают проблемы, попробуйте проделать следующее. 
    1.    Используйте для подключения к серверу утилиту InterBase 
Communication Diagnostics, находящуюся в папке InterBase 4.2. Вначале 
попробуйте проверить связь с сервером с помощи кнопки Test, находящейся на 
вкладке DB Connection. Если связь устанавливается, вероятно, имеется ошибка в 
конфигурации псевдонима BDE. Вернитесь к программе BDE Administrator и 
проверьте параметры псевдонима. Если с помощью вкладки DB Connection 
подключиться к базе данных не удается, откройте вкладку NetBEUI или Winsock и 
испробуйте кнопки Test на этих вкладках. Если какая-либо из этих кнопок 
сработала, значит имеются ошибки в спецификациях. Если же не сработал ни один 
из этих способов, то можно попытаться проделать следующее. 

    344	Часть III. Справочные материалы 

    2.   Свяжитесь с сервером с помощью утилиты InterBase WISQL. Если это 
возможно, а связь из приложения Delphi по-прежнему не работает, то, вероятно, 
имеется ошибка в конфигурации псевдонима BDE. Вернитесь к программе BDE 
Administrator и проверьте значения параметров (в частности, имя сервера). 
    3.    Если с помощью утилиты InterBase WISQL соединение установить нельзя, 
то возможна проблема с протоколом. Если для подключения используется протокол 
TCP/IP, то попытайтесь вызвать главный компьютер через утилиту PING, 
поставляемую вместе с системами Windows 95 и Windows NT. Для вызова 
используйте как имя компьютера, указанное в файле HOSTS, так и его IP-адрес. 
    4.    Если для подключения к серверу Windows NT используются поименованные 
каналы, то воспользуйтесь командой net view \\имя_сервера, где идентификатор 
имя_сервера — это имя сервера Windows NT, на котором работает сервер SQL. Если 
эта команда выполняется успешно, то используйте команду netuse 
\\имя_сервера\1РС$, заменив идентификатор имя_сервера настоящим именем 
сервера. Если этот тест не сработал, то по сети связаться с сервером нельзя. 
Проконсультируйтесь с системным администратором Windows NT. Возможно, на 
сервере имеются неполадки в службах поименованных каналов. 
    5.    Если обращение к компьютеру через утилиту PING по IP-адресу 
происходит корректно, а по имени — нет, то проблема, вероятно, связана с 
файлом HOSTS. Для восстановления связи с сервером необходимо решить проблему с 
файлом HOSTS, поскольку программное обеспечение клиентов InterBase использует 
для связи именно этот файл. Для каждого сервера файл HOSTS должен содержать 
строку наподобие следующей: 

    100.10.15.12     marketing 

    Если обращение к компьютеру через утилиту PING по IP-адресу происходит 
корректно, а по имени — нет, то скорее всего его имя либо пропущено в файле 
HOSTS, либо соответствует другому IP-адресу. В любом из этих случаев для 
решения проблемы достаточно внести исправления в файл HOSTS. 
    6.    Если главный компьютер не вызывается с помощью утилиты PING ни по 
имени, ни по IP-адресу, то возможна неполадка в сети. Необходимо проверить 
такие очевидные вещи, как правильность IP-адреса сервера. Попробуйте 
обратиться по фиктивному зацикливающему адресу TCP/IP, 127.0.0.1, чтобы 
проверить правильность работы стека TCP/IP. Этот адрес предназначен для 
эмуляции вызова компьютера из сети. Если такой вызов не срабатывает, то в 
конфигурации протокола имеются серьезные ошибки. Для их устранения необходимо 
проконсультироваться с администратором сети. 
    7.    Если связь через утилиту WISQL не срабатывает, а через PING — 
срабатывает, то попытайтесь связаться с сервером с помощью утилиты TELNET, 
поставляемой в составе Windows 95 и Windows NT. Соответствующая команда имеет 
следующий синтаксис: 

    TELNET 100.100.100.100 

    ИЛИ 

    TELNET имя 

    где 100.100.100.100— TCP/IP-адрес главного компьютера, а имя— его имя. 
Если связь через TELNET не работает, то возможна проблема с фоновым процессом 
inet на сервере. 
    8.    Если TELNET срабатывает, a WISQL по-прежнему нет, то в первую 
очередь следует проверить правильность установки программного обеспечения 
сервера InterBase на главном компьютере. Во-вторых, следует проверить наличие 
соответствующей строки в файле параметров TCP/IP SERVICES, которая должна 
выглядеть примерно так: 

    gds_db  3050/tcp 

    9.    Если все эти меры не привели к решению проблемы, то следует 
обратиться к администратору сети или базы данных. 

    Азы SQL 

    Основное средство, которое программисты используют для связи с серверами 
баз данных — это язык SQL. В этом ра:деле дается краткое введение в богатый 
диалект языка SQL СУБД InterBase и рассматриваются некоторые черты, отличающие 
его от других реализаций SQL. При этом предполагается, что сервер 
функционирует, и связь с ним через утилиту InterBase WISQL происходит корректно. 

    Глава 17. InterBase 345 

    Создание базы данных 

    У вас уже, наверное, есть база данных, содержащая несколько временных 
таблиц для работы с примерами этой главы. Если нет, то такую базу данных 
нетрудно создать. В SQL база данных создается командой CREATE DATABASE. Точный 
синтаксис команды зависит от конкретной СУБД. Вот базовый синтаксис InterBase: 

    CREATE   DATABASE   'C:\DATA\IB\SALES'   USER   SYSDBA PASSWORD masterkey; 

    Утилита InterBase WISQL не может непосредственно выполнить эту команду, 
поэтому вместо нее используется пункт Create Database меню File. Для создания 
базы данных с использованием утилиты WISQL выполните следующее. 
    1.   Запустите программу Interactive SQL (WISQL) из программной группы 
InterBase или из меню Task программы InterBase Service Manager. 
    2.    Выберите пункт Create Database из меню File. 
    3.    Введите полный путь к создаваемой базе данных (например, 
C:\DATA\IB\SALES.GDB) в строке Database диалогового окна Create Database. Если 
вы хотите разместить базу данных в новом каталоге, его нужно создать заранее, 
до создания самой базы данных. 
    4.    Введите имя пользователя и пароль. По умолчанию используется имя 
SYSDBA и пароль masterkey. 
    5.    Щелкните на кнопке ОК. В результате будет создана база данных и 
произойдет подключение к ней. Для подключения к уже существующей базе данных 
используется пункт Connect to Database меню File. 
    В области ввода Database Options диалогового окна Create Database можно 
устанавливать ряд специальных параметров, например, размер страницы базы 
данных в байтах. По умолчанию предусмотрен размер 1024 байта (1 Кбайт), но его 
можно изменить на 2048, 4096 или 8192 (т.е. указать, например, 
PAGE_SIZE=2048). Кроме основного файла базы данных, можно создать также 
дополнительные файлы, указав для них начальную длину так же, как для основного файла. 
    Хотя утилита WISQL не поддерживает выполнение команды CREATE DATABASE, эту 
команду поддерживает ее аналог— утилита командной строки ISQL. С помощью 
утилиты ISQL можно выполнять целый ряд команд, доступных в WISQL только из 
меню. Программу ISQL можно найти в каталоге С: \Program Files\Borland\ IntrBaseXBin. 

    Отображения 

    В InterBase имеется специальный тип объектов — отображения (shadows), с 
помощью которых можно отображать базы данных на другие логические диски. 
Благодаря этому ослабляются негативные последствия фатального повреждения базы 
данных или отказа диска, на котором она находится. 
    Отображения создаются с помощью команды CREATE SHADOW после подключения к 
базе данных. Вот синтаксис этой команды: 

    CREATE  SHADOW  I   "sales.shd"   LENGTH  5000; 

    Первым параметром команды должен быть уникальный номер отображения. Если 
номер отсутствует или совпадает с уже существующим, то отображение не создается. 
    Поскольку отображение является точной копией ассоциированной с ним базы 
данных, каждая модификация исходной базы требует двойного количества операций 
записи. Поэтому, если поместить отображение на диск с низкой скоростью записи, 
то производительность всей системы значительно снизится. 
    В команде CREATE SHADOW допускается специальный параметр для указания 
действий, которые должны предприниматься при недоступности отображения по 
какой-либо причине. Параметр AUTO означает, что клиентные приложения должны 
продолжать работу, а отображение следует просто уничтожить. Параметр MANUAL 
означает, что все обращения клиентов к базе данных должны блокироваться до тех 
пор, пока отображение не станет доступным или пока оно не будет отключено от 
базы данных командой DROP SHADOW. Параметр CONDITIONAL означает, что 
подключения должны функционировать по-прежнему, но 

    346 Часть III. Справочные материалы 

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

    CREATE   SHADOW   I   CONDITIONAL   "d:\shadows\sales.shd" LENGTH  5000; 


    Команда CONNECT 

    Команда InterBase CONNECT используется для подключения к существующей базе 
данных. Она имеет следующий синтаксис: 

    CONNECT  путь_к__серверу_и_БД USER   "имя__польз" PASSWORD   "пароль_польз" 

    Замените идентификатор путь_к_серверу__и_БД полным путем к серверу и файлу 
базы данных. Если производится подключение к локальному серверу, то путь к 
серверу можно опустить. Вот пример команды подключения к локальному серверу: 

    CONNECT "C:\DATA\IB\SALES.GDB" USER "SYSDA" PASSWORD "masterkey"; 

    Для принудительного прерывания связи с сервером, установленной командой 
CONNECT, используется команда DISCONNECT. 

    DISCONNECT ALL; 

    Слово ALL можно с тем же успехом заменить словом DEFAULT. В программе 
WISQL, в которой команды CONNECT и DISCONNECT не работают (хотя работают в 
программе ISQL), для подключения к серверу и отключения от него используются 
пункты Connect to Database и Disconnect from Database меню File. 

    Создание таблиц 

    После создания базы данных можно приступать к созданию ее объектов. 
Практически все основные понятия реляционных баз данных можно 
продемонстрировать на примере набора из трех таблиц. Для работы с примерами 
этой главы начните с создания трех таблиц, приведенных ниже. Таблицы создаются 
оператором SQL CREATE TABLE. Для создания таблицы CUSTOMER введите в области 
ввода операторов SQL утилиты WISQL следующую команду. 

    CREATE TABLE CUSTOMER 
    ( 
    CustomerNumber        int       NOT NULL, 
    LastName	char(30), 
    FirstName	char(30), 
    StreetAddress         char(30), 
    City	char(20), 
    State	char(2), 
    Zip	char(10) 
    ) 

    Затем с помощью следующей команды создайте таблицу SALE. 

    CREATE TABLE SALE 
    ( 
    SaleNumber      int       NOT NULL, 
    SaleDate        date, 
    CustomerNumber   int    NOT NULL, 
    ItemNumber      int    NOT NULL, 
    Amount	float 
    ) 

    Последняя таблица, ITEM, создается следующей командой. 

    CREATE TABLE ITEM 
    ( 
    ItemNumber	int                 NOT  NULL, 

    Глава 17. InterBase	347 

    Description  char (30), Price        float ) 

    Внешние таблицы 

    В СУБД InterBase для команды CREATE TABLE предусмотрены некоторые 
интересные модификации. В частности, таблицы можно создавать вне баз данных, 
например, следующим образом. 

    CREATE TABLE SALE_HISTORY EXTERNAL FILE 
    'С:\DATA\IB\SALEHIST.DAT' 
    ( 
    SaleNumber     int    NOT NULL, 
    SaleDate      date, 
    CustomerNumber int   NOT NULL, 
    ItemNumber     int    NOT NULL, 
    Amount        float 
    ) 

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

    Столбцы с вычисляемыми значениями 

    Одной из особенностей команды CREATE TABLE в InterBase является 
возможность создания столбцов с вычисляемыми значениями (computed column). 
Ниже приведена модификация таблицы ITEM, содержащая столбец с вычисляемым 
значением государственной цены. 

    CREATE   TABLE   ITEM ( 
    ItemNumber	int                 NOT  NULL, Description               char 
(30), Price                              float, 
    GovernmentPrice   COMPUTED  BY   (Price   -   Price   *   .15) ) 

    В приведенном примере столбец GovernmentPrice содержит цену со скидкой 15% 
для государственных учреждений. Поскольку тип данных для этого столбца не 
указан, используется тип данных столбца, по которому производятся вычисления. 
Стобцы, используемые в вычислениях, должны стоять в списке столбоцов оператора 
CREATE TABLE раньше, чем столбцы с вычисляемыми значениями. 
    Возможность создания столбцов с вычисляемыми значениями напоминает 
реализацию операций над столбцами в запросах или операторе SELECT, но в 
отличие от них предусматривает вычисления прямо в определении таблицы. Это 
более эффективный метод реализации бизнес-правил, поскольку приложения-клиенты 
и другие объекты SQL могут непосредственно обращаться с запросами к таким 
столбцам без затрат времени на дополнительные вычисления. 

    Столбцы массивов 

    Кроме столбцов с простыми типами данных, в диалекте SQL СУБД InterBase 
можно определять столбцы, содержащие массивы данных различных типов. В таких 
столбцах можно помещать элементы данных, которые образуют группу или 
множество. Вот вариант таблицы CUSTOMER, содержащий столбец массива: 

    CREATE TABLE CUSTOMERARRAY 
    ( 
    CustomerNumber        int       NOT NULL, 
    LastName	char(30), 
    FirstName	char(30), 
    StreetAddress         char(30)[3], 
    City	char (20), 
    State	char(2), 
    Zip	char(10) 
    ) 

    348	Часть III. Справочные материалы 

    Обратите внимание на модификатор [3] справа от определения столбца 
StreetAddress. Данный столбец является массивом, содержащим три элемента типа 
char (30). Его можно использовать, например, для хранения сразу нескольких 
адресов одного клиента. 
    Для столбцов массивов можно явно задать значения максимального и 
минимального индексов. Вот пример: 

    CREATE TABLE CUSTOMERARRAY 
    ( 
    CustomerNumber        int       NOT NULL, 
    LastName	char(30), 
    FirstName	char(30), 
    StreetAddress         char(30)[1:3], 
    City	char(20), 
    State	char(2), 
    Zip	char(10) 
    ) 

    В данном случае столбец StreetAddress — это одномерный массив из трех 
элементов, пронумерованных от 1 (вместо 0 по умолчанию) до 3 (вместо 2). 
    Столбцы могут содержать и многомерные массивы (до 16 измерений). Вот 
пример такого массива: 

    CREATE TABLE HOURLY_SAMPLES 
    ( 
    SampleNo	int      NOT NULL, 
    SampleDate         date     NOT NULL, 
    WeeklySampleValues  int[7,24] 
    ) 

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

    Предупреждение 
    Прежде чем начать широко использовать массивы в базе данных, необходимо 
учесть следующее. Столбцы массивов — это повторяющиеся группы. С точки зрения 
нормализации реляционной базы данных применение таких столбцов не 
соответствует требованиям первой нормальной формы. Для их обработки требуются 
дополнительные операции, в частности, по форматированию отчетов и выполнению 
запросов. Кроме того, в языке SQL нельзя выполнить присваивание значений 
столбцу массива. Для столбцов массивов существуют дополнительные ограничения, 
которые не применяются к другим типам данных (например, их нельзя передавать и 
возвращать из хранимых процедур). Поэтому, прежде чем включать массивы в 
структуру базы данных, необходимо тщательно взвесить все "за" и "против". 

    Специальные используемые по умолчанию значения столбцов 

    Кроме констант, в InterBase для задания значений используемых по умолчанию 
значений столбцов можно применять три специальных ключевых слова: USER, TODAY 
и NOW. С помощью параметра USER столбцу назначается значение, равное имени 
текущего пользователя, с помощью параметра TODAY — значение текущей даты 
(аналог функции Delphi DATE), а параметра NOW — текущей даты и времени (аналог 
функции Delphi NOW). Вот пример использования всех трех ключевых слов. 

    CREATE  TABLE  REPORTLOG (ReportUser  varchar(20)   DEFAULT  USER, 
    ReportDate  date   DEFAULT   "TODAY", 
    ReportDateTime  date   DEFAULT   "NOW") 

    Обратите внимание, что слова "TODAY" и "NOW" должны быть заключены в 
кавычки, тогда как слово USER не должно. Если заключить его в кавычки, то 
вместо имени пользователя для столбца будет назначено используемое по 
умолчанию значение в виде строковой константы "USER". 

    Глава 17. InterBase	349 

    Добавление и удаление столбцов таблицы 

    Для добавления и модифицирования столбцов существующей таблицы 
используется команда SQL ALTER TABLE. Далеко не все серверы поддерживают 
модификацию столбцов после создания таблицы (например, поддержка такой 
модификации отсутствует в Microsoft SQL Server), однако это не относится к 
СУБД InterBase. Для добавления столбца используется следующая синтаксическая конструкция. 

    ALTER TABLE CUSTOMER 
    ADD (PhoneNumber char (10)) 

    Удаление столбцов выполняется следующей командой. 

    ALTER TABLE CUSTOMER DROP PhoneNumber 

    Следует заметить, что столбец со значениями NOT NULL нельзя добавить в 
таблицу, в которой уже есть строки, поскольку после добавления столбца его 
элементам автоматически присваиваются значения NULL. 
    
    Ограничения 

    Ограничением (constraint) называется механизм определения допустимых типов 
данных данного столбца. С помощью ограничений можно задавать значения для 
полей по умолчанию. Ограничения могут налагаться при создании таблицы с 
помощью команды CREATE TABLE или впоследствии, с помощью команды ALTER TABLE. 
Вот пример ограничения первичного ключа: 

    ALTER  TABLE  CUSTOMER 
    ADD   PRIMARY  KEY   (CustomerNumber) 

    Приведенная команда добавляет в таблицу CUSTOMER ограничение первичного 
ключа, назначая первичным ключом таблицы столбец CustomerNumber. В результате 
для таблицы создается уникальный индекс, использующий в качестве ключа столбец 
CustomerNumber. Обратите внимание, что в качестве первичного ключа нельзя 
использовать столбец, допускающий использование значения NULL. 
    Ограничение внешнего ключа определяет столбец одной таблицы, значения 
которого должны существовать во второй таблице, которая называется внешней. В 
отличие от первичного ключа, внешний ключ не является уникальным индексом 
строки. Наоборот, ключевые столбцы должны быть первичными (уникальными) 
ключами во внешней таблице. Добавление в таблицу ограничения внешнего ключа 
приводит к автоматическому созданию вторичного индекса по ключевым столбцам. 
Вот пример соответствующей команды: 

    ALTER   TABLE   SALE 
    ADD  FOREIGN  KEY   (CustomerNumber)   REFERENCES   CUSTOMER 

    Это ограничение назначает столбец CustomerNumber таблицы SALE внешним 
ключом, который ссылается на аналогичный столбец таблицы CUSTOMER. Это 
означает, что введенные в таблицу SALE номера покупателей должны существовать 
в таблице CUSTOMER, а также то, что номера, использующиеся в таблице SALE, 
нельзя удалить из таблицы CUSTOMER. Такая возможность закрепления связи между 
двумя таблицами путем ее изначального определения называется декларативной 
ссылочной целостностью (declarative referential integrity). Этот термин 
означает, что обеспечение целостности ссылок таблиц друг на друга выполняется 
при их создании или объявлении на уровне сервера базы данных, а не на уровне приложения. 
    Третьим типом ограничений является сравнение значений столбца со списком 
предварительно определенных значений. Вот пример задания такого ограничения: 

    ALTER TABLE CUSTOMER 
    ADD CONSTRAINT INVALID_STATE CHECK (State in ('OK', 'AR', 'MO')) 

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

    350	Часть III. Справочные материалы 

    Тестирование ограничений 

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

    INSERT  INTO CUSTOMER   (CustomerNumber,   State) VALUES    (123,'CA') 

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

    Создание индексов 

    Индексы в языке SQL СУБД InterBase создаются командой CREATE INDEX. Вот ее 
базовый синтаксис: 

    CREATE   INDEX  SALE02   ON   SALE   (SaleDate) 

    Здесь SALE02 — имя нового индекса, SALE — имя таблицы, по которой строится 
индекс, a SaleDate — ключ индекса. Обратите внимание на то, что имена индексов 
InterBase должны быть уникальны по всей базе данных, в которой они располагаются. 
    С помощью варианта данной команды CREATE UNIQUE INDEX создается индекс, не 
допускающий повторений: 

    CREATE  UNIQUE   INDEX  SALE01   ON   SALE   (SaleNumber) 

    Ключи индекса по умолчанию выстраиваются в порядке возрастания, но в 
InterBase поддерживаются ииндексы в порядке убывания. Для этого используется 
ключевое слово DESCENDING: 

    CREATE DESCENDING INDEX SALE03 ON SALE (Amount) 

    Благодаря этому быстрее выполняются такие запросы, как, например, 
приведенный ниже: 

    SELECT * FROM SALE 
    ORDER BY Amount DESCENDING 


    Подключение и отключение индексов 

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

    ALTER INDEX SALE02 INACTIVE 

    Для повторного создания индекса используется следующая команда. 

    ALTER INDEX SALE02 ACTIVE 

    Как уже отмечалось, при подключении индекса он строится заново. Обратите 
внимание, что операция отключения откладывается до тех пор, пока не 
прекратится использование индекса — в том числе использование ограничения 
первичного или внешнего ключа. Чтобы отключить индекс, используемый 
ограничением, вначале необходимо снять это ограничение. 

    Вставка данных 

    Оператор SQL INSERT используется для добавления данных в таблицу 
InterBase. С помощью ключевого слова VALUES оператора INSERT можно вставить 
одну строку; если же выбрать несколько строк из другой таблицы, то можно 
вставить все эти строки одновременно. Для добавления данных в каждую из трех 
имеющихся у нас таблиц используются команды, приведенные ниже. Вначале 
вставляются три строки в таблицу CUSTOMER (команды вводятся и выполняются в 
окне утилиты WISQL по одной). 

    Глава 17. InterBase	351 


    INSERT INTO CUSTOMER (CustomerNumber, LastName, FirstName, StreetAddress, 

City, State, Zip) VALUES(1,'Doe','John','123 SunnyLane','Anywhere', 'MO','73115') 

    INSERT INTO CUSTOMER (CustomerNumber, LastName, FirstName, StreetAddress, 
City, State, Zip) VALUES(2,'Doe','Jane','123 SunnyLane','Anywhere', 'MO', 
'73115' ) 

    INSERT INTO CUSTOMER (CustomerNumber, LastName, FirstName, StreetAddress, 
City, State, Zip) VALUES(3,'Philgates','Buck','57 Riverside','Reo',	| 'AR' , 
'65803' )                                                                      
    ; 
    i После этого добавляются три строки в таблицу ITEM. 

    INSERT INTO ITEM (ItemNumber, Description, Price) 
    VALUES(1001, 'Zoso LP',13.45) 

    INSERT INTO ITEM (ItemNumber, Description, Price) 
    VALUES(1002,'White LP',67.90) 

    INSERT INTO ITEM (ItemNumber, Description, Price) 
    VALUES(1003,'Bad Co. LP',11.45) 

    Наконец, добавляются четыре строки в таблицу SALE.	, 

    INSERT INTO SALE (SaleNumber, SaleDate, CustomerNumber, 
    ItemNumber, Amount) 

    VALUES(101, 40/18/90',1,1001,13.45)	: 
    INSERT INTO SALE (SaleNumber, SaleDate, CustomerNumber, 
    ItemNumber, Amount) 
    VALUES(102,'02/27/92',2,1002,67.90)	I 

    INSERT INTO SALE (SaleNumber, SaleDate, CustomerNumber,	j 
    ItemNumber, Amount) 
    VALUES(103, '05/20/95',3,1003,11.45) 

    INSERT INTO SALE (SaleNumber, SaleDate, CustomerNumber, 
    ItemNumber, Amount) 
    VALUES(104,'11/27/97',1,1002,67.90) 

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

    INSERT INTO ITEM (Price, ItemNumber) VALUES(13.45,1001) 


    Специальные значения 

    Как и при создании столбцов, при добавлении строк можно использовать 
специальные используемые по умолчанию значения USER, TODAY и NOW. 

    INSERT INTO REPORTLOG VALUES(USER, "TODAY", "NOW")	I 


    Команда UPDATE 

    Команда SQL UPDATE используется для изменения данных, которые уже 
находятся в таблице. Оператор UPDATE может содержать ключевое слово WHERE, 
который определяет, какие именно строки следует модифицировать. Вот синтаксис 
этой команды: 

    UPDATE CUSTOMER SET Zip='65803' WHERE' City='SpringField' 

    Наличие ключевого слова WHERE в операторе UPDATE может привести к тому, 
что в таблице будет изменена, например, всего одна строка; в этом случае для 
изменения всех строк таблицы достаточно убрать ключевое слово WHERE. 

    UPDATE CUSTOMER SET State='MO' 

    352	Часть III. Справочные материалы 

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

    UPDATE ITEM 
    SET Price=Price+(Price*.07) 

    Как и в команде INSERT, в операторе UPDATE можно использовать специальные 
используемые по умолчанию значения столбцов USER, TODAY и NOW. 

    UPDATE   SALE 
    SET Amount=Amount-(Amount*.25) 
    WHERE SaleDate >= "TODAY"-30 

    В этой команде для наложения условий на модифицируемые строки используется 
константа TODAY. С ее помощью определяются продажи, произведенные не раньше, 
чем 30 дней назад. 

    Команда DELETE 

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

    DELETE FROM CUSTOMER 

    Команда DELETE может содержать ключевое слово WHERE для отбора отдельных строк. 

    DELETE FROM CUSTOMER WHERE LastNameO'Doe' 


    Управление транзакциями 

    Транзакцией (transaction) называется группа изменений в базе данных. 
Пользовательские транзакции инициируются командой SET TRANSACTION. Изменения 
данных, произошедшие в ходе транзакции, записываются в базе данных с помощью 
команды COMMIT, а отменяются командой ROLLBACK. Обе эти команды применяются 
только к изменениям, внесенным в базу данных после последней команды COMMIT; 
все сделанные до этого изменения отменить нельзя. 
    Утилита InterBase WISQL автоматически инициирует транзакцию (выполняя 
эквивалент команды SET TRANSACTION) сразу после ее запуска. При выходе из 
программы пользователя спрашивают, нужно ли сохранить в базе данных сделанные 
изменения. Сохранить или отменить изменения можно в любой момент с помощью 
команд Commit Work и Rollback Work меню File. 

    На заметку 
    Кроме обычной модификации данных, в транзакции InterBase могут включаться 
также операторы языка Data Definition Language (DDL). Эти операторы служат для 
объявления и создания объектов баз данных, например, таблиц и индексов. Если 
объект базы данных создается в ходе транзакции, а затем транзакция отменяется, 
то объект автоматически удаляется. Изменение немедленно распространяется на 
всю базу данных и имеет более высокий приоритет, чем любой действующий уровень 
разграничения транзакций (Transaction Isolation Level — TIL). 

    Команда SELECT 

    По команде SQL SELECT отображается содержимое таблицы. Для примера давайте 
просмотрим содержимое трех таблиц, созданных в этой главе, с использованием 
этого оператора. Введите для каждой таблицы команду SELECT * FROM имя_таблицы, 
заменив имя_таблицы на фактическое имя (т.е. на CUSTOMER, SALE или ITEM), К 
настоящему моменту в каждой из трех таблиц должно быть по крайней мере по три 
строки. Проверьте это с помощью оператора SELECT. 
    По команде SELECT * выводятся все столбцы всех строк таблицы. Чтобы 
выбрать отдельные столбцы, замените звездочку на список столбцов, отделенных 
друг от друга запятыми. 

    SELECT  CustomerNumber,   LastName,   State   FROM  CUSTOMER 

    Глава 17. InterBase 353     12 Delphi 3 м системы клиент/сервер 

    Выражения в столбцах 

    Каждый пункт в списке столбцов оператора SELECT может представлять собой 
не просто название столбца, но выражение, включающее арифметические операции, 
константы и функции. Вот пример оператора SELECT, который возвращает записи из 
таблицы SALE с наценкой за доставку товара в $15: 

    SELECT   SaleNumber,SaleDate,Amount+15  AmountPlusShipping FROM  SALE 

    Вычисляемые столбцы 

    Вычисляемые столбцы (aggregate column) — это функции, применяемые для 
выполнения каких-то вычислений над некоторым набором данных. Примерами 
вычисляемых столбцов могут служить функции COUNT, SUM, AVG, MIN и MAX. Вот 
некоторые примеры их использования. Следующий запрос подсчитывает количество 
покупателей, внесенных в таблицу. 

    SELECT COUNT(*) FROM CUSTOMER 

    По данному запросу выводится сумма максимальной продажи. 

   SELECT  MAX(Amount)    FROM   SALE 

    А следующий запрос возвращает общую сумму всех продаж. 

    SELECT SUM(Amount) FROM SALE 


    Ключевое слово WHERE 

    Ключевое слово SQL WHERE используется для наложения дополнительных условий 
на данные, выбираемые оператором SELECT. Вот некоторые примеры. Следующий 
оператор возвращает список клиентов, живущих в шт. Миссури (код штата — мо). 

    SELECT * FROM CUSTOMER WHERE State='MO' 

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

    SELECT * FROM CUSTOMER 
    WHERE StreetAddress LIKE '%Sunny%' 

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

    SELECT * FROM SALE WHERE Amount > 500 

    А этот запрос возвращает список только тех продаж, которые имели место с 
18 октября 1990 г. по 20 мая 1995 г. включительно. 

    SELECT * FROM SALE 
    WHERE SaleDate BETWEEN '10/18/90' AND '05/20/95' 


    Объединения 

    Ключевое слово WHERE используется также для объединения одной таблицы с 
другой и образования составных наборов данных. Присоединение одной таблицы к 
другой с помощью ключевого слова WHERE требует двух изменений в базовом 
синтаксисе команды SELECT. Первое изменение состоит в использовании в 
операторе SELECT ключевого слова FROM, с помощью которого указываются 
дополнительные таблицы, а второе — в применении операции сравнения (=) для 
создания выражения, которое с помощью ключевого слова WHERE определяет поля, 
используемые для объединения указанных таблиц. Вот пример: 

    SELECT  CUSTOMER.CustomerNumber,   SALE.Amount 
    FROM  CUSTOMER,    SALE 
    WHERE   CUSTOMER.CustomerNumber=SALE.CustomerNumber 

    354	Часть III. Справочные материалы 

    Обратите внимание на то, что в список, определяемый ключевым словом FROM, 
включена таблица SALE, а также на то, что для объединения таблиц CUSTOMER и 
SALE используется знак равенства между их полями CustomerNumber. Таблицы, 
расположенные слева и справа от знака равенства, называются соответственно 
внешней (outer) и внутренней (inner), или левой и правой таблицами, что 
указывает на их расположение в левом объединении (left join) — самом 
распространенном типе объединений в запросах SQL. 

    Различие между внутренними и внешними объединениями 

    Упомянутые в предыдущем разделе левые объединения известны также под 
названием внутренних объединений (inner join). Внутренние объединения 
возвращают строки таблицы только в том случае, если выполняется условие 
объединения. В противоположность этому, во внешнем объединении (outer join) 
строки возвращаются независимо от выполнения условия, однако если условие не 
выполняется, то столбцы внутренней таблицы имеют значение NULL. 

    ANSI-синтаксис объединений 

    Для левого внутреннего объединения ANSI-синтаксис выглядит следующим образом. 

    SELECT  CUSTOMER.CustomerNumber,   SALE.Amount 
    FROM  CUSTOMER  LEFT   JOIN   SALE 
    ON  CUSTOMER.CustomerNumber=SALE.CustomerNumber 

    Ключевое слово INNER подразумевается по умолчанию. Как уже было показано, 
для определения левого внутреннего объединения в InterBase поддерживается 
также следующий синтаксис. 

    SELECT   CUSTOMER.CustomerNumber,    SALE.Amount 
    FROM   CUSTOMER,    SALE 
    WHERE   CUSTOMER.CustomerNumber=SALE.CustomerNumber 

    Для левого внешнего объединения используется следующий синтаксис. 

    SELECT   CUSTOMER.   CustomerNumber,    SALE.Amount 
    FROM   CUSTOMER   LEFT   OUTER   JOIN   SALE 
    ON  CUSTOMER.CustomerNumber=SALE.CustomerNumber 

    Для создания правых внешних объединений достаточно заменить LEFT на RIGHT. 
Обратите внимание, что правые и левые внутренние объединения — это фактически 
одно и то же, и между ними нет никаких синтаксических различий. 

    Многоуровневые объединения 

    Многоуровневым объединением (multi-tier join) называется объединение, 
включающее более двух таблиц. Таблица А присоединяется к таблице Б, которая в 
свою очередь присоединяется к таблице в. Рассмотрим следующий запрос. 

    SELECT  С.LastName,С.FirstName,I.Description,S.Amount 
    FROM   CUSTOMER   C, 
    SALE   S, 
    ITEM   I 
    WHERE С.CustomerNumber=S.CustomerNumber 
    AND S.ItemNumber=I.ItemNumber 

    В данном запросе таблицы CUSTOMER и SALE объединяются по общему ключу — 
столбцу CustomerNumber. После этого по общему ключу, столбцу ItemNumber, 
объединяются таблицы SALE и ITEM. В результате все три таблицы объединяются в 
один общий набор данных. 

    Самообъединения 

    Помимо объединения с другими таблицами, любая таблица может быть 
объединена сама с собой. Этот тип объединений называется рефлексивным 
(reflexive) или самообъединением (self-join). Рассмотрим следующий запрос. 

    SELECT  S.CustomerNumber,   S.Amount, 
    (S.Amount   /   SUM(S2.Amount))*100   Percentage FROM   SALE   S, SALE   S2 
    WHERE   S.CustomerNumber=S2.CustomerNumber GROUP  BY   S.CustomerNumber,   S.Amount 

    Глава 17. InterBase	355 

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

    Тета-объединения 

    В тета-объединениях (theta join) две таблицы объединяются с использованием 
операций сравнения, отличных от проверки на равенство. Обычно в таких 
объединениях используется операция проверки неравенства (о). Ниже приводится 
пример тета-объединения; это разновидность запроса, использованного выше для 
демонстрации самообъединений. 

    SELECT  С.CustomerNumber,S.Amount,SUM(S2.Amount)   OTHERS 
    FROM  CUSTOMER   C, 
    SALE   S, 
    SALE   S2 
    WHERE   С.CustomerNumber=S.CustomerNumber 
    AND  С.CustomerNumber<>S2.CustomerNumber 
    GROUP  BY  C.CustomerNumber,    S.Amount 

    Фактически данный запрос содержит два объединения. Во-первых, для 
получения всех продаж каждому покупателю объединяются таблицы CUSTOMER и SALE. 
Во-вторых, используется тета-объединение для получения всех продаж, которые не 
связаны с данным покупателем. Поскольку для обращения к одной и той же таблице 
SALE используются два разных типа объединений, для нее введены два разных псевдонима. 

    Полные объединения 

    В полном объединении (full join) строки двух таблиц обрабатываются без 
использования условий, определяемых с помощью ключевого слова WHERE. Это 
объединение применяется для получения данных из таблиц с нестрогими 
взаимосвязями. Если ни одна из таблиц не обязана содержать все строки, которые 
вам нужны, то можно объединить их во внешнее объединение для получения всех 
строк. Вот пример такого объединения. 

    SELECT   DISTINCT   С.CustomerNumber,    S.SaleNumber FROM   CUSTOMER   С  
 FULL   JOIN   SALE   S ON   1=1 


    На заметку 
    В приведенном примере используется заглушка 1=1, поскольку синтаксический 
анализатор InterBase требует во всех объединениях наличия ключевого слова ON 
(даже в полных, где в нем нет необходимости). 

    Декартово произведение 

    Декартово произведение (Cartesian product) — произведение всех строк одной 
таблицы на строки другой таблицы. Возникновение декартова произведения обычно 
возникает по недоразумению, в результате пропуска или неправильного 
использования объединений между таблицами. Вот пример: 

    SELECT   SALE.SaleNumber,   ITEM.ItemNumber 
    FROM  SALE,    ITEM 
    ORDER  BY  SaleNumber,    ItemNumber 

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

    Вложенные запросы 

    Вложенным запросом (subquery) называется оператор SELECT, указанный после 
ключевого слова WHERE другого оператора SELECT. Обычно вложенные запросы 
используются для получения списка данных, по которому затем производится новый 
поиск в таблице. 

    356	Часть III. Справочные материалы 

    ;       SELECT   *   FROM  CUSTOMER 
    1      WHERE  CustomerNumber   IN(SELECT   CustomerNumber   FROM  SALE) 

    Некоторые операторы, такие как ANY, ALL, SOME, EXISTS и SINGULAR, работают 
только во вложенных запросах. Хотя ключевое слово ALL используется также в 
операторе SELECT, как отдельный оператор оно ;.     применяется только во 
вложенных запросах. 

    !   GROUP   BY 

    Поскольку SQL является языком запросов, ориентированным на множества, 
операторы группировки данных являются интегральными элементами. Программисты, 
работающие с другими СУБД, нередко находят такой подход необычным ввиду своей 
привычки работать с данными построчно. Построчный перебор таблицы для 
получения некоторой итоговой информации — довольно распространенный способ 
обработки таблиц локальных СУБД. К счастью, в SQL это не так. 
Один-единственный оператор SQL может делать то же самое, что и 10, а то и 50, 
операторов кода dBASE. "Виновниками" этого являются ключевое слово GROUP BY 
оператора SELECT и вычисляемые столбцы SQL. Вот пример использования ключевого 
слова GROUP BY. 

    SELECT  CUSTOMER.CustomerNumber,   sum(SALE.Amount)   TotalSale 
    FROM  CUSTOMER,    SALE 
    WHERE  CUSTOMER.CustomerNumber=SALE.CustomerNumber 
    GROUP  BY  CUSTOMER.CustomerNumber 

    Данный запрос возвращает список всех покупателей вместе с общим объемом 
продаж каждому покупателю. 
    Как определить, какие столбцы включать в список, определяемый с помощью 
ключевого слова GROUP BY? В диалекте InterBase (и языке SQL стандарта ANSI) 
необходимо группировать строки с помощью ключевого слова GROUP BY по всем 
невычисляемым столбцам, включенным в список столбцов оператора SELECT. 
Использование ключевого слова GROUP BY подразумевает наличие в списке столбцов 
оператора SELECT хотя бы одного вычисляемого столбца — синтаксический 
анализатор InterBase просто не даст вам вставить ключевое слово GROUP BY, если 
такого столбца не будет. 

    HAVING 

    Ключевое слово HAVING оператора SELECT используется для наложения условий 
на строки, возвращаемые при использовании ключевого слова GROUP BY. Результат 
его совместной работы с GROUP BY напоминает результат работы оператора SELECT 
с ключевым словом WHERE, с той разницей, что ключевое слово HAVING выполняет 
те же функции над строками возвращаемого набора данных, а не исходной таблицы. 
    Обычно бывает удобнее налагать условия на строки таблицы, чем на строки 
возвращаемого набора данных. В целом использование ключевого слова HAVING 
менее эффективно, чем ключевого слова WHERE, потому что в первом случае строки 
отбираются после их организации в группы, тогда как во втором — до этого. 
Однако вот один из примеров удачного использования ключевого слова HAVING. 

    SELECT   CUSTOMER.LastName,    COUNT(*)   NumberWithName 
    FROM  CUSTOMER 
    GROUP  BY  CUSTOMER.LastName 
    HAVING  COUNT(*)    >   1 

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

    ORDER   BY 

    Ключевое слово ORDER ВУНгсггользуется для упорядочения строк в 
возвращаемом наборе данных. Вот пример его использования: 
    SELECT * FROM CUSTOMER ORDER BY STATE 

    Глава 17. InterBase	357 

    Псевдонимы столбцов 

    Вы, должно быть, отметили, что для результатов вычисления функций 
наподобие COUNT () и зим () постоянно использовались имена фиктивных столбцов. 
Такие имена называются псевдонимами столбцов (column alias) и предназначены 
для того, чтобы запросы и результаты их выполнения было легче читать. В 
диалекте InterBase SQL псевдоним столбца должен стоять сразу же после 
соответствующего столбца в списке оператора SELECT. Например, в следующем 
запросе для вычисляемого столбца COUNT () используется псевдоним NumberWithName. 

    SELECT  CUSTOMER.LastName,   COUNT(*)   NumberWithName 
    FROM  CUSTOMER 
    GROUP  BY  CUSTOMER.LastName 
    HAVING  COUNT(*)    >   1 

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

    SELECT  CUSTOMER.LastName   LNAME,   COUNT(*)   NumberWithName 
    FROM  CUSTOMER 
    GROUP  BY  CUSTOMER.LastName 

    В возвращаемом наборе данных этого запроса вместо настоящего имени столбца 
LastName подставляется псевдоним LName. Обратите внимание, что псевдонимы 
нельзя применять в других фрагментах запроса, например, в списках ключевых 
слов WHERE и GROUP BY — в них необходимо использовать настоящие имена столбцов. 

    Псевдонимы таблиц 

    Вместо того, чтобы всякий раз в операторе SELECT употреблять полное имя 
таблицы, можно заменить его кратким удобным обозначением по своему выбору. Это 
делается путем указания псевдонима таблицы (table alias) в списке имен таблиц, 
определяемом с помощью ключевого слова FROM оператора SELECT. Псевдоним 
ставится справа от настоящего имени таблицы, как показано в следующем примере. 

    SELECT   С.LastName,   COUNT(*)   NumberWithName FROM   CUSTOMER   С GROUP 
 BY  C.LastName 

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

    Представления 

    Представление (view) таблицы SQL создается с помощью оператора SELECT, 
после чего с полученным набором данных можно обращаться как с таблицей, и, в 
свою очередь, применять к нему операторы SELECT. В некоторых случаях к 
представлению можно применять также операторы INSERT, DELETE и UPDATE. В самом 
представлении не хранится никаких данных — это всего лишь логическая 
конструкция. Представление можно считать маленькой SQL-программой, которая 
выполняется при каждом запросе. Оно похоже на процедуры выбора InterBase, 
обсуждаемые в следующем разделе "Хранимые процедуры". При обращении к 
представлению оптимизатор запросов находит оператор SELECT, используемый для 
создания представления, совмещает его с оператором, применяемым к 
представлению, и оптимизирует оба оператора, рассматривая их как один запрос. 
    Представления SQL создаются с помощью команды CREATE VIEW. Вот пример: 

    CREATE VIEW MOCUSTOMERS AS*V SELECT * FROM CUSTOMER WHERE State='MO' 

    После создания представления к нему можно обращаться с запросами точно так 
же, как к таблице. 

    SELECT * FROM MOCUSTOMERS 


    358                          Часть III. Справочные материалы 


    При выполнении этого запроса обратите внимание, что даже при отсутствии 
ключевого слова WHERE во внешнем операторе SELECT, применяемом к 
представлению, результат выглядит так, будто этот ключевое слово присутствует, 
потому что данное ключевое слово встроено в само представление. 
    Оператор SELECT, который образует представление, может делать практически 
все то же самое, что и обычный оператор SELECT, за одним исключением: он не 
может содержать ключевое слово ORDER BY. Это ограничение существует не только 
в СУБД InterBase, но и в Sybase SQL Server, Microsoft SQL Server и Oracle. 
    При создании модифицируемых представлений на них налагаются дополнительные 
ограничения. Модифицируемое представление InterBase должно удовлетворять 
следующим условиям. 
    Q  Оператор SELECT такого представления может обращаться только к одной 
таблице или к одному модифицируемому представлению. 
    Q  Столбцы базовой таблицы, не включенные в представление, должны 
допускать значения NULL, чтобы представление могло поддерживать команду INSERT. 
    Q  Оператор SELECT представления не должен содержать вложенных запросов, 
предиката DISTINCT, ключевого слова HAVING, вычисляемых столбцов, 
присоединенных таблиц, функций, определенных пользователем, и хранимых процедур. 
    При создании модифицируемого представления можно указать, чтобы сервер 
выполнял проверку соответствия модифицируемых или добавляемых с помощью 
запроса строк критериям, указанным в представлении. Другими словами, сервер 
может следить за тем, чтобы модифицированная или добавленная запись не вышла 
за рамки представления и не исчезла из виду. Это делается путем использования 
ключевого выражения WITH CHECK OPTION в команде CREATE VIEW. Вот синтаксис 
соответствующей команды: 

    CREATE VIEW MOCUSTOMERS AS SELECT * FROM CUSTOMER WHERE State='MO' WITH 
CHECK OPTION 

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

    Хранимые процедуры 

    Хранимой процедурой (stored procedure) называется скомпилированная 
программа произвольной длины на языке SQL, которая хранится в базе данных 
вместе с другими объектами. Хранимые процедуры InterBase подразделяются на две 
основные разновидности: процедуры выбора (select procedure) и выполняемые 
процедуры (executable procedure). Процедуры выбора используются в операторе 
SELECT вместо таблицы или представления, и следовательно, должны возвращать 
значения, тогда как для выполняемых процедур это не обязательно. 
    Хранимые процедуры создаются командой CREATE PROCEDURE, пример которой на 
языке InterBase приведен ниже. 

    CREATE PROCEDURE listcustomers 
    RETURNS (LastName CHAR(30), FirstName CHAR(30)) AS BEGIN 
    FOR SELECT LastName, FirstName FROM CUSTOMER 
    INTO : LastName., : FirstName 
    DO SUSPEND; END	* 

    Если процедура использует какие-либо параметры, то ее синтаксис несколько 
меняется. Вот синтаксис для InterBase: 

    CREATE PROCEDURE listcustomer^sbystate (State char (2), 
LastNameMask"~cb.ar (30) ) RETURNS (LastName CHAR(30), FirstName CHAR(30)) AS BEGIN 
    FOR SELECT LastName, FirstName FROM CUSTOMER WHERE State = :State and 
LastName like :LastNameMask INTO :LastName, :FirstName DO SUSPEND; END 

    Глава 17. InterBase	359 

    Процедуры выбора 

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

    CREATE   PROCEDURE   listcustomers    (State   CHAR(2)) 
    RETURNS(LastName   CHAR(30)) 
    AS 
    BEGIN 
    FOR SELECT LastName 
    FROM CUSTOMER 
    WHERE State=:State 
    INTO :LastName 
    DO 
    SUSPEND; END 

    Обратите внимание на использование конструкции FOR SELECT... DO для 
возвращения строк результата в вызывающую программу. Команда SUSPEND 
приостанавливает выполнение процедуры до следующего запроса на строку. Перед 
приостановкой выполнения возвращаются значения, присвоенные выходным параметрам. 

    Выполняемые процедуры 

    Выполняемые процедуры почти ничем не отличаются от процедур выбора, за 
исключением того, что они не обязаны содержать оператор RETURNS. Вот пример 
выполняемой процедуры в диалекте InterBase SQL: 

    CREATE PROCEDURE insertitem 
    (ItemNumber Integer, Description Char(30), Price Float) AS BEGIN 
    INSERT INTO ITEM (ItemNumber, Description, Price) VALUES (:ItemNumber, 
:Description, :Price); END 

    Сценарии 

    Нередко бывает удобно помещать операторы языка определения данных (Data 
Definition Language — DDL), в том числе хранимые процедуры, в файлах сценариев 
(script) SQL. Эти файлы можно редактировать в любом текстовом редакторе — 
большинство хороших редакторов SQL поддерживается сохранение содержимого 
сценариев на диске. Помните, что такие сценарии должны содержать все 
необходимые операторы USE и SET TERM. Запуск на выполнение сценария SQL в СУБД 
InterBase производится выбором пункта Run an ISQL Script меню File программы 
WISQL. Пример файла сценария приведен в листинге 17.1. 

    Листинг 17.1. Хранимая процедура из файла SQL-сценария 

    CONNECT "C:\DATA\IB\SALES.GDB" USER "SYSDBA" PASSWORD "masterkey"; 
    SET TERM л; 
    CREATE PROCEDURE GET_CUSTOMER_BY_STATE (State CHAR(2)) 
    RETURNS (LastName CHAR(30)) 
    AS 
    BEGIN 
    FOR SELECT LastName 
    FROM CUSTOMER
    WHERE State = :State 
    INTO : LastName  
    DO	*"*".. 
    SUSPEND; END л 
    SET TERM ; A EXIT; 

    Обратите внимание на использование оператора CONNECT в начале файла для 
подключения к базе данных. Затем идет команда SET TERM, которая заменяет 
обычный разделитель операторов SQL (;) на символ л. Благодаря этому команды, 
включенные в хранимую процедуру, не выполняются до тех пор, пока не за

    360	Часть 111. Справочные материалы 

    вершится выполнение оператора CREATE   PROCEDURE. Наконец, командой SET   
TERM восстанавливается прежний разделитель операторов. 

    Выполнение хранимых процедур 

    Хранимые процедуры InterBase выполняются по команде EXECUTE  PROCEDURE, 
которая имеет следующий синтаксис. 

    EXECUTE  имя_процедуры  параметры 

    Идентификатор имя_процедуры следует заменить именем процедуры, а 
идентификатор параметры — списком параметров, например: 

    EXECUTE PROCEDURE GET_CUSTOMER_BY_STATE "МО" 

    По этой команде выполняется хранимая процедура GET CUSTOMER BY_STATE с 
одним параметром "МО". 

    Исключительные ситуации 

    Исключительные ситуации (exception) — это механизм сообщения об ошибках, 
определенных пользователем, реализуемый с помощью хранимых процедур и 
триггеров. Для определения новой исключительной ситуации в InterBase 
используется команда CREATE EXCEPTION, а команда EXCEPTION применяется для 
активизации или генерирования исключительной ситуации. В листинге 17.2 
приведен пример исключительной ситуации InterBase и хранимой процедуры, в 
которой она генерируется. 

    Листинг 17.2. Исключительная ситуация InterBase и содержащая ее хранимая процедура 

    CONNECT "C:\DATA\IB\SALES.GDB" USER "SYSDBA" PASSWORD "masterkey"; 
    CREATE EXCEPTION SALE_TOO_LOW 
    "Сумма слишком низка — допускаются суммы не меньше $5."; 
    SET TERM л; 
    CREATE PROCEDURE insertsale (SaleNumber int, SaleDate date, CustomerNumber 
int, Item-Number int, Amount float) AS BEGIN 
    IF (:Amount < 5) THEN 
    EXCEPTION SALE_TOO_LOW; ELSE 
    INSERT INTO SALE 
    VALUES (:SaleNumber, :SaleDate, :CustomerNumber, 
    :ItemNumber, :Amount); END л 
    SET TERM ; л EXIT; 

    Эта процедура помещает в таблицу только те данные о продажах, сумма 
которых превышает $5. Обратите внимание на использование конструкции IF. . 
.THEN для определения того, превосходит ли значение столбца Amount вставляемой 
строки сумму $5. Если сумма меньше этой величины, то по команде EXCEPTION 
генерируется исключительная ситуация SALE TOO_LOW. 

    Триггеры 

    Триггеры (trigger) имеют определенное сходство с хранимыми процедурами, но 
в то же время отличаются от них. Это программы на языке SQL, которые 
выполняются при определенной операции над конкретной таблицей: вставке, 
обновл%н^и или удалении данных, т.е. ассоциируются с этой операцией. Вот 
пример триггера на языке InterBase SQL: 

    CREATE  TRIGGER  SALEDelete   FOR  CUSTOMER 
    BEFORE   DELETE	x 
    AS 
    BEGIN 
    DELETE FROM SALE 
    WHERE CustomerNumber=OLD.CustomerNumber; END 

    Глава 17. InterBase	361 

    Этот триггер удаляет данные о продажах определенному покупателю из таблицы 
SALE, как только запись об этом покупателе удаляется из таблицы CUSTOMER. 
Такое удаление называется каскадным (cascading delete) поскольку одна операция 
удаления записи из таблицы вызывает каскад операций удаления данных в других 
таблицах, ассоциированных между собой по ключу. 
    Обратите внимание на использование контекстной переменной OLD. Эта 
переменная служит для ссылки на значения, которые имели столбцы строки перед 
выполнением операций UPDATE или DELETE. Контекстная переменная NEW служит для 
ссылки на новые значения, которые должны вставляться в столбцы по командам 
INSERT или UPDATE. 
    Обратите внимание также на использование ключевого слова BEFORE — триггер 
может срабатывать как перед, так и после выполнения операций INSERT, UPDATE 
или DELETE. 
    В СУБД InterBase с операцией над таблицей можно ассоциировать практически 
любое количество триггеров (точнее, до 32768). Порядок выполнения нескольких 
триггеров, ассоциированных с одной и той же операцией, устанавливается с 
помощью ключевого слова POSITION, например: 

    CREATE   TRIGGER   SALEDate   FOR  CUSTOMER 
    BEFORE   DELETE 
    POSITION   0 
    AS 
    BEGIN 
    DELETE   FROM   SALE 
    WHERE   CustomerNumber=OLD.CustomerNurnber; END 

    Значение параметра команды POSITION может меняться от 0 до 32767. Триггеры 
с меньшими номерами выполняются первыми. Если же несколько триггеров имеют 
один и тот же номер, то они выполняются в случайном порядке. 

    Функции 

    В InterBase пользователи могут расширять диалект SQL путем введения 
собственных функций. Функции определяются во внешних совместно используемых 
библиотеках (в системе Windows это динамические библиотеки типа DLL), и 
объявляются для использования в СУБД InterBase с помощью команды DECLARE 
EXTERNAL FUNCTION. С этого момента функция помещается в базу данных и ведет 
себя точно так же, как любая встроенная функция. Вот пример исходного текста 
библиотеки DLL с определениями двух функций. 

    library IBUDFLIB; 
    uses 
    SysUtils, Classes; 
    function Maxlnt(var Intl, Int2 : Integer) : Integer; 
    far cdecl export; 
    begin 
    If (Intl>Int2) then Result:=Intl 
    else Result:=Int2; end; 
    function Minlnt(var Intl, Int2 : Integer) : Integer; 
    far cdecl export; 
    begin	*•*
    If (Intl<Int2) then Result:=Intl 
    else Result:=Int2; 
    **•* end;	"TV 
    exports Maxlnt, Minlnt; 
    begin end. 

    362	Часть III. Справочные материалы 

    А вот пример сценария SQL, который делает описанные функции доступными для 
использования в InterBase. 

    CONNECT "C:\DATA\IB\SALES.GDB" USER SYSDA PASSWORD masterkey 
    DECLARE EXTERNAL FUNCTION MAXININT 
    INTEGER, INTEGER RETURNS INTEGER BY VALUE ENTRY_POINT "Maxlnt" MODULE_NAME "IBUDFLIB.DLL"; 
    DECLARE EXTERNAL FUNCTION MININT 
    INTEGER, INTEGER RETURNS INTEGER BY VALUE ENTRY__POINT "Minlnt" 
MODULE_NAME "IBUDFLIB.DLL"; 
    EXIT; 

    Вот что необходимо помнить при расширении СУБД InterBase собственными функциями. 
    Q  InterBase импортирует функции библиотек DLL по именам, в которых 
различается верхний и нижний регистр. Поэтому в команде DECLARE EXTERNAL 
FUNCTION необходимо соблюдать правильный регистр, иначе функция не будет найдена. 
    О  Параметры функций передаются по ссылкам, а не по значениям (обратите 
внимание на ключевое слово var в списках параметров функций Maxlnt и Minlnt), 
т.е. функции используют в качестве параметров указатели на переменные, а не 
значения переменных. 
    Q  Функции-расширения InterBase должны использовать соглашения о вызове 
типа cdecl. Соглашения 
    far pascal, stdcall и safecall работать не будут. 
    О   Результаты из функций могут возвращаться как по значениям, так и по 
ссылкам. Если результат возвращается по ссылке, то не забудьте возвращать 
указатель на переменную, а не ее значение, иначе InterBase даст сбой. 
    Функции Minlnt и Maxlnt можно протестировать в программе WISQL следующим образом. 

    SELECT  Maxlnt(3,5)    FROM  CUSTOMER; 

    Поскольку в InterBase любой оператор SELECT должен обращаться по крайней 
мере к одной таблице, здесь используется таблица CUSTOMER. Функция Maxlnt 
будет выполняться по одному разу для каждой строки таблицы CUSTOMER, поэтому 
будет отображено несколько результатов ее выполнения. 
    Для выполнения команд SELECT, которые не связаны с запросами к таблицам, 
может использоваться таблица, содержащая всего одну строку. Вот пример 
создания и использования такой таблицы (каждый оператор выполняется в утилите 
WISQL отдельно): 

    CREATE   TABLE   DUAL    (A   CHAR(l)); INSERT   INTO   DUAL    (A)   
VALUES    ('A'); SELECT   22   /   7  A3  Approximate?!   FROM   DUAL; 

    Для удаления объявления внещней функции из базы данных используется 
команда DROP   EXTERNAL FUNCTION. 

    Курсоры 

    Курсоры (cursor) — это компромисс между ориентированным на множества 
подходом SQL и потребностью в построчных операциях. С помощью курсоров можно 
работать с отдельными строками таблицы. Обычно курсоры не пишутся на языке 
SQL, а автоматически создаются системой BDE, но иногда они оказываются 
удобными для использования в хранимых. 
    Над курсорами выполняются четыре основные операции: объявление, открытие, 
извлечение данных и закрытие. С помощью курсоров можно также модифицировать и 
удалять строки таблицы. 

    Глава 17. InterBase 363 

    На заметку 

    Не пытайтесь выполнять эти команды поодиночке из программы WISQL. Они 
используются только в хранимых процедурах. 
    Объявление курсора содержит оператор SELECT и (для модифицируемых 
курсоров) список модифицируемых столбцов. Вот пример такого объявления: 

    DECLARE CUSTOMER_SELECT CURSOR FOR SELECT * FROM CUSTOMER 

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

    OPEN CUSTOMER__SELECT 

    По команде OPEN в приложение не передаются никакие данные. Для этого 
необходимо использовать команду FETCH. 

    FETCH CUSTOMER_SELECT 

    По этой команде из возвращаемого курсором набора данных извлекается одна 
строка. Все последующие вызовы вызовы FETCH приводят к извлечению очередных 
строк. В курсорах SQL Server поддерживается только одностороннее продвижение 
по записям таблицы: с помощью команды FETCH нельзя возвращаться к ранее 
пройденным записям. Для этого необходимо закрыть курсор командой CLOSE и снова 
открыть его командой OPEN. 

    На заметку 
    Отсутствие в InterBase поддержки двунаправленных курсоров — это еще не 
повод не использовать их в приложениях Delphi. Система ВОЕ эмулирует 
двунаправленные курсоры на уровне приложений-клиентов независимо от того, 
поддерживаются ли они сервером СУБД. Вот почему по таким структурам данных, 
как TQuery и ттаЫе, можно передвигаться как вперед, так и назад. 

    Строки, полученные из модифицируемого курсора, можно модифицировать с 
помощью специальных версий команд UPDATE и DELETE. Модифицируемый курсор 
объявляется с использованием ключевого слова FOR UPDATE OF. Вот пример такого объявления: 

    DECLARE CUSTOMERJJPDATE CURSOR FOR SELECT * FROM CUSTOMER FOR UPDATE OF LastName 


    На заметку 
    В списке ключевого слова FOR UPDATE OF следует перечислять только те 
столбцы, которые на самом деле будут модифицироваться. Наличие в этом списке 
лишних столбцов замедляет работу сервера. 

    Для удаления или модифицирования текущей строки курсора в дополнение к 
команде DELETE или UPDATE используется синтаксическая конструкция WHERE 
CURRENT OF имя_курсора, как в следующем примере: 

    UPDATE CUSTOMER 
    SET LastName="Cane"         *•*
    WHERE CURRENT OF CUSTOMERJJPDATE 
    ИЛИ	*~ ^ 
    DELETE FROM CUSTOMER 
    WHERE CURRENT OF CUSTOMERJJPDATE 

    Для завершения работы курсора его закрывают командой CLOSE. Закрытие 
курсора приводит к освобождению используемых им системных ресурсов. Вот 
синтаксис этой команды: 

    CLOSE CUSTOMER UPDATE 

    364 Часть III. Справочные материалы 

    Управление базами данных InterBase 

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

    Резервирование и восстановление 

    Основной заботой разработчика, администратора и пользователя в равной 
степени должна стать обеспечение безопасности базы данных. Представьте, что 
может случиться, если с диском, на котором расположена база данных, что-то 
случится. Катастрофические последствия такой ситуации предотвращаются путем 
создания резервных копий базы данных. Для этого недостаточно просто 
скопировать все файлы операционной системы, образующие базу данных, поскольку 
некоторые из них могут в текущий момент использоваться на сервере и находиться 
в его памяти. Такое копирование не гарантирует мгновенного "снимка" всей базы 
данных и работоспособности ее копии, сделанной в данный момент времени. 
Корректное резервирование баз данных InterBase выполняется с применением 
программы Server Manager. Для этого выполните следующее. 
    1.	Запустите программу Server Manager. 
    2.	Выберите команду File^Server Login и зарегистрируйтесь на сервере. 
    3.	Выберите команду TasksOBackup для открытия диалогового окна Database Backup. 
    4.    Введите полное имя и путь к резервируемой базе данных в строке 
Database Path. Щелкните на кнопке Remote для ввода имени удаленной базы данных 
для сетевой операционной системы, отличной от NetWare. 
    5.    Введите имя файла или устройства резервирования в строке Backup File 
or Device. Если вы работаете в системе Windows NT, то можно по умолчанию 
выбрать устройство \\.\tapeO. 
    6.   Для резервирования базы данных щелкните на кнопке ОК. На рис. 17.1 
показано все вышеизложенное. 
    Восстановление базы данных из резервной копии представляет собой 
практически тот же процесс в обратном порядке. Для этого следует выбрать 
команду Restore из меню Tasks, ввести имя резервной копии в строке Restore 
Source и имя базы данных в строке Restore Destination. 

    Управление бюджетами пользователей 

    Чтобы подключаться к базам данных InterBase, необходимо иметь правильные 
имя пользователя и пароль. Для создания новых пользовательских бюджетов 
используется команда меню Task^User Security программы Server Manager. Для 
добавления нового бюджета пользователя InterBase выполните следующее. 
    1.	Запустите программу Server Manager. 
    2.	Выберите команду File^Sefver Login и зарегистрируйтесь на сервере. 
    3.	Выберите команду Tasks^User Security для открытия диалогового окна 

InterBase Security (рис. 17.2). 


    4.	Щелкните на кнопке Add User для ввода информации о новом пользователе. 
    5.	Введите имя и пароль нового пользователя. 
    6.	Щелкните на кнопке ОК для добавления нового бюджета. 


    Глава 17. InterBase	365 



    Рис. 17.1. Резервирование базы данных с использованием программы Server Manager 

    Рис. 17.2. Добавление новых бюджетов пользователей InterBase в окне User 
Configuration программы Server Manager 

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

    Настройка конфигурации сервера 

    Диалоговое окно InterBase Server Configuration можно открыть несколькими 
способами: выбрать команду Task<=>Server Config в меню программы Server 
Manager или же щелкнуть правой кнопкой мыши на пиктограмме InterBase server на 
панели», задач Windows и выбрать из контекстного меню команду Properties. 
    Параметры окна Server Configuration делятся на два класса: параметры СУБД 
InterBase и параметры операционной системы. 
    К группе InterBase (IB Settings^ относятся два параметра: Database Cache и 
Client map size. Параметр Database Cache определяет количество страниц, 
резервируемое для кэширования баз данных. Если размер кэшпамяти выбрать 
достаточно большим, то вполне возможно, что в оперативную память поместится 
вся база данных. В результате быстродействие операций резко повысится. Если же 
выбрать размер кэш-памяти слишком большим, то операционная система будет 
интенсивно буферизовать страницы InterBase на диске, и производительность 
сервера упадет. Параметр Client size map определяет размер буфера для каждого 
клиентского подключения. Этот параметр лучше не менять — можно разве что 
увеличить его при необходимости интен-сивнго обмена данными большого объема 
(например, BLOB) с приложением-клиентом. 

    366 Часть III. Справочные материалы 

    К группе операционной системы (OS Settings) относятся три параметра: Min 
Process Working Set, Max Process Working Set и Process Priority Class. 
Параметры Min Process Working Set и Max Process Working Set контролируют 
выделение серверу физической памяти (в килобайтах). Если увеличить 
максимальное значение, то можно увеличить и размер кэш-памяти для базы данных 
(Database Cache), но чрезмерное его увеличение может привести к излишней 
буферизации. Если сервер работает в системе Windows NT, то с помощью утилиты 
Performance Monitor можно определить, необходимо ли изменение рабочих 
параметров. Для этого выполните следующее. 
    1. При работающем сервере InterBase запустите утилиту Windows NT 
Performance Monitor (предпочтительно на том же компьютере, что и сервер). 
    2.Откройте новую диаграмму и нажмите клавиши <Ctrl+I> для добавления в 
диаграмму новых показателей. 
    3.Выберите Object: Process, Intance: IBSERVER, Counter: Page File Bytes и 
щелкните на кнопке Add. 
    4.Добавьте показатели Page Faults/sec и % Processor Time объекта IBSERVER 
(рис. 17.3). 

    Рис. 17.3. Использование утилиты Performance Monitor Windows NT для 
определения потребности в оперативной памяти для InterBase 

    Если происходит интенсивная буферизация (показатель Page Faults/sec), или 
показатель % Processor Time имеет значение ниже 50%, то можно увеличить 
диапазон Process Working Set для повышения производительности сервера. 
Изменения в параметрах вступят в действие после следующего запуска сервера. 
    Значение параметра Process Priority Class влияет на приоритет процесса 
сервера InterBase среди других процессов, работающих на том же компьютере. 
Изменение значения этого параметра на High может привести к резкому повышению 
быстродействия, особенно на компьютерах, специально назначенных серверами 
InterBase, в том случае, если на этих компьютерах работает много 
приложений-клиентов. Изменение этого параметра вступает в силу сразу же после 
щелчка на кнопке Apply. 

    Просмотр статистики блокировок 

    Из-за консервативных механизмов распараллеливания, применяемых в СУБД типа 
"клиент-сервер", конфликты и взаимная блокировка ресурсов достаточно широко 
распространены. В InterBase, как и в большинстве многопользовательских СУБД, 
ресурсы блокируются для предотвращения записи изменений, сделанных одним 
пользователем, поверх изменений, выполненных другим. Если два пользователя 
таким образом блокируют друг друга (эта ситуация известна под названием 
"клинч" (deadlock)), то необходимо проверить корректность работу блокировок 
ресурсов сервера. Блокировки InterBase просматриваются путем выбора команды 
Tasks^Lock^Janager Statistics из меню программы Server Manager (рис. 17.4). 
    Диспетчер блокировок InterBase использует для отслеживания блокировок 
специальную таблицу, в которой хранится информация о состоянии блокировок всех 
ресурсов сервера. Блок LOCK_HEADER BLOCK в верхней части листинга содержит 
итоговую информацию обо всей системе, включая текущий и максимальный размер 
таблицы блокировок, свободные блокировки, общее количество клинчей и т.д. Окно 
диспетчера также содержит информацию об отдельных процессах: принадлежность 
блокировок процессам, назначение и приостановка блокировок и т.п. Эту 
информацию можно использовать для выявления таких проблем, как взаимное 
блокирование процессов. 

    Глава 17. InterBase 367 

    Проверка работоспособности базы данных 

    Помимо регулярного резервирования, для обеспечения сохранности и 
корректности данных необходимо время от времени выполнять проверку целостности 
и работоспособности базы данных. Предпочтительно делать это непосредственно 
перед резервированием или после него. Для этого выберите команду 
Main-tenance^Database Validation из меню программы InterBase Server Manager. 
На рис. 17.5 показано диалоговое окно Database Validation. 
    Проверка базы данных состоит из трех основных операций: выявления 
поврежденных структур дискового пространства, составления перечня неправильно 
размещенных страниц данных и перемещения этих страниц на свободное место для 
последующего повторного использования. Обычно те исправления, которые не 
затрагивают пользовательские данные, вносятся автоматически, но этот режим 
можно отключить, установив флажок Read-only validation. 

    Рис. 17.4. Окно Lock Manager Statistics с   подробной информацией о 
блокировках InterBase 

    Рис. 17.5. Диалоговое окно Database Validation для проверки 
работоспособности базы данных 

    Все ошибки, зарегистрированные средствами проверки базы данных, 
отображаются в окне. Для попытки исправления найденных ошибок щелкните на 
кнопке Repair. Если в базе данных обнаружено нарушение контрольной суммы, то 
можно включить режим игнорирования таких ошибок, чтобы утилита проверки смогла 
закончить обработку оставшейся части базы данных. Для исправления поврежденной 
базы данных InterBase выполните следующей. 
    1.Создайте резервную копию базы данных без помощи службы резервирования 
Server Manager (например, с помощью копирования ^программе Explorer 
(Проводник) Windows). Это связано с тем, что поврежден- 'J ные базы данных не 
могут резервироваться стандартным методом. 
    2.Для проверки базы данных выберите команду Maintenance^Database 
Validation из меню программы InterBase Server Manager. 
    3.После завершения процесса проверки щелкните на кнопке Repair для 
отметки и исправления поврежденных структур. 

    368 Часть III. Справочные материалы 

    4.Если имеются ошибки в контрольных суммах, то снова выберите команду 
Database Validation, на этот раз установив флажок Ignore checksum errors. 
    5.После завершения проверки щелкните на кнопке Repair для исправления 
вновь найденных ошибок. 
    6.Снова запустите службу проверки ошибок, включив режим Read-only 
validation. Заметьте, что на этот раз отчет о свободных страницах не выдается, 
а негодные записи отмечаются как поврежденные. Эти записи исключаются из 
резервных копий, сделанных с помощью Server Manager. 
    7.Сделайте резервную копию исправленной базы данных с помощью службы 
резервирования Server Manager. Поврежденные записи будут потеряны навсегда, 
поскольку они исключены из резервной копии. 
    8.Восстановите базу данных из только что сделанной резервной копии. В езультате некоторые внутренние структуры будут перестроены, и все повреждения устранены. 
    9.В последний раз запустите службу проверки баз данных, чтобы убедиться 
в том, что база данных окончательно исправлена. Перед проверкой включите режим 
Read-only validation. 

    Статистика базы данных 

    Для выполнения команды Database Statistics и всех последующих команды 
программы Server Manager, помимо регистрации на сервере, необходимо 
подключиться к базе данных. Для подключения к базе данных выберите команду 
File Database^Connect из меню программы Server Manager. 
    При выборе команды Tasks1* Database Statistics из меню программы Server 
Manager отображается статистическая информация о базе данных: дата создания 
базы данных, самая старая из активных транзакций, размер страницы базы данных 
и количество определенных для нее отображений. Некоторые из этих данных 
доступны также по команде меню Maintenance^Database Properties. На рис. 17.6 
показан пример окна Database Statistics. 

    Рис. 17.6. Окно Database Statistics с основной статистической информацией 
о базе данных 

    Пока окно Database Statistics находится на экране, для выяснения 
количества страниц, отведенных для базы данных, и их наполнения, можно выбрать 
команду View^Database Analysis. Таким образом можно определить, как 
организация базы данных влияет на распределение ее содержимого по физическим устройствам. 


    Обновление базы данных 

    При обновлении базы данных по команде Maintenance^Database Sweep 
освобождается пространство, занимаемое старыми версиями записей и записями, 
которые отменялись в ходе транзакций. Средства обновления баз данных можно 
считать своеобразными уборщиками мусора. Хотя для обновления базы данных нет 
необходимости закрывать ее, все же лучше делать это, выбрав момент, когда база 
данных используется с минимальной интенсивностью, чтобы не затрагивать 
интересы пользователей. Помните, что обновление больших баз данных может 
существенно замедлить работу сервера. 

    Глава 17. InterBase 369 

    Завершение транзакций 

    При инициировании транзакции, охватывающей несколько баз данных, 
автоматически запускается двуч-этапный процесс сохранения измененых данных на 
диске, предназначенный для синхронной записи из\е-нений во всех базах данных. 
При недоступности одной из баз данных из-за нарушения связи по сети или 
неисправности диска этот процесс может завершиться аварийно. Команда меню 
Maintenance^Transaction .Recovery предназначена как раз для работы с 
транзакциями, которые остались в "подвешенном" состоянии вследствие аварийного 
завершения двухэтапного процесса сохранения данных. Таким образом эти 
траник-ции можно довести до логического завершения — отменить изменения или сохранить. 

    Резюме 

    Эта глава содержит краткое введение в основные понятия и особенности СУБД 
InterBase. Из этой главы вы узнали, как запустить сервер InterBase, как 
подключиться к нему, как предупредить и устранить возможные ошибки 
подключения. Глава содержит также подробный обзор диалекта языка SQL для 
InterBase и описание основных задач управления базами данных в этой СУБД. Хотя 
СУБД InterBase сама по себе является предметом для отдельной книги, тем не 
менее можно надеяться, что представленный здесь обзор значительно облегчит 
жизнь разработчикам приложений Delphi, которые должны взаимодействовать с InterBase. 

    Что дальше... 

    В главе 18, "Sybase SQL Server", рассматриваются некоторые вопросы, 
касающиеся разработки приложений Delphi для подключения к серверам баз данных Sybase. 

    370	Часть III. Справочные материалы 
