    16 
    ГЛАВА 

    Oracle 

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

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

    Метод запуска сервера в значительной степени варьируется от платформы к 
платформе. Здесь будет рассмотрен запуск сервера в системах Windows 95 и 
Windows NT. Для других операционных систем следует обращаться к документации 
по данной СУБД. 
    Обычно СУБД Oracle устанавливается так, чтобы автоматически запускаться 
вместе с Windows. Если же это не так, то можно запустить ее с помощью утилиты 
Oracle Instance Manager или (в системе Windows NT) из окна Control Panel. Для 
запуска Oracle в Windows NT следует использовать приложение, имя которого 
имеет вид OracleStartORCL, где ORCL — имя конкретного экземпляра базы данных. 

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

    Для подключения к серверу баз данных Oracle необходимо установить и 
настроить программное обеспечение создания подключений Oracle SQL Net. Для 
этого достаточно запустить программу установки Oracle общего назначения 
ORAINST. Для настройки программного обеспечения необходимо определить 
псевдонимы баз данных (Database Aliases) — набор параметров, содержащий всю 
информацию, которая необходима для связи с сервером. Эти псевдонимы имеют 
определенное сходство с собственными псевдонимами BDE Delphi, но работают на 
уровне драйверов Oracle, а не на уровне общих драйверов баз данных. 
    Чтобы выполнить настройку псевдонима базы данных Oracle с использованием 
конфигурационного приложения SQL Net для Windows 95 и Windows NT, запустите 
программу SQL Net Easy Configuration, выберите пункт Add Database Alias и 
щелкните на кнопке ОК. 
    В следующем диалоговом окне появится приглашение выбрать псевдоним базы 
данных. Поскольку добавляется новый псевдоним, введите новое имя по своему 
выбору и щелкните на кнопке ОК. 
    Затем в окне появится приглашение выбрать сетевой протокол. Выберите 
протокол, который будет использоваться для связи с сервером (например, 
TCP/IP), и щелкните на кнопке ОК. 
    После выбора сетевого протокола программа предложит вам ввести 
дополнительную информацию о сервере. Если выбран сетевой протокол TCP/IP, то 
необходимо ввести имя сервера в том виде, в каком оно указано в файле HOSTS. 
Можно также ввести IP-адрес сервера. Если сервер Personal Oracle установлен на 
том же компьютере, что и клиент, то в качестве IP-адреса сервера можно указать 
фиктивный зацикливающий адрес протокола TCP/IP, т.е. 127.0.0.1 (в большинстве 
систем можно использовать локальное имя главного компьютера). Если для 
обслуживания подключения выбран протокол SPX, то вместо этого необходимо 
ввести имя службы SPX. Введите требуемую информацию и щелкните на кнопке ОК. 

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

    В последнем диалоговом окне отображается информация о подключении для 
создаваемого псевдонима базы данных. Для его добавления щелкните на кнопке ОК. 
    После возвращения в главное меню программы настройки SQL Net выберите Exit 
и щелкните на кнопке ОК для завершения работы программы. 
    После настройки псевдонима базы данных следует протестировать его путем 
подключения к серверу. Для этого новый псевдоним используется в утилите Oracle 
SQL*Plus следующим образом: 
    sqlplus   имя_польз/пароль®псевдоним @<файл>.<расш> 
    Здесь имя_польз и пароль — это, соответственно, имя пользователя и его 
пароль, а псевдоним — только что созданный псевдоним базы данных. 
    Следует заметить, что для проверки связи с сервером можно использовать 
также программу Oracle TNSPING. Для нее используется тот же синтаксис, что и 
для известной команды PING системы UNIX. 

    На заметку 

    При соединении с сервером Personal Oracle, работающем на одном компьютере 
с клиентом, меньше всего проблем возникает при использовании протокола TCP/IP. 
В этом случае можно применять в качестве IP-адреса сервера фиктивный адрес 
127.0.0.1. Программное обеспечение протокола TCP/IP поставляется вместе с 
Windows 95 и Windows NT. Достаточно установить его, и у вас будет все, что 
необходимо для связи с сервером Oracle.	9*Sllli 

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

    После настройки связи с сервером баз данных наступает очередь создания 
псевдонима BDE для обращения к серверу из приложений Delphi. Эта тема 
освещается в данной книге в другом месте, однако здесь приводится ее краткий 
обзор — для удобства и для раскрытия взаимосвязи между настройкой драйверов 
баз данных и настройкой псевдонимов BDE. 
    Псевдонимы BDE создаются либо с помощью утилиты BDE Administrator, либо с 
помощью приложения Delphi Database Explorer. Приведенные ниже инструкции 
относятся к программе BDE Administrator. 
    Запустить программу BDE Administrator можно не только щелчком на ее 
пиктограмме в папке Delphi, но и из приложения Windows Control Panel (Панель управления).	s 
    1.    Запустите утилиту BDE Administrator и выберите на вкладке 
Configuration пункт Configura-tion^Drivers^Native^Oracle. 
    2.    Раскройте список VENDOR INIT в группе Definition и выберите 
динамическую библиотеку Oracle, соответствующую той версии Oracle, к которой 
необходимо обратиться. Например, для связи с сервером Oracle 7.2 необходимо 
выбрать библиотеку ORA72.DLL. 
    Обратите внимание, что здесь можно выбрать также и другие параметры 
драйвера. Установленные параметры становятся параметрами по умолчанию для всех 
новых псевдонимов, использующих данный драйвер. 
    3.    Щелкните правой кнопкой на вкладке Databases и выберите пункт New из 
всплывающего меню. После появления диалогового окна New Database Alias 
выберите пункт Oracle в раскрывающемся списке Database Driver Name и щелкните 
на кнопке ОК. 
    4.    После добавления нового псевдонима введите для него имя. 
    5.    Настройте параметры нового псевдонима на вкладке Definition. 
    6.    Щелкните на параметре SERVER NAME и установите его значение равным 
псевдониму базы данных. Это должно быть то же самое имя, которое 
использовалось в конфигурационной утилите SQL Net. 
    7.    По желанию можно указать в параметре USER NAME имя пользователя 
сервера, автоматически регистрируемого на сервере по умолчанию. Введенное имя 
будет отображаться по умолчанию при каждом появлении встроенного диалогового 
окна регистрации Delphi. 
    Для сохранения изменений щелкните на кнопке Apply (или нажмите <Ctrl+A>), 
а затем выйдите из программы BDE Administrator. 

    Глава 16. Oracle 327 

    Определение псевдонима, установленного с использованием программы BDE 
Administrator, можно найти в системном реестре Windows по следующему ключу: 

    HKEY_LOCAL_MACHINESSOFTWARE\BORLAND\DATABASE ENGINEXSETTINGS 

    Этот ключ можно использовать, например, для создания определений 
псевдонимов без помощи программ JjBDE Administrator или Delphi Database Explorer. 
    Ниже приведены некоторые параметры программы BDE Administrator, настройка 
которых может понадобиться если не сейчас, то впоследствии. 

    ENABLE INTEGERS 

    Параметр ENABLE INTEGERS определяет, следует ли драйверам BDE считать поля 
типа NUMERIC, не содержащие десятичных цифр после запятой, целочисленными. По 
умолчанию такие поля относятся к типу NUMERIC независимо от наличия дробных 
цифр. • 
    Этот параметр напоминает по функциям параметр ENABLE BCD, но имеет более 
высокий приоритет. 

    Синонимы 

    В Oracle можно использовать альтернативные имена объектов, называемые 
синонимами. Для выбора режима обработки синонимов Oracle используется 
специальный параметр драйвера базы данных LIST SYNONYMS. Этот специальный 
параметр устанавливается с использованием свойства Params компонента Database. 
В табл. 16.1 перечислены возможные значения этого параметра. 

    Таблица 16.1. Допустимые значения параметра LIST SYNONYMS 

    Значение	Пояснение 

    NONE	Нет синонимов 
    PRIVATE	__              Разрешены только скрытые синонимы 
    ALL	___            _____     Разрешены все (скрытые и общедоступные) синонимы 

    Для выбора одного из этих значений дважды щелкните на свойстве Params 
компонента Database и введите имя параметра и его значение следующим образом: 

    LIST SYNONYMS=ALL 

    Общедоступные синонимы 

    При установке параметра LIST SYNONYMS равным ALL, в таблице синонимов 
можно видеть в числе прочих общедоступные синонимы (типа PUBLIC. Однако для 
того, чтобы открыть общедоступный синоним, необходимо обладать привилегией 
SELECT на объект, представленный этим синонимом. Если вы (или пользователь 
вашего приложения) не обладаете необходимыми правами, то при попытке открытия 
синонима окажется, что его как бы не существует. Права, необходимые для 
открытия синонима, может назначить администратор базы данных. 
    В список общедоступных синонимов Oracle включается также набор 
динамических таблиц производительности. По умолчанию доступ к ним имеет только 
пользователь SYS. Имена этих синонимов имеют формат У$имя, где имя — имя 
синонима (например, LOCK, OPEN_CURSOR и т.п.) 

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

    Если при подключении к серверу Oracle возникают проблемы, попытайтесь 
проделать следующее. 
    1.   Используйте для подключения к серверу утилиту Oracle SQL*Plus. Если с 
помощью этой утилиты можно подключиться, а из приложения Delphi нельзя, то, 
вероятно, имеется ошибка в конфигурации псевдонима BDE. Вернитесь к программе 
BDE Administrator и проверьте значения параметров (в частности, имя сервера). 

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

    Если с помощью утилиты Oracle SQL* Plus подключиться нельзя, то возможна 
проблема с протоколом. Если для подключения к серверу используется протокол 
TCP/IP, то попытайтесь вызвать главный компьютер через утилиту PING, 
поставляемую вместе с системами Windows 95 и Windows NT. Для вызова 
используйте как имя компьютера, указанное в файле HOSTS, так и его IP-адрес. 
    Если обращение к компьютеру через утилиту PING по IP-адресу происходит 
корректно, а по имени — нет, то проблема, вероятно, связана с файлом HOSTS. 
Временное решение этой проблемы — изменить строку подключения в программе SQL 
Net таким образом, чтобы вместо имени использовался IP-адрес. Проблему с 
файлом HOSTS необходимо решить как можно быстрее, поскольку подключение к 
удаленным компьютерам по имени является более гибким и удобным способом. 
    Если для подключения к серверу используется протокол SPX, то проверьте, 
совпадает ли имя службы SPX сервера с тем, которое указано в программе 
настройки SQL Net. Если это так, но подключение все равно не устанавливается, 
или если используется какой-либо другой протокол, проконсультируйтесь с 
администратором сети 
    Если используется протокол TCP/IP, и вызов через PING как по имени, так и 
по IP-адресу не происходит, то, по всей видимости, имеется неполадка в сети. 
Проверьте такие очевидные вещи, как правильность IP-адреса сервера. Попробуйте 
обратиться по фиктивному зацикливающему адресу TCP/IP, 127.0.0.1, чтобы 
проверить правильность работы стека TCP/IP. Этот адрес предназначен для вызова 
по сети самого вызывающего компьютера, т.е. для эмуляции вызова компьютера из 
сети. Если такой вызов не срабатывает, то в конфигурации протокола имеются 
серьезные ошибки. Для их устранения необходимо проконсультироваться с 
администратором сети. 
    Если подключение через SQL*Plus не устанавливается, но вызов через P1NG 
происходит корректно, то проверьте, указан ли в системной переменной PATH 
каталог Oracle. Если в PATH все правильно, то проверьте содержимое файла 
(каталог_ОКАСЬЕ) \NETWORK\ADMIN\TNSNAMES.ORA. Это текстовый файл, поэтому его 
можно просматривать с помощью команды TYPE или любого текстового редактора, но 
непосредственно редактировать его не нужно — для этого лучше воспользоваться 
программой SQL Net. Ниже приведен пример того, как должен выглядеть этот файл 
для локального сервера. 
    SCOTTSDATABASE.world = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = 
    (COMMUNITY = tcp.world) (PROTOCOL = TCP) (Host = 127.0.0.1) (Port = 1521) 
) (ADDRESS = 
    (COMMUNITY = tcp.world) (PROTOCOL = TCP) (Host = 127.0.0.1) (Port = 1526) 
    ) 
    (CONNECT   DATA 
    (SID  =  ORCL) 
    7.    Если в конфигурации параметров, на первый взгляд, нет ошибок, то 
можно попробовать сменить протокол (в том случае, если имеется выбор). 
Поскольку сервер можно настроить на прием сообщений сразу по нескольким 
протоколам, его можно временно использовать с работающим протоколом, пока не 
будет обнаружена причина неполадок. Например, для связи с локальным сервером 
(т.е. таким, который находится на одном компьютере с клиентом) можно выбрать 
протокол Oracle Bequeath — простой зацикливающий (loop-back) протокол, 
избавляющий от необходимости работать в сети. 

    Азы SQL 

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

    Глава 16. Oracle 329 

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

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

    CREATE DATABASE имяБД LOGFILE спецификация_файла DATAFILE спецификация_файла; 

    В этой команде можно указать ряд параметров. Самый минимальный набор для 
Oracle — это имя базы • данных и местонахождение файлов данных и регистрации. 
Если вы полагаете, что краткость — сестра та- * ланта, то можно опустить 
вообще все параметры: 

    CREATE DATABASE; 

    По этой команде будет создана небольшая база данных с параметрами, 
имеющими установленные по     • умолчанию значения.	« 
    Файлы, образующие базу данных, обычно имеют расширение DBF или DAT, что 
позволяет отличить их от других файлов каталогов. Обратите внимание, что 
размер файла можно установить заранее или настроить его на автоматическое 
расширение по мере разрастания базы данных. 

    Команда CONNECT 

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

    CONNECT USER/пароль®источникБД 

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

    CONNECT SYS/57RIVERSIDE; 

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

    DISCONNECT; 


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

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

    CREATE TABLE CUSTOMER 
    ( 
    CustomerNumber	number  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 number NOT NULL, SaleDate date, 
    CustomerNumber number NOT NULL, ItemNumber number NOT NULL, Amount	number (5,2) 

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

    Итак, таблица SALE создана. Осталась всего одна таблица — ITEM, и она 
создается следующей командой. 

    CREATE TABLE ITEM 
    ItemNumber 
    Description 
    Price 
    number char(30) , number(5,2) 
    NOT  NULL, 

    Табличные области 

    В СУБД Oracle для команды CREATE TABLE предусмотрены некоторые интересные 
модификации. В частности, таблицы можно размещать в специально отведенных для 
них табличных областях (tablespace) — участках дискового пространства, которые 
могут содержать объекты баз данных наподобие таблиц или индексов. При 
создаШй~таблйчной~области она ассоциируется с конкретным диском или томом, 
например, следующим образом. 

    CREATE  TABLESPACE   salestables   DATAFILE 
'C:\ORANT\DATABASE\salestables.dbf   SIZE   250K 

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

    CREATE "TABLE ITEM 
    ( 
    ItemNumber       number    NOT NULL, 
    Description      char(30), 
    Price	number(5,2) 
    ) 
    TABLESPACE salestables 

    Это позволяет управлять размещением таблиц и индексов на отдельных дисках, 
и не допускать их конкуренции за средства чтения и записи. Помещая таблицы и 
индексы в табличные области, которые нахо-дятся~на_ различных дисках (а в 
идеале — обслуживаются различными контроллерами), можо значительно повысить 
производительность системы. 

    Вложенные запросы и ключевое слово AS 

    Еще одна интересная разновидность команды CREATE TABLE позволяет создавать 
одну таблицу по результатам запроса к другой таблице. Аналогом этой команды в 
диалекте Transact-SQL для SQL Server является команда SELECT . . . INTO. 
Вместо списка полей для создания таблицы Oracle в этом случае используется 
набор данных, возвращаемый запросом к другой таблице. Новая таблица содержит 
все строки исходной таблицы, которые удовлетворяют условиям запроса. Вот пример: 

    CREATE TABLE LARGE_SALE 
    AS SELECT * FROM SALE WHERE Amount > 50; 

    Обратите внимание, что в этой команде вообще не указаны поля, поскольку 
набор полей для новой таблицы заимствуется из исходной таблицы. Хотя в чем-то 
это напоминает создание представления с помощью команды CREATE VIEW, таблицы, 
созданные с помощью ключевого слова AS, в отличие от запросов, действительно 
содержат данные. 

    UNRECOVERABLE 

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

    UNRECOVERABLE В Команду CREATE TABLE. Вот Пример: 
    CREATE TABLE LARGE_SALE 
    UNRECOVERABLE 
    AS SELECT * FROM SALE WHERE Amount > 50; 

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

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

    SALE 
    CREATE TABLE LARGE_ UNRECOVERABLE PARALLEL (DEGREE 5) AS SELECT * FROM SALE 
    WHERE Amount > 50; 

    Глава 16. Oracle 331 

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

    ALTER TABLE CUSTOMER 
    ADD (PhoneNumber char(10)) 

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

    ALTER TABLE CUSTOMER 
    MODIFY (PhoneNumber char(13)) 

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

    Ограничения 

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

    ALTER TABLE CUSTOMER 
    ADD PRIMARY KEY (CustomerNumber) 

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

    ALTER TABLE SALE 
    ADD CONSTRAINT INVALID_CUSTOMER_NUMBER FOREIGN KEY (CustomerNumber} 
REFERENCES CUSTOMER 

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

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

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

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

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

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

    CREATE INDEX SALE02 ON SALE (SaleDate) 

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

    CREATE  UNIQUE   INDEX  SALE01   ON   SALE   (SaleNumber) 

    ^Несмотря на то, что в команде CREATE INDEX допускается ключевое слово 
DESC, создание убывающих индексов "не поддерживается. Индексы Oracle всегда 
располагаются в порядке возрастания, а ключевые слова ASC и DESC допускаются 
только для совместимости с DB2. 

    Ключевые слова UNRECOVERABLE и PARALLEL 

    Ключевые слова UNRECOVERABLE и PARALLEL, которые уже обсуждались в связи с 
командой CREATE TABLE, применяются также и в команде CREATE INDEX. Их 
использование ускоряет процесс построения индексов больших таблиц. 

    NOSORT 

    Ключевое слово NOSORT используется для указания серверу Oracle, что строки 
таблицы уже отсортированы по индексному ключу. Благодаря этому можно 
сэкономить время, не создавая индексов для данных, которые уже выстроены в 
нужном порядке. 

    Табличные области 

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

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

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

    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' ) ; 

    После этого добавляются три строки в таблицу 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) 

    Глава 16. Oracle 333 

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

    INSERT   INTO  SALE   (SaleNumber,   SaleDate,   CustomerNumber, 
    ItemNumber,   Amount) 
    VALUES(101, Ч8-ОСТ-901,1,1001,13.45) 
    INSERT INTO SALE (SaleNumber, SaleDate, CustomerNumber, 
    ItemNumber, Amount) 
    VALUES(102, '27-FEB-921,2,1002,67.90) 
    INSERT INTO SALE (SaleNumber, SaleDate, CustomerNumber, 
    ItemNumber, Amount) 
    VALUES(103, '20-MAY-951 ,3,1003,11.45) 
    INSERT   INTO  SALE   (SaleNumber,   SaleDate,   CustomerNumber, 
    ItemNumber,   Amount) 
    VALUES(104,'27-NOV-97',I,1002,67.90) 

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

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


    Команда UPDATE 

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

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

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

    WHERE: 
    UPDATE CUSTOMER 
    SET   State='MO' 

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

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


    Команда DELETE 

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

    DELETE FROM CUSTOMER 

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

    DELETE FROM CUSTOMER WHERE LastNameO'Doe' 


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

    Транзакцией (transaction) называется группа изменений в базе данных. В 
СУБД Oracle после ввода любой из команд CONNECT, COMMIT или ROLLBACK 
автоматически начинается новая транзакция. Изменения в базе данных фиксируются 
с помощью команды COMMIT, а отменяются командой ROLLBACK. Обе эти команды 
применяются только к изменениям, внесенным в базу данных после последней 
команды COMMIT; все ранее сохраненные изменения отменить уже нельзя. 

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

    Утилита Oracle SQL* Plus автоматически инициирует транзакцию сразу после 
подключения к базе данных. После выхода из программы все изменения 
автоматически сохраняются. Сохранить или отменить изменения можно в любой 
момент с помощью команд COMMIT и ROLLBACK, соответственно. 

    На заметку 

    i:B Oracle операторы языка определения данных (Data Definition Language — 
DDL) работают в транзакциях | иначе, чем другие операторы. До и после 
выполнения каждой команды DDL инициируется команда COMMIT. j Это означает, что 
действие операторов DDL в СУБД Oracle отменить нельзя. 

    Команда SELECT 

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

    SELECT  CustomerNumber,   LastName,   State   FROM  CUSTOMER 


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

    Каждый пункт в списке полей оператора SELECT может представлять собой не 
просто название столбца, но выражение (expression column), включающее 
арифметические операции, константы и функции. Вот пример оператора 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 для 
преобразования всех символов полей и искомых значений к верхнему регистру. 

    Глава 16. Oracle 335 

    Следующий оператор возвращает список продаж на сумму более $500. 

    SELECT * FROM SALE WHERE Amount > 500 

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

    SELECT * FROM SALE 
    WHERE SaleDate BETWEEN Ч8-ОСТ-90' AND '20-MAY-95' 


    Объединения 

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

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

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

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

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

    SELECT  CUSTOMER.CustomerNumber,   SALE.Amount 
    FROM   CUSTOMER,    SALE 
    WHERE   CUSTOMER.CustomerNumber(+)=SALE.CustomerNumber 

    Обратите внимание, что для обозначения внешней таблицы объединения 
используется символ (+). Строки этой таблицы будут возвращаться независимо от 
удовлетворения условий объединения. 
    Для построения правых внешних объединений достаточно поставить символ (+) 
справа от правой таблицы. Следует заметить, что правые и левые внутренние 
объединения представляют собой одно и тоже, и поэтому не отличаются 
синтаксически.

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

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

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

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

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

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

    Помимо объединения с другими таблицами, любая таблица может быть 
объединена сама с собой. Этот тип объединений называется рефлексивным 
(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 

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

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

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

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

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

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

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

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

    Объем данных в декартовых произведениях при увеличении размеров таблиц 
возрастает по экспоненциальному закону. Даже из сравнительно небольших таблиц 
можно, таким образом, получить огромное количество данных. Например, декартово 
произведение двух таблиц по 100 строк будет содержать 10000 строк. Поэтому 
декартовых произведений следует по возможности избегать, особенно в больших таблицах. 

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

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

    SELECT * FROM CUSTOMER 
    WHERE CustomerNumber IN(SELECT CustomerNumber FROM SALE) 
    
    Глава 16. Oracle 337 

    GROUP  BY 

    Поскольку SQL является языком запросов, ориентированным на множества, 
операторы группировки данных — очень важная часть языка. Один-единственный 
оператор SQL может делать то же самое, что и 10, а то и 50, операторов 
обычного строчно-ориентированного кода. "Виновниками" этого являются ключевое 
слово 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? В диалекте Oracle (и языке SQL стандарта ANSI) нужно обязательно 
перечислять в этом списке всем не являющиеся вычисляемыми столбцы, включенными 
в список полей оператора SELECT. 

    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 BY используется для упорядочения строк в возвращаемом 
наборе. Вот пример его использования. 

    SELECT * FROM CUSTOMER ORDER BY STATE 

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

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

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

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

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

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

    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-программой, которая 
выполняется при каждом запросе. При обращении к представлению оптимизатор 
запросов находит оператор SELECT, используемый для создания представления, 
совмещает его с оператором, применяемым к представлению, и оптимизирует оба 
оператора, рассматривая их как один запрос. 
    Представления SQL создаются с помощью команды CREATE VIEW. Вот пример: 

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

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

    SELECT * FROM MOCUSTOMERS 

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

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

    Глава 16. Oracle	339 

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

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

    Хранимой процедурой (stored procedure) называется скомпилированная 
программа на языке SQL, которая хранится в базе данных вместе с другими 
объектами. Хранимые процедуры создаются командой GREATER PROCEDURE, пример 
которой на языке SQL СУБД Oracle приведен ниже. 

    CREATE  OR  REPLACE   PROCEDURE   increaseprices 
    AS 
    BEGIN 
    UPDATE   ITEM  set   Price=Price+(Price*.05); END; 

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

    CREATE  OR  REPLACE   PROCEDURE   increaseprices (increasepercent number) 
AS BEGIN 
    UPDATE   ITEM  set   Price= 
    Price+(Price*(increasepercent/100); END 


    Сценарии 

    Нередко бывает удобно конструировать операторы языка описания данных (Data 
Definition Language — DDL), в том числе хранимые процедуры, с применением 
файлов сценариев (script) SQL. Эти файлы можно редактировать в любом текстовом 
редакторе; в большинстве хороших редакторов SQL поддерживается сохранение 
содержимого сценариев на диске. Помните, что такие сценарии должны содержать 
все необходимые операторы USE и SET TERM. Запуск сценария Oracle SQL на 
выполнение производится выбором пункта Run an ISQL Script меню File программы 
SQL*Plus. В листинге 16.1 приведен пример файла сценария SQL. 

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

    CONNECT SCOTT/TIGER 
    SPOOL PRICE 
    PROMPT BUILDING PROCEDURE increaseprices 
    CREATE OR REPLACE PROCEDURE increaseprices (increasepercent number) 
    IS 
    BEGIN 
    UPDATE ITEM set Price= 
    Price+(Price*(increasepercent/100)); END / 
    SPOOL OFF EXIT; 

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

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

    Хранимые процедуры Oracle запускаются на выполнении по имени, с указанием 
необходимых значений параметров, например: 
    Increaseprices(5); 

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

    Триггеры 

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

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

    Этот триггер удаляет данные о продажах определенному покупателю из таблицы 
SALE, как только запись об этом покупателе удаляется из таблицы CUSTOMER. 
Такое удаление называется каскадным (cascading delete), поскольку операция 
удаления записи из одной таблицы вызывает каскад операций удаления данных в 
других таблицах, связанных с ней по ключу. 
    Обратите внимание на использование контекстной переменной OLD. Эта 
переменная служит для ссылки на значения, которые имели поля строки перед 
выполнением операций UPDATE или DELETE. Контекстная переменная NEW служит для 
ссылки на новые значения, которые должны вставляться в поля по командам INSERT 
ИЛИ UPDATE. 
    Обратите внимание также на использование ключевого слова BEFORE — триггер 
может срабатывать как перед (BEFORE), так и после (AFTER) выполнения операций 
INSERT, UPDATE или DELETE. 

    Курсоры 

    Курсоры (cursor) используются в языке SQL для обработки отдельных строк 
таблицы. Обычно курсоры не пишутся на языке SQL, а автоматически создаются 
системой BDE, но иногда они оказываются удобными для использования в хранимых процедурах. 
    Над курсорами выполняются четыре основные операции: объявление, открытие, 
извлечение данных и закрытие. С помощью курсоров можно также модифицировать и 
удалять строки таблицы. 
    Объявление курсора содержит оператор SELECT и (для модифицируемых 
курсоров) список модифицируемых полей. Вот пример такого объявления: 
    DECLARE CUSTOMER_SELECT CURSOR FOR SELECT * FROM CUSTOMER 
    Прежде чем считывать строки, используя курсор, его необходимо открыть. Для 
инициирования запроса, содержащегося в объявлении курсора, используется 
команда OPEN. 

    OPEN CUSTOMER_SELECT 

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

    FETCH CUSTOMER_SELECT 

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

    На заметку 
    Отсутствие в Oracle поддержки двунаправленных курсоров (bidirectional 
cursor) — это еще не повод не использовать их в приложениях Delphi. Система 
BDE эмулирует двунаправленные курсоры на уровне клиент-ной части приложения 
независимо от того, поддерживаются ли они платформой сервера. Вот почему по 
таким структурам данных, как TQuery и ттаЫе, можно передвигаться как вперед, 
так и назад. 

    Глава 16. Oracle 341 

    Строки, полученные из модифицируемого курсора, можно модифицировать с 
помощью специальных версий команд 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 


    Резюме 

    Эта глава содержит краткое введение в основные понятия и особенности СУБД 
Oracle. Данная СУБД сама по себе является предметом для отдельной книги. Тем 
не менее можно надеяться, что представленный здесь обзор значительно облегчит 
жизнь разработчикам приложений Delphi, которые должны взаимодействовать с Oracle. 

    Что дальше 

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

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