Вы находитесь на странице: 1из 492

С. Н. Смирнов, И. С.

Задворьев

Учебное пособие
2-е издание
исправленное и дополненное

Москва
"Гелиос АРВ'
2002
УДК 681.3.06
ББК 32.973.2
С 57

Смирнов С. И., Задворьев И. С.


С 57 Работаем с Oracle: Учебное пособие/ 2-е изд., испр.
и доп. — М: Гелиос АРВ, 2002. — 496 с.
ISBN 5-85438-048-Х

Книга "Работаем с Oracle" представляет собой быстрое вве-


дение в методы и средства распределенной СУБД Oracle. Рассмот-
рены методологические основы распределенной обработки ин-
формации, основные объекты базы данных Oracle, язык SQL —
базовое средство взаимодействия с сервером баз данных и его
процедурное расширение PL/SQL. Представляется возможность
получить углубленные знания по использованию SQL для работы
с большими базами данных. Особое внимание уделено технологи-
ям Oracle, обеспечивающим безопасность и целостность данных в
условиях многопользовательского доступа. В книге также содер-
жится описание средств, предназначенных для создания приложе-
ний на языке Java.
Книга ориентирована на студентов, молодых специалистов и
всех желающих самостоятельно познакомиться с Oracle — распре-
деленной СУБД для эффективной обработки данных.

УДК 681.3.06
ББК 32.973.2

ISBN 5-85438-048-Х © Смирнов С. Н., Задворьев И. С., 2002


© Оформление. Королев Н. А., Шачек Е. С., 2002
Азбука Oracle
К настоящему времени Oracle превратилась в настолько
мощную и развитую систему, что некоторые пользователи
подчас обнаруживают непонимание факторов, влияющих на
базовую производительность ее приложений. Эта книга, пре-
жде всего, направлена на то, чтобы показать, почему некото-
рые показатели оказывают определяющее влияние на общую
производительность, а другие — практически мало что меня-
ют. При этом авторы исходили из важного концептуального
принципа — среду прикладной системы нужно рассматривать
в едином комплексе, а не в виде набора отдельных модулей.
Ни для кого не секрет, что типичная среда разработки —
быстрая локальная сеть, малое число пользователей на высо-
копроизводительных рабочих станциях, до 100 строк в тесто-
вой таблице; обычная среда эксплуатации — медленная гло-
бальная сеть, большое количество пользователей на слабых
компьютерах, миллионы записей в таблицах. Поэтому в про-
цессе разработки какого-либо приложения общая производи-
тельность системы не исследуется, и проблема встает в пол-
ный рост только на этапе тестирования или, что еще хуже,
после ввода системы в эксплуатацию.
Вот тогда возникает необходимость либо кардинального
перепроектирования, либо существенного наращивания мощи
аппаратных ресурсов. Очевидно, то и другое связано с допол-
нительными затратами и, как правило, немалыми. Таким об-
разом, производительность системы не менее важна, чем про-
ектируемые функциональные возможности приложения.
Попытка так называемой "настройки" для решения про-
блемы не что иное, как желание превратить обычный "куку-
рузник" в сверхзвуковой "Конкорд". Ведь даже при использо-
вании самых лучших инструментов настройки достигаемый
эффект очень мал по сравнению с выгодой, получаемой от
работ по повышению производительности в период разработ-
ки.
Книга дает возможность практически оценить влияние
модификаций различных параметров системы, а также пре-
'
Предисловие

имущества и недостатки различных программных и аппарат-


ных настроек. Она может быть хорошим помощником не
только в процессе достижения желаемой системной произво-
дительности, но и в доступной форме объяснить, как система
функционирует в действительности, как определяются потен-
циально 'узкие места при расширении системы, когда уэели-
чивается количество пользователей, объемы обрабатываемых
данных или происходят изменения в организации бизнес-
процессов.
Учитывая, что среда разработки в Oracle обогатилась
многими новыми средствами, авторы дают возможность ре-
шения одной и той же задачи различными способами, помо-
гая читателю найти более эффективные инструменты, соот-
ветствующие назначению приложений.
Известно, что работа приложений Oracle во многом зави-
сит от функционирования компьютерной сети, и в то же вре-
мя, как-тправило, между специалистами по сети и разработчи-
ками приложений трудно наладить конструктивный диалог. В
этом смысле книга сближает названных участников процесса,
тем самым облегчая достижение целей, поставленных заказ-
чиком перед разработчиком.
Из теории очередей известно, что в многопользователь-
ских системах время реакции на запрос зависит от степени
использования ресурса (процессора, диска и т. д.) процессом,
обслуживающим запрос, и создаваемой при этом очередью.
Авторы дают конструктивные рекомендации по повышению
производительности системы на основе совершенствования
операций, выполняемых в разделяемом пуле.
В книге обращено особое внимание на операции оптими-
зации во время тестирования на реальном объеме данных,
когда даже небольшая настройка SQL-предложений может
значительно улучшить производительность системы.
Говоря о содержании книги, прежде всего, следует отме-
тить ее логичную структуру.
Начальные разделы книги формируют общее представле-
ние об архитектуре сервера Oracle, используемых инструмен-
4
Предисловие

тальных средствах и описанию языка SQL, который является


стандартом de facto в системах управления базами данных.
Далее раскрывается структура и базовые языковые конструк-
ции процедурного расширения языка SQL — PL/SQL. Этот
специфический для Oracle язык представляет собой мощный
инструмент для написания пользовательских программ и
триггеров.
В последующих разделах обсуждаются средства Oracle
обеспечивающие безопасность и целостность баз данных.
Рассмотрены как вопросы, связанные с языковыми средства-
ми разграничения доступа, так и средства повышения защи-
щенности системы, построенные на использовании представ-
лений и триггеров. Описание средств обеспечения целостно-
сти данных включает описание средств поддержки достовер-
ности данных средствами языка SQL, а также технологий за-
грузки данных из внешних источников, логической разгрузки
и восстановления данных.
Повсеместное распространение технологий обработки
данных, характерных для Интернет, делает весьма уместным
обсуждение средств построения приложений на языке Java.
Рассмотрена технология JDBC доступа к данным и интерфейс
процедур и функций, специфичных для сервера Oracle.
Финальная часть книги ориентирована на более подго-
товленного пользователя. В ней рассмотрены методы повы-
шения производительности Oracle. Сформулированы и про-
иллюстрированы правила оптимального написания SQL-
запросов, способы работы с оптимизатором Oracle, использо-
вание различных индексов. Доступно и внятно изложен под-
ход к построению объектно-ориентированных расширений
Oracle, появившихся в восьмой версии системы. Описаны
объектные типы и методы, наборы данных и объектные пред-
ставления.
Большим достоинством книги является наличие большо-
го числа примеров. Представленные 260 листингов иллюст-
рируют практически весь материал книги.
Предисловие

Предваряя непосредственное знакомство уважаемого чи-


тателя с содержанием достаточно серьезной работы авторов,
посвященной Oracle, хотелось бы сказать следующее.
Oracle продолжает доминировать на мировом рынке
СУБД, еще раз доказав свою лидирующую роль после пред-
ставления на рынке новой версии — Oracle 9i, включающей
два ключевых серверных продукта компании: Oracle 9i
Application Server и Oracle 9i Database. В новой версии, по
сравнению с предыдущей, сделано около четырехсот измене-
ний.
Сведение в новой версии семи с лишним десятков в но-
менклатуре серверных продуктов Oracle к двум базовым пре-
следует цель дать пользователям целостную среду разработки
Интернет-приложений. Главнейшее новшество в Oracle 9i —
это применение патентованной технологии кэширования,
дающей возможность существенного увеличения пропускной
способности при работе с Web-сайтами.
Другое новшество связано с техникой более эффективной
поддержки процедур date mining и data warehousing, интел-
лектуализирующих автоматизированные системы, расши-
ряющих возможности для аналитики и уводя СУБД все даль-
ше от простых процедур "учета-отчета".
Oracle 9i разрабатывалась с учетом активного использо-
вания средств, допускающих "аренду приложений" (ASP),
позволяющих платить за реально используемые возможности
СУБД по мере роста задач, стоящих перед организацией, а не
"про запас".
В версии Oracle 9i сделан шаг по сознательному отходу
от стандарта ANSI в угоду производительности СУБД; в
OLAP-машину Oracle встроен прямой интерфейс с Java, что
повышает реактивность SQL-запросов, генерируемых внеш-
ними Интернет-приложениями. Расширены возможности
объектных типов и реализовано долгожданное наследование
объектов. Упрощена процедура конфигурирования системы.
Получила дальнейшее развитие система виртуальных част-
ных БД (VPD), появившаяся в версии 8. Основная ее цель —
6
Предисловие

контролировать доступ к базам данных Oracle со стороны


Web-серверов. Говоря о возможностях Oracle, открывающих-
ся с появлением новой версии системы, хотелось бы подчерк-
нуть следующее.
СУБД Oracle относится к числу информационных техно-
логий с большим временем жизни. И здесь важно отметить,
что многие из новинок в Oracle 9i представляют собой даль-
нейшее развитие того, что уже имелось в версиях OracleS и 8i.
Думается, авторы в свойственной им доступной, наглядной и
вместе с тем достаточно строгой форме еще расскажут о раз-
витии Oracle в своей новой книге.
Но, учитывая, что новшества в системе Oracle зреют го-
дами, и не всегда они удаются, пользователям стоит осмотри-
тельнее относиться к увлечению ими. Тем более, что у Oracle
версии 8 к настоящему времени имеется солидный запас
прочности, и было бы разумным использовать этот запас по
максимуму. Такую возможность дает настоящая книга, по-
священная миру изящных решений и неисчерпаемых
возможностей Oracle.

В.А. Минаев,
доктор технических наук, профессор, академик РАЕН
Предисловие
ко второму изданию
Повсеместное распространение персональных компьюте-
ров и ориентированных на персональные компьютеры
средств обработки данных привело к тому, что для широкого
круга пользователей проблематика систем обработки данных
промышленного масштаба оказалась недоступной. Следстви-
ем ситуации явилось широкое распространение неверного
мнения, что система обработки данных, хорошо зарекомендо-
вавшая себя для персонального применения или применения
в небольшой группе, будет хорошо работать и в масштабе
отдела или предприятия в целом. Другое распространенное
заблуждение состоит в том, что при существенном увеличе-
нии объемов обрабатываемых данных можно обеспечить
приемлемые характеристики большой системы прямым на-
ращиванием мощности компьютеров.
Всякая абстрактная идея лучше всего воспринимается то-
гда, когда она иллюстрируется конкретным примером. Выбор
конкретной СУБД для иллюстрации изложения во многом
определяется вкусом авторов. Действительно, сервер OracleS
является наиболее интересным и функционально богатым
продуктом на современном рынке. Это мнение, видимо, раз-
деляют и коллективы, обеспечившие разработку и поддержку
большого числа крупномасштабных банковских систем и ин-
формационных систем больших предприятий. В то же время в
любой СУБД, поддерживающей распределенную обработку
данных, читатель легко найдет практически совпадающий
спектр проектных решений.
Цель данной-книги состоит в достаточно общем описании
концепции построения и возможностей СУБД Oracle. При
этом сервер Oracle рассматривается как ядро распределенной
многопользовательской системы обработки данных.
Второе издание книги существенно переработано. Замет-
но увеличился объем представленного материала. Тем не ме-
8
Предисловие

нее хотелось сохранить характерную для первого издания


ориентацию, в том числе и ценовую, на широкий круг читате-
лей, прежде всего, студентов. Поэтому при отборе материала
авторы решали непростую задачу выбора из богатейшего ар-
сенала средств Oracle наиболее важные для формирования
общего представления множества разумной мощности. На-
сколько решение этой задачи удалось — судить читателю.
Первый раздел книги должен дать общее представление о
компонентах распределенной вычислительной системы, ис-
пользуемых инструментальных средствах и архитектуре сер-
вера Oracle.
Второй раздел посвящен систематическому изложению
языка SQL. Учитывая место, занимаемое SQL в современных
информационных технологиях, его знание необходимо любо-
му специалисту, работающему в этой области.
В третьем разделе излагаются основы процедурного рас-
ширения языка SQL — PL/SQL. Это средство Oracle предна-
значено для реализации серверной бизнес-логики в виде со-
вокупности хранимых программ. Наличие встроенного языка
с богатыми возможностями для программирования процедур
и триггеров является важным преимуществом Oracle. Для
многих систем обработки данных оказывается достаточно
важным, чтобы и данные, и управляющие их обработкой
процедуры хранились и управлялись в логическом
пространстве СУБД. В отличие от интегрированных с СУБД
процедур, написанных на каком-либо из языков
программирования, которые выполняются в среде
операционной системы и хранятся в файлах, язык PL/SQL
позволяет создать прикладную систему, полностью
размещенную в базе данных и управляемую сервером Oracle.
В четвертом разделе книги обсуждаются средства разгра-
ничения доступа Oracle. Лучше предотвратить нарушение,
чем ликвидировать последствия нарушения информационной
безопасности системы. Oracle предоставляет возможности и
для предотвращения, и для выявления несанкционированного
использования ресурсов. Описание средств обеспечения
9
Предисловие

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


намических средствах разграничения доступа и использова-
ние средств аудита системы для фиксации действий пользо-
вателей.
В пятом разделе книге обсуждаются средства построения
приложений на языке Java, взаимодействующих с базами
данных. Технологию Java в сколько-нибудь полном виде
нельзя описать в одном разделе. Ее подробное изложение со-
ставит целую серию книг. Тем не менее в связи с развитием
Интернет обсуждение распределенной обработки данных без
изложения вопросов доступа к базам данных из приложений
на Java будет ущербным. В качестве необходимого минимума
изложены вопросы организации описания доступа к базам
данных из приложений на языке Java.
В шестом разделе идет речь о средствах обеспечения це-
лостности данных в Oracle. Модель предметной области, хра-
нимая в базе данных Oracle, должна быть достоверной. Для
обеспечения целостности данных существуют различные
языковые и программные средства. Языковые средства кон-
троля целостности в основном решают задачу автоматической
индикации (или запрещения) ввода данных подозрительных
на ошибочные, либо противоречащие ранее введенным дан-
ным или правилам, описывающим предметную область. Про-
граммные средства обеспечивают решение важнейшей задачи
восстановления данных. К сожалению, ситуация, когда база
данных разрушается, не является редкой. Для организации
обычно критически важно создать и поддерживать в работо-
способном состоянии технологию восстановления баз дан-
ных. Описанию соответствующих средств Oracle посвящен
этот раздел.
В седьмом разделе изучается крайне актуальная в на-
стоящее время тема — методы повышения производительно-
сти. Современные базы данных должны быть способны рабо-
тать с огромными объемами информации. И эти объемы бу-
дут расти из года в год, при этом базы данных не должны
деградировать в плане производительности. Для обеспечения
10
Предисловие

эффективной работы с большими и сверхбольшими базами


данных Oracle предназначены специальные методы и специ-
альные программные средства, описанные в седьмом разделе.
Восьмой заключительный раздел посвящен объектным
расширениям в OracleS. Использование методов объектно-
ориентированного программирования для создания надежных
систем широко используется при создании различных систем
обработки данных. Корпорация Oracle несколько расширила
границы традиционной реляционной модели данных, предос-
тавив проектировщикам баз данных новые инструменты: объ-
ектные типы, объектные представления и наборы данных.
Изложение проведено на уровне, позволяющем читателю со-
ставить представление об этой развивающейся ветви техноло-
гий Oracle.
Экономические потрясения индустрии информационных
технологий последних лет стали тяжелым испытанием для
всех фирм, делающих свой бизнес в этой области. Для многих
испытание оказалось последним. Несмотря на то, что Oracle
занимает достаточно узкую нишу в индустрии, что обычно
делает фирму достаточно уязвимой для экономических кри-
зисов, корпорация Oracle преодолевает период проверки на
выживаемость с минимальными потерями. Не в последнюю
очередь это связано с высоким качеством флагманского про-
дукта корпорации — сервера баз данных Oracle. Видимо, от-
цы-основатели и в первую очередь легендарный Ларри Элли-
сон заложили прочный фундамент и изящные и перспектив-
ные проектные решения в архитектуру системы управления
базами данных. В течение более чем тридцати лет система
развивалась и совершенствовалась. Сейчас ее описание зани-
мает несколько десятков томов документации.
Авторы выражают надежду, что эта книга станет нитью
Ариадны, которая поможет найти правильный путь к пони-
манию возможностей СУБД Oracle для построения систем
обработки данных.
В добрый путь, дорогой читатель!

11
Предисловие

Благодарности
Авторы выражают признательность за помощь в написа-
нии книги Сергею Саенко, Александру Знобищеву, Сергею
"Джихаду" Кургузову и Ольге Соколовой, а также благодарят
за оказанную техническую поддержку Валерия Чашкина и
Анатолия Моргунова.
Раздел 1
АРХИТЕКТУРА
РАСПРЕДЕЛЕННЫХ
СИСТЕМ ОБРАБОТКИ
ДАННЫХ

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


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

'13
'i
Раздел 1

Для более глубокого понимания состава и функций про-


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

14
Архитектура распределенных систем обработки данных

В основе любого языка программирования высокого


уровня лежит идея определения типовых единиц обработки,
то есть операндов, и базовых конструкций обработки, то есть
операторов. В роли типовых единиц обработки выступают
типы данных, например целый, вещественный, символьный и
т. п. В роли базовых конструкций обработки выступают опе-
раторы присваивания, ветвления и цикла," описания процедур
или подпрограмм, присутствующие практически во всех язы-
ках высокого уровня, операторные скобки, конструкция вы-
бора, специальные операции над строками и т. п., характер-
ные для некоторых языков и определяемые спецификой при-
менения.
На этом этапе развития систем обработки данных процесс
разработки постепенно утрачивал элементы ремесленничест-
ва и приобретал черты промышленного производства. Удель-
ная стоимость аппаратуры неуклонно снижалась, а относи-
тельная стоимость программного обеспечения росла.
Такая картина объясняется тем, что под каждую новую
задачу создавалась новая программа. Практически не уделя-
лось внимания вопросу совместимости программ по данным.
Совершенно ясно, что ввод исходных данных в задачах обра-
ботки информации является дорогостоящим делом. Наличие
собственных данных для каждой задачи приводило к дубли-
рованию хранимой информации и, как следствие, к значи-
тельным затратам, связанным с изменением данных и их син-
хронизацией.
Каков же должен был быть выход из сложившейся ситуа-
ции? Он следовал из логики развития программного обеспе-
чения. По аналогии с операционными системами и языками
программирования высокого уровня необходимо было соз-
дать языковые средства и соответствующее программное
обеспечение для выполнения функций, характерных для сис-
тем обработки данных.
Эта задача и решалась на третьем этапе развития автома-
тизированных систем. Особенность этого этапа — появление
средств, обеспечивающих техническую возможность опера-
15
Раздел 1

тивного доступа большого количества пользователей к ком-


пактно хранимым данным: запоминающих устройств прямого
доступа большой емкости, средств отображения и машинно-
ориентированных средств связи. Централизованное накопле-
•- ние, оперативный поиск и корректировка информации пред-
вещали качественный скачок в информационном обеспечении
управления. -Однако прогресс сдерживался низкими темпами
создания соответствующего программного обеспечения. По-
этому создаваемые программные комплексы должны были
обеспечить возможность удовлетворения информационных
потребностей пользователей с возможно меньшим объемом
работ, выполняемых программистами-профессионалами.
Для решения этой задачи было необходимо разработать и
реализовать средства общения пользователя с автоматизиро-
ванной системой более высокого уровня, чем язык програм-
мирования, то есть приблизить язык системы к языку, на ко-
тором формулирует свои запросы пользователь.
Централизованное накопление и обработка информации
возможны только при обеспечении согласованного представ-
ления пользователей о хранимых в системе данных. Но пред-
ставление различных групп пользователей о хранимых в сис-
теме данных отражает цели этих групп, которые могут сильно
отличаться друг от друга. Следовательно, согласованность
представления должна обеспечиваться некоторыми специ-
альными механизмами и соответствующими программными
средствами. Причем представление данных, а значит, и при-
кладные программы, не должны изменяться ни при измене-
нии физической организации хранимых данных, ни при
включении в рабету новых пользователей.
Таким образом, в процессе эволюции программного
обеспечения автоматизированных систем обработки инфор-
мации возникло четкое понимание возможности и целесооб-
разности разработки и реализации комплексов программ, ко-
торые позволяют описывать характерные для обработки дан-
ных операции на языке более высокого уровня. Такие ком-

16
Архитектура распределенных систем обработки данных

плексы получили названия системы управления базами дан-


ных (СУБД).
Можно выделить две черты, характерные для современ-
ных автоматизированных систем: разнообразие задач, решае-
мых различными пользователями на общей базе данных, и
постоянное улучшение аппаратных средств, предназначенных
для хранения и обработки данных. Следовательно, необходи-
мым условием существования СУБД является реализация (в
большей или меньшей степени) принципа логической и физи-
ческой независимости представления данных.
Логической независимостью данных называют возмож-
ность изменения логической структуры данных без измене-
ния существующих прикладных программ и технологии об-
работки данных. Наиболее типичной является ситуация уве-
личения или уменьшения числа обрабатываемых характери-
стик какого-либо информационного объекта.
Физической независимостью данных называют возмож-
ность изменения физической организации данных без пере-
стройки прикладных программ и логической структуры дан-
ных. Типичной ситуацией, когда необходимость этого требо-
вания очевидна, является организация доступа к данным с
использованием вновь созданного индекса.
Стремительное совершенствование технологии произ-
водства персональных ЭВМ привело к тому, что использова-
ние для обработки данных больших ЭВМ часто становится
нецелесообразным, если сравнивать их с настольными систе-
мами по критерию типа цена-производительность. Во многих
случаях роль центральной ЭВМ может выполнять достаточно
мощный сервер. Широкое распространение получили систе-
мы обработки данных на базе локальных вычислительных
сетей (ЛВС), представляющих собой группы компьютеров,
соединенных высокоскоростными линиями связи. Для таких
систем характерной чертой является то, что процессы обра-
ботки информации частично выполняются в месте ее получе-
ния, но наиболее ресурсоемкие процессы обработки инфор-
мации происходят на сервере.
11
Раздел 1

Эволюция реляционных
СУБД на фоне истории Oracle
Около двадцати лет назад молодые сотрудники неболь-
шой американской консалтинговой фирмы Ларри Эллисон,
Роберт Майнер и Эдвард Оутс решили открыть собственное
дело для создания коммерческой реляционной СУБД. За пять
лет, прошедших с момента первых публикаций классиков Э.
Ф. Кодда и К. Дж. Дэйта, идеи реляционных систем прочно
завоевали место в теоретических и экспериментальных ис-
следованиях в области автоматизированных систем обработ-
ки данных. Серия публикаций в научно-исследовательском
журнале фирмы IBM, в которых описывались проект реляци-
онной системы управления базами данных "System R" и язык
запросов SEQUEL2, привела к переводу проблемы в практи-
ческую плоскость.
Основной целью созданной тремя программистами фир-
мы Relational Software Incorporated была реализация перено-
симой реляционной системы управления базами данных с
поддержкой базового языка обработки данных SQL (Structure
Query Language — структурированный язык запросов). За два
года поставленная задача была решена.
В 1979 г. заказчикам была представлена версия СУБД для
мини-компьютеров PDP-11 фирмы Digital Equipment
Corporation сразу для нескольких ОС: RSX-11, IAS, RSTS и
UNIX. Чуть позже система была перенесена на компьютеры
VAX под управлением VAX VMS. Значительная часть кода
была написана на ассемблере, и поэтому процесс переноса
системы на новую платформу требовал значительных усилий.
Основным отличием СУБД очередной, третьей версии,
было то, что она была полностью написана на языке Си. Та-
кое решение обеспечивало переносимость системы на многие
новые платформы, в частности на различные клоны UNIX.

18
Архитектура распределенных систем обработки данных

Второй важной особенностью новой (1983) версии была


поддержка концепции транзакций. Системные средства га-
рантировали либо выполнение некоторой выделенной опера-
ции (транзакции) с базой данных, либо откат к состоянию на
начало транзакции, если операция по каким-либо причинам
завершилась неуспешно. Примерно в это время фирма полу-
чила новое имя — Oracle Corporation — и заняла лидирующее
место на рынке производителей СУБД.
Четвертая версия Oracle характеризовалась расширением
перечня поддерживаемых платформ и операционных систем.
Oracle был перенесен как на большие ЭВМ фирмы IBM
(мэйнфрэймы), так и на персональные компьютеры. Именно в
четвертой версии был сделан важный шаг в технологии под-
держки целостности баз данных. Для многопользовательских
систем было предложено оригинальное решение Oracle под-
держки "непротиворечивости чтения".
В пятой версии была впервые реализована СУБД с архи-
тектурой "клиент-сервер". Поражает умение идеологов фир-
мы видеть перспективу: ведь индустрия персональных ком-
пьютеров и локальных вычислительных сетей находилась в
тот период (1985) в младенческом состоянии. Именно тогда
было впервые реализовано средство SQL*Net, обеспечиваю-
щее поддержку сначала однородных, а некоторое время спус-
тя и неоднородных операционных сред обработки данных.
Впервые были разрешены распределенные запросы, то есть
запрос мог обращаться к данным, физически размещенным в
разных узлах, сети. Причем несколько взаимодействующих
серверов создавали впечатление единой логической базы дан-
ных.
Шестая версия Oracle была ориентирована на построение
крупномасштабных систем обработки данных с надежной и
эффективной обработкой транзакций. Серьезные изменения
претерпели методы реализации ввода-вывода, подсистема
управления буферизацией, подсистемы управления парал-
.лельным доступом, резервированием и восстановлением. Бы-
ла реализована поддержка симметричных мультипроцессор-
19
Раздел 1
ных архитектур, на которых сервер Oracle показывал хоро-
шую масштабируемость: при увеличении числа процессоров
пропорционально улучшались временные характеристики
системы обработки данных.
Седьмая версия Oracle была выпущена в конце 1992 г.
Эта версия обладала рядом новых решений, в основном свя-
занных с дальнейшим улучшением масштабируемости, отка-
зоустойчивости и производительности. .
В ней реализован логический сервер, состоящий из не-
скольких параллельных серверов с независимым одновре-
менным доступом процессов, расположенных на различных
узлах сети, к одним и тем же элементам базы данных и
управляющим файлам. Усовершенствованы средства и мето-
ды обеспечения безопасности и целостности данных. Введен
новый объект базы данных — роль, предназначенный для
структуризации и типизации решений в области разграниче-
ния доступа. Реализована поддержка профилей пользователя,
ограничивающих использование системных ресурсов. Для
настройки производительности системы включена команда
ANALYZE, позволяющая собирать статистику о данных для
ее использования оптимизатором запросов. Введен новый
объект базы данных — триггер. Триггер представляет собой
программу на процедурном расширении SQL — языке
PL/SQL, автоматически запускаемую сервером при наступле-
нии некоторых событий. Наличие триггеров открывает прак-
тически неограниченные возможности по формированию
проверок полномочий и допустимости действий, связанных с
данными.

OracleS. Основные возможности


Летом 1997 года корпорация Oracle выпустила на рынок
систему управления базами данных нового поколения —
OracleS. Она позиционируется как система, совершившая
прорыв в технологии обработки данных. Если абстрагиро-
20
Архитектура распределенных систем обработки данных

ваться от рекламно-маркетинговых заявлений, то сервер


OracleS действительно явился значительным шагом вперед и
заметно укрепил позиции Oracle Corporation как ведущего
производителя в области СУБД корпоративного уровня. Зна-
чительное продвижение технологии вперед, с одной стороны,
можно объяснить появлением объектных расширений реля-
ционной модели данных, то есть совершенно нового направ-
ления для Oracle. С другой стороны, в первую очередь
OracleS — это устойчивая, масштабируемая система управле-
ния реляционными базами данных, способная эффективно
хранить и обрабатывать огромное количество данных в усло-
виях многопользовательского доступа. Ядро сервера OracleS
было серьезно переработано на основе опыта разработки и
эксплуатации приложений для предыдущих версий, при этом
был получен значительный выигрыш в производительности и
надежности.
Рассмотрим основные направления, по которым фирма
Oracle совершенствовала свой основной продукт. Как и в лю-
бой новой версии программного обеспечения, в OracleS были
доработаны существующие механизмы и реализованы новые
возможности, отсутствующие в Oracle 7. Можно выделить
три основных новых направления: поддержка больших и
сверхбольших баз данных в режимах оперативных транзак-
ций и хранилищ данных, объектные расширения и встроенная
в ядро сервера Java-машина. Остановимся на них подробнее.
С помощью технологий Oracle возможно построить ин-
формационную систему, решающую сколь угодно сложные
задачи по обработке данных. Для этого в распоряжении про-
ектировщиков и разработчиков имеются все необходимые
инструментальные средства. Как было сказано выше, Oracle 7
оказалась очень удачной системой управления базами дан-
ных. На ее основе были построены системы, автоматизирую-
щие самые различные области человеческой деятельности. В
базах данных под управлением серверов Oracle было накоп-
лено огромное количество информации. Например, в таблицы
баз данных телефонных компаний каждый день загружаются
21
Раздел 1

десятки миллионов записей о разговорах абонентов. Со вре-


менем эти таблицы могут занимать дисковое пространство
объемом десятки терабайт. Разработчики и администраторы
баз данных некоторое время поддерживали производитель-
ность систем на приемлемом уровне с помощью обширных
возможностей Oracle 7 по настройке и оптимизации работы
сервера. Однако требовалась его специальная доработка для
поддержки больших и сверхбольших баз данных.
OracleS может управлять базой данных размером 512 пе-
табайт, а не 32 терабайта, как Oracle 7. Поэтому, наряду с оп-
тимизацией кода ядра сервера (например, вызов функций, на-
писанных на языке PL/SQL, из операторов SQL стал быстрее
на 40%), в OracleS появились новые возможности для управ-
ления большими и сверхбольшими базами данных. Кратко
перечислим их.
Секционирование таблиц и индексов — таблицы и ин-
дексы могут быть разбиты на секции, с каждой из которых
можно работать как с одним объектом, например хранить
различные секции на различных устройствах и управлять ими
автономно. В этом случае для таблицы или индекса выбира-
ется один или несколько столбцов — так называемый ключ
секционирования. Их значения определяют секцию, куда бу-
дет помещена запись. Например, для упоминавшихся выше
таблиц с записями телефонных разговоров ключом секциони-
рования может быть столбец, в котором хранится дата начала
разговора, а таблица может быть разбита на секции так, что-
бы в одну секцию попадали сведения о разговорах за один
месяц. В этом случае запрос, с помощью которого извлекают-
ся сведения о разговорах за последний месяц, не будет обра-
щаться к данным из других секций, в которых хранятся раз-
говоры за другие месяцы и будет получен значительный вы-
игрыш производительности. Для работы с секционированны-
ми таблицами и индексами требуется установленная опция
сервера — Partitioning option.

21
Архитектура распределенных систем обработки данных

Индексные таблицы — новый вид таблиц, позволяющий


организовать хранение данных непосредственно в индексах,
не используя сегменты данных.
Для оптимального доступа к данным была улучшена ра-
бота оптимизатора запросов: введен новый тип запросов —
типа "звезда", появились новые подсказки оптимизатору. Те-
перь поддерживаются новые виды индексов — масочные дво-
ичные индексы и индексы с реверсированным ключом. Также
внесен ряд изменений в существовавшие механизмы,
предназначенных специально для поддержки больших баз
данных. Подробно об этом рассказывается в разделах "SQL
— язык обработки данных Oracle" и "Методы повышения
производительности".
Другим важным нововведением для OracleS стала под-
держка объектных расширений. Тенденция к объектной ори-
ентированности в настоящее время наблюдается у всех круп-
ных производителей систем управления базами данных. Не
осталась в стороне и корпорация Oracle. OracleS поддержива-
ет абстрактные типы данных, то есть разработчик может кон-
струировать новые типы данных из базовых. Поддерживается
три абстрактных типа данных: OBJECT — для создания но-
вых типов объектов со своей внутренней структурой;
VARRAY — массив объектов определенного типа; TABLE —
таблица объектов определенного типа.
Для манипулирования хранимыми в СУБД объектами в
OracleS реализованы специальные расширения языка SQL.
Существует возможность создания так называемых объект-
ных представлений над реляционными таблицами. Это позво-
ляет вести разработку новых объектно-ориентированных
приложений в рамках существующих систем. Работе с объек-
тами посвящен раздел "Объектные расширения в OracleS".
Начиная с версии 8.1.5.0, ядро сервера Oracle включает в
себя Java-машину. Таким образом, стало возможным разраба-
тывать серверную компоненту системы как на основном язы-
ке создания хранимых программ PL/SQL, так и на Java. Про-
граммы, написанные на этих языках, могут взаимодейство-
23
Раздел 1 ;

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


возможность подключения сотен предопределенных классов.
Библиотеки Java-классов содержат методы, которые разра-
ботчики могут расширять и включать в свои программы.
Примеры написания хранимых Java-программ и их использо-
вания для манипулирования объектами базы данных приве-
дены в разделе "Создание приложений на языке Java". В на-
стоящее время наблюдается бум Java-приложений и можно
ожидать более интенсивного использования Java-машины
Oracle. Тем не менее написано огромное количество кода на
PL/SQL и в ближайшее время будет продолжаться его широ-
кое применение для разработки серверной логики, хотя уже
имеются средства для автоматического преобразования кода
PL/SQL в программы Java.
Как было отмечено выше, наряду с реализацией новых
возможностей, были значительно усовершенствованы суще-
ствующие механизмы сервера. Основные усовершенствова-
ния были предназначены для обеспечения удобства разработ-
ки новых приложений и повышения эффективности уже при-
меняемых. По мере изложения материала книги, усовершен-
ствованные механизмы описываются с той или иной степе-
нью детализации, а пока изложим их конспективно.
Динамический SQL в OracleS выполняется так же быстро,
как и обычный статический. Сокращено время при вызове
операторов SQL из PL/SQL и наоборот. Улучшены алгоритмы
работы с таблицами PL/SQL. Уменьшены потребности сессий
пользователей в оперативной памяти на 30-60%. Добавлена
отложенная проверка ограничений целостности, — она может
выполняться не сразу после выполнения операторов измене-
ния данных, а откладываться до фиксации транзакции.
Введены новые типы данных для хранения неструктури-
рованной информации. Для этого в Oracle 7 используются
типы данных LONG и LONG RAW, которые обладают рядом
недостатков. В OracleS появились новые типы данных: CLOB
(Character Large Object), BLOB (Binary Large Object) и BFILE,
свободные от этих недостатков. Эти типы данных не могут
24 .
Архитектура распределенных систем обработки данных

быть использованы в запросах, но их можно хранить как в


файловом пространстве, так и непосредственно в базе дан-
ных. При действиях с данными этого типа поддерживаются
все возможности транзакционной модели Oracle (за исключе-
нием тех объектов, которые хранятся как ссылки на объекты
файловой системы). Таким образом, сделан шаг вперед в на-
правлении технологии IPS (Internet File System), основная
идея которой — все объекты, с которыми работает пользова-
тель, хранятся в базе данных. При этом их хранение органи-
зовано прозрачно и операции копирования, удаления, измене-
ния и т. п. объектов выполняются так же, как будто бы они
хранились в файловой системе. Работа с большими объектами
рассмотрена в разделе "PL/SQL — процедурное расширение
языка SQL".
Существенно улучшены возможности реплицирования
данных. Ранее программный механизм реплицирования был
реализован как совокупность триггеров базы данных. Теперь
он перенесен в ядро сервера, а его работа стала быстрее и на-
дежнее.
Существенно расширился круг средств администрирова-
ния пользователей: Появилась возможность ведения политики
безопасности: принудительное блокирование учетной записи
пользователя, установка срока действия пароля, блокирова-
ние учетной записи пользователя после определенного числа
неудачных попыток входа в систему, программная реализа-
ция собственных алгоритмов проверки сложности пароля и т.
Д.
Как видим, внесено очень много усовершенствований в
те механизмы, которые OracleS унаследовал от предыдущих
версий. Их можно использовать как при разработке новых
приложений, так и при модификации существующих. Тем не
менее не стоит ожидать, что с переходом на новую версию
сервера базы данных эффективность существующих прило-
жений значительно увеличится сама по себе. Такой переход
требует еще раз пересмотреть технологию функционирования
всей системы. Некоторые операции действительно станут вы-
25
Раздел 1

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


например некоторые SQL-запросы могут для новой версии
сервера выполняться дольше. Поэтому при переходе, напри-
мер, даже с версии 8.1.6.0 на 8.1.7.0 требуется осторожность и
несколько этапов переноса серверной компоненты и доработ-
ки клиентской части и промежуточного уровня.
Сервер OracleS поставляется в нескольких конфигураци-
ях. Они отличаются друг от друга как наличием или отсутст-
вием дополнительных возможностей, так и серьезными архи-
тектурными решениями. Например, версия, предназначенная
для работы с мобильными устройствами, не поддерживает
язык PL/SQL, а только Java. OracleS Workgroup Edition в от-
личие от основного варианта OracleS Enterprise Edition не
поддерживает параллельную обработку данных, объектно-
реляционные расширения и секционирование таблиц. Более
подробные сведения о возможностях сервера Oracle можно
узнать из прилагаемой к нему документации (OracleS Server
Release Notes).
История Oracle показывает, что основные этапы развития
СУБД связаны с улучшением ее управляемости в условиях
многопользовательского доступа к данным, масштабируемо-
сти, совершенствованием системы распараллеливания опера-
ций на различных уровнях и повышением уровня защищен-
ности и целостности системы. Языковые средства системы
эволюционируют достаточно медленно. Принципиальным
моментом является распределенность СУБД, то есть наличие
в СУБД нескольких компонент, выполняющихся на различ-
ных компьютерах, объединенных в сеть.
Учитывая возможности масштабируемости, заложенные
в Oracle, рано или поздно система, построенная для решения
серьезной задачи, станет распределенной, построенной на
архитектуре клиент-сервер или многозвенной- архитектуре.
Перейдем к краткому описанию этих архитектур обработки
данных.

26
Архитектура распределенных систем обработки данных

Архитектуры обработки данных


При описании архитектур обработки данных использу-
ются разнообразные термины, поэтому дадим определения
основных понятий, используемых в книге. Следующие опре-
деления относятся к архитектуре "клиент-сервер".
Сервер определим как логический процесс, который обес-
печивает обслуживание запросов других процессов. Сервер
не посылает результатов запрашивающему процессу до тех
пор, пока не придет запрос на обслуживание. После иници-
ирования запроса управление синхронизацией обслуживания
и связей становится функцией самого сервера.
Подчеркнем, что в данном изложении термин "сервер"
используется в смысле логического процесса, а не узла вы-
числительной сети, выполняющего определенные функции. В
дальнейшем рассматриваются серверы баз данных. Сервер
баз данных —это логический процесс, отвечающий за обра-
ботку запросов к базам данных.
Клиента определим как процесс, посылающий серверу
запрос на обслуживание. В данном контексте мы абстраги-
руемся от технических средств, на которых реализован про-
цесс клиента. Главной особенностью, отличающей клиента от
сервера, является то, что клиент может начать взаимодейст-
вие с сервером, а сервер, как правило, никогда не начинает
подобных действий.
Функцией клиента являются инициирование установле-
ния связи, запрос конкретного вида обслуживания, получение
от сервера результатов и подтверждение окончания об-
служивания. Хотя клиент может запросить синхронное или
асинхронное уведомление об окончании обслуживания, он
сам не управляет синхронизацией обслуживания и связи.
Основным назначением архитектуры "клиент-сервер" яв-
ляется обеспечение прикладным программам клиента доступа
к данным, которыми управляет сервер. Архитектура "клиент-

27
Раздел 1

сервер" позволяет нескольким клиентам совместно эффек-


тивно использовать один сервер.
При использовании этой архитектуры высокая произво-
дительность распределенной автоматизированной системы
обеспечивается за счет эффективного управления передачей
запросов к серверу баз данных и возвратом полученных в ре-
зультате этих запросов данных клиенту. Клиент взаимодейст-
вует с сервером баз данных с помощью языка, ориентирован-
ного на работу с базами данных (обычно, это язык SQL). По-
сле обработки запроса клиента сервер баз данных посылает
клиенту обратно только данные, которые удовлетворяют за-
просу.
В этом состоит ключевое отличие рассматриваемого ме-
тода от метода обработки запросов, характерного для персо-
нальных СУБД, установленных в сети. При получении за-
проса файл, в котором находятся данные, полностью пересы-
лается по сети в компьютер клиента, где и происходит отбор
данных по критерию пользователя. В большинстве запросов
отбирается менее 1% данных, а трафик в сети оказывается
неоправданно высоким. Сеть перегружается пересылкой не-
нужных данных. Если пользователей несколько, то сеть бы-
стро приходит в состояние фатальной перегрузки.
Рассмотрим преимущества и недостатки архитектуры
"клиент-сервер". Путем распределения вычислений достига-
ется гибкость и масштабируемость системы: во-первых, каж-
дый компьютер в системе можно выбирать так, чтобы он
лучше всего подходил к требованиям каждого компонента.
Например, для сервера можно выбрать мощный многопро-
цессорный компьютер с большим объемом памяти под управ-
лением защищенной многопользовательской операционной
системы UNIX-класса. Такой сервер будет выдерживать тре-
буемый уровень нагрузки. Для рабочих станций, на которых
будет развернуто клиентское программное обеспечение, тре-
бования совсем другие. Как правило, это так называемый
офисный компьютер. Во-вторых, такая система обладает хо-
рошей адаптируемостью и гибкостью — в силу модульности
28
Архитектура распределенных систем обработки данных

легко можно заменить переставший удовлетворять требова-


ниям компонент или даже целиком какую-либо составляю-
щую. Например, заменить весь парк устаревших рабочих
станций. В-третьих, легко масштабировать систему, добавив в
нее новые рабочие станции или нарастив вычислительные
мощности на сервере.
Но наряду с такими ощутимыми преимуществами имеют-
ся и недостатки. Частые обращения клиента к серверу сни-
жают производительность работы сети, приходится решать
вопросы безопасной многопользовательской работы с дан-
ными, так как приложения и данные распределены между
различными клиентами. Распределенный характер построе-
ния системы обусловливает сложность ее настройки и сопро-
вождения. Чем сложнее структура системы, построенной по
технологии "клиент-сервер", тем выше вероятность отказа
любого из ее компонентов. В очень сложную проблему может
превратиться процесс смены клиентского программного
обеспечения, особенно если в системе работает большое чис-
ло рабочих станций.
Изложенные выше недостатки архитектуры "клиент-
сервер" стимулировали поиск новых архитектур обработки
данных, одним из результатов которого стала многозвенная
архитектура, свободная от некоторых недостатков своей
предшественницы. Интернет/интранет — магистральное на-
правление развития информационных технологий и много-
звенная архитектура специально предназначена для работы в
этой среде.
Была предложена идея распределения нагрузки между
тремя и более различными компьютерами. Клиент по-
прежнему выполняет функции предоставления интерфейса
пользователя и, возможно, некоторые не очень сложные и
ресурсоемкие операции обработки данных, другие этапы
функционирования системы теперь распределены между не-
сколькими компьютерами — серверами баз данных и серве-
рами приложений. Серверы баз данных управляют данными,

29
Раздел 1
а серверы приложений выполняют все вычисления, связанные
с реализацией безнес-логики приложениями.
Аналогично технологии "клиент-сервер" дадим ряд опре-
делений, существенных для описания многозвенной архитек-
туры. В ее состав входит универсальный клиент — определим
его как процесс, посылающий запрос на обслуживание и спо-
собный осуществить отображение его результатов на основе
некоторого универсального протокола выдачи информации.
Основное отличие универсальных клиентов от обычных —
способность предоставления пользователю интерфейса для
решения любых задач, низкая стоимость внедрения, админи-
стрирования и поддержки. Как правило, это браузер, про-
грамма просмотра сценариев на каком-либо языке разметки.
Браузер может поддерживать с помощью run-time расшире-
ний и другие форматы файлов. Приложения, используемые в
качестве таких расширений, хранят все свои файлы на клиен-
те. Когда браузер встречает вызов такого расширения, он за-
гружает соответствующие исполнимые файлы и запускает
приложение.
Сервер баз данных -— это логический процесс, отвечаю-
щий за обработку запросов к базе данных. Сервер приложе-
ний — совокупность логических процессов, реализующих
бизнес-логику на основании данных, предоставляемых серве-
ром баз данных и передающих результаты вычислений уни-
версальному клиенту через некоторую среду передачи дан-
ных. Администрирование и обслуживание приложений осу-
ществляются полностью на сервере приложений, а не на сто-
роне клиента, поэтому обновлять программные модули уни-
версального клиента (браузера) приходится довольно редко.
Основными экономическими преимуществами данной архи-
тектуры являются:
— относительно низкие затраты на внедрение и эксплуа-
тацию;
— высокая способность к интеграции существующих
информационных ресурсов;

30
Архитектура распределенных систем обработки данных

— прикладные программные средства доступны с любо-


го клиентского рабочего места;
— минимальный состав программно-технических
средств на клиентском рабочем месте.
Опираясь на концепцию многозвенной архитектуры,
Oracle предлагает три базовых элемента информационной
системы:
— сервер баз данных OracleS;
— универсальный сервер приложений Oracle Application
Server 4.0;
— набор драйверов в стандарте JDBC, специально опти-
мизированных для доступа из Java-программ к Oracle, а также
SQLJ — поддержка операторов SQL, встроенных в програм-
мы Java.
Этот набор не является жестко заданным. При проекти-
ровании конкретной системы следует учитывать все особен-
ности ее функционирования и, например, использование web-
сервера Apache и языка Perl может оказаться эффективнее
применения web-расширений языка PL/SQL для Oracle
Application Server. Кроме того, в интерпретации Oracle много-
звенная архитектура имеет еще одну особенность. Она изна-
чально задумана как расширяемая. Основной единицей рас-
ширения является картридж — клиентский, прикладной или
картридж данных, предусмотрены интерфейсы для их взаи-
модействия с другими компонентами информационной сис-
темы. Картриджи могут разрабатываться как производителя-
ми программного обеспечения, так и пользователями с уче-
том их возможного повторного использования. Существует
три типа картриджей.
Картриджи базы данных — функционируют внутри сер-
вера базы данных. Oracle предоставляет свои картриджи для
решения конкретных задач, например interMedia Text для об-
работки неструктурированных текстов. Также разработчики
могут реализовать на каком-либо языке программирования
свои картриджи. Например, для устранения недостатков ра-

31
Раздел 1

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


ки данных в сети. Это может быть как простейшая электрон-
ная почта, так и сложная асинхронная обработка разделяемых
баз данных. Совместная обработка данных позволяет под-
держивать общие базы данных в актуальном состоянии (ис-
пользуется только одна копия) и иметь индивидуальные или
локальные базы данных, которые каждый пользователь обра-
батывает по своему усмотрению.
В-третьих, появляется возможность повышения живуче-
сти системы обработки данных за счет какого-либо вида дуб-
лирования функций узлов.
Рассмотрим основные понятия, характеризующие аппа-
ратное обеспечение локальной вычислительной сети.
Сетевой адаптер — это специальное устройство, подклю-
чаемое к приемнику среды передачи данных. Основное на-
значение сетевого адаптера — взаимодействие со средой пе-
редачи данных, включая поддержку технологии передачи
данных в среде.
Среда передачи данных для локальной вычислительной
сети — как правило, это кабель, по которому распространя-
ются сигналы, переносящие данные в сети. Наибольшее рас-
пространение получили три вида кабеля: витая пара, коакси-
альный кабель и оптоволоконный кабель. В настоящее время
также все шире используются среды беспроводной передачи
данных.
Для обеспечения работы аппаратных компонент ЛВС на
приемлемом для пользователя языковом уровне необходима
операционная система. В настоящее время наибольшее рас-
пространение получили такие операционные системы, как
UNIX (включая многочисленные клоны: Solaris, HP-UX, AIX,
SCO и т. д.), Windows и NetWare. В большинстве этих систем
пользователю предоставляются многочисленные встроенные
средства выполнения операций в сети. Например, пользова-
тель может запустить на своем компьютере программу, ис-
полняемый код которой расположен на файловом сервере,
поставить документ в очередь для распечатки на сервере пе-
34
Архитектура распределенных систем обработки данных

чати или модифицировать данные, расположенные на сервере


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

Эталонная модель
взаимодействия открытых систем
Необходимость осмысления и управления сложными и
многообразными функциями, осуществляемыми различными
элементами вычислительной сети, привела к созданию кон-
цепции многоуровневого взаимодействия. Разделенные на
иерархически упорядоченные группы, несколько функцио-
нальных слоев, называемых уровнями, выполняют опреде-
ленную логическую функцию. При этом для элементов более
высокого уровня предоставляется определенный перечень
услуг.
С целью установления единых правил взаимодействия
вычислительных систем различных фирм-производителей,
Международной организацией стандартов (ISO — Inter-
national Standards Organization) в 1978 г. выпущен набор спе-
цификаций, описывающих структуру неоднородной сети. В
1984 г. на базе спецификаций неоднородной сети была при-
нята и рекомендована к использованию эталонная модель
взаимодействия открытых систем (QSI — Open System
Interconnection Reference Model). Данная модель является ме-
ждународным стандартом, описывающим взаимодействие
программных, и аппаратных компонент при организации ра-
боты компьютеров в сети.
Эталонная модель взаимодействия открытых систем
(ЭМВОС) определяет стандарты соединения и взаимодейст-
35
2*
Раздел 1

вия элементов вычислительной сети в процессе ее функцио-


нирования. Термин "открытая система" означает, что про-
граммное и аппаратное обеспечение элементов сети удовле-
творяет набору стандартов, точное соблюдение которых га-
рантирует возможность взаимодействия открытых систем
между собой.
Базовыми понятиями модели являются системы, при-
кладные процессы и сеансы. Под сеансом понимается про-
цесс обмена данными между прикладными процессами.
Иерархически упорядоченные прикладные процессы называ-
ются уровнями. Совокупность процедур взаимодействия объ-
ектов одного уровня называется протоколом. Совокупность
правил взаимодействия объектов смежных уровней называет-
ся межуровневым интерфейсом.
Таким образом, концепция ЭМВОС основывается на пе-
редаче информации между смежными уровнями, то есть
функция обмена данными является определяющей. Междуна-
родная организация стандартов рекомендует к использованию
семиуровневую модель взаимодействия прикладных процес-
сов. Уровни, упорядоченные снизу вверх, имеют названия
физический, канальный (в некоторой литературе использует-
ся термин "уровень управления линией передачи данных"),
сетевой, транспортный, сеансовый, представления и приклад-
ной.
Помимо деления на уровни в модели вводится единая
терминология для объектов. Для каждого уровня модель за-
дает цель его работы, виды услуг, обеспечиваемых для про-
цесса более высокого уровня, и определение функций каждо-
го уровня. Задача каждого уровня — предоставление услуг
более высокому уровню. При этом уровень одного узла рабо-
тает так, как если бы он был связан с соответствующим уров-
нем другого узла напрямую.
Прикладной уровень. Прикладной уровень обес-
печивает доступ прикладных процессов к среде взаимодейст-
вия открытых систем. Он выполняет функции "окна" между
взаимодействующими прикладными процессами, которые
36
Архитектура распределенных систем обработки данных

используют среду открытых систем для совместного решения


задач.
Функции прикладного уровня разделяются на две груп-
пы: общие и специальные. Первая дает средства взаимодейст-
вия, используемые рядом различных приложений (например,
средства организации связи между прикладными процесса-
ми). Вторая группа обеспечивает определенные потребности
конкретных приложений (например, обмен файлами, переда-
ча заданий).
Уровень представления. Назначением уровня
представления является представление данных, подлежащих
передаче между прикладными объектами, а также представ-
ление структур данных, на которые прикладные объекты
ссылаются в процессе обмена.
Уровень представления имеет дело с синтаксисом, то есть
с представлением данных, а не с их семантикой — смыслом,
известным только прикладным объектам. Представление дан-
ных в едином виде освобождает прикладные объекты от не-
обходимости заботиться о проблеме "общего" представления
информации, то есть обеспечивает для них независимость от
синтаксиса. Эта независимость от синтаксиса достигается
тем, что прикладные объекты могут использовать любой ло-
кальный синтаксис, а уровень представления обеспечивает
преобразование между этими синтаксисами и общим синтак-
сисом, необходимым для взаимодействия прикладных объек-
тов. Это преобразование выполняется внутри открытых сис-
тем. Оно не видно (прозрачно) для других открытых систем и
поэтому не оказывает влияния на стандартизацию протоколов
представления.
К функциям уровня представления относятся: запрос на
установление сеанса; передача данных; согласование выбора
синтаксиса; преобразование синтаксиса, включая преобразо-
вание данных, форматирование и специальные преобразова-
ния (например, сжатие или шифрование); запрос на прекра-
щение сеанса.

37
Раздел 1

Вариантов синтаксиса данных может быть три: синтак-


сис, используемый прикладным объектом-отправителем, син-
таксис, используемый прикладным объектом-получателем, и
синтаксис, используемый между представительными объек-
тами (синтаксис передачи). Любые два или все три синтакси-
са могут быть идентичными.
Уровень представления-содержит функции, необходимые
для выполнения преобразования между синтаксисом переда-
чи и каждым из остальных двух синтаксисов.
Согласование синтаксиса осуществляется посредством
диалога между представительными объектами для опре-
деления формы, которую будут иметь данные в процессе об-
мена в функциональной среде. В процессе согласования оп-
ределяется, какие преобразования необходимо выполнить
(если такая необходимость имеется) и где они должны вы-
полняться. Согласование может быть ограничено фазой ини-
циирования либо выполняться в любое время в ходе сеанса.
Сеансовый уровень . Назначение сеансового уров-
ня заключается в обеспечении сервиса, необходимого взаи-
модействующим представительным объектам для организа-
ции и синхронизации своего диалога и управления обменом
данными. Для этого сеансовый уровень предоставляет услуги
по установлению сеансового соединения между двумя пред-
ставительными объектами и поддержания упорядоченного
взаимодействия при обмене данными между ними. Для осу-
ществления передачи данных между объектами уровня пред-
ставления сеанс отображается на транспортное соединение.
Сеанс существует до тех пор, пока он не будет разъединен
соответствующими объектами. Во время существования сеан-
са его услуги поддерживают состояние диалога, даже несмот-
ря на потерю данных, которая может произойти на транспорт-
ном уровне.
Функции сеансового уровня сводятся к установлению и
разъединению сеансового соединения; обмену нормальными
и срочными данными; управлению взаимодействием; синхро-
низации сеанса; восстановлению сеанса.
38
Архитектура распределенных систем обработки данных

Транспортный уровень. Транспортный уровень


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

39
Раздел 1

там быть независимыми от особенностей маршрутизации и


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

40
Архитектура распределенных систем обработки данных

рых ретранслирует передачу бит внутри физического уровня.


Объекты физического уровня соединены друг с другом по-
средством физических средств передачи.
Функции физического уровня сводятся к активизации и
разъединению физического соединения, а также собственно
передаче данных.

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

'"
Раздел 1
производителя. После конфигурации программного обеспе-
чения сетевого адаптера необходимо определить используе-
мый сетевой протокол. Один адаптер может поддерживать
передачу данных по нескольким протоколам.
Используемый протокол определяет способ задания сете-
вого адреса. Каждый узел в сети должен иметь свой уникаль-
ный сетевой адрес. При создании распределенных систем на
базе Oracle чаще всего используется протокол ТСРЛР. Для
систем UNIX это — стандартный телекоммуникационный
протокол. Для Windows поддержка этого протокола встроена
в операционную систему.
Таким образом, первым шагом создания распределенной
системы обработки данных является правильное конфигури-
рование параметров сетевого адаптера, операционной систе-
мы и проверка работоспособности сетевого транспорта. Пра-
вильное конфигурирование и работоспособность сетевого
транспорта являются необходимыми условиями создания
распределенной системы обработки данных. Проверку функ-
ционирования транспорта можно выполнить программами
диагностики сети, например, утилитой ping. В листинге 1
приведен пример проверки функционирования сетевого
транспорта к компьютеру, имеющему сетевое имя ora_server.

C:\ping ora_server
Pinging ora_server [192.147.0.2] with 32 bytes of
data:
Reply from 1 9 2 . 1 4 7 . 0 . 2 : bytes=32 time=2ms TTL-128

Листинг 1. Проверка функционирования сетевого


транспорта

Сетевые средства Oracle обеспечивают поддержку трех


верхних уровней модели: сеансового уровня, уровня пред-
ставления и прикладного уровня. Совокупность сетевых
средств OracleS называется Net8 (ранние версии — SQL*Net).
Net8 организует взаимодействие приложений с сетевым про-
42
Архитектура распределенных систем обработки данных

граммным обеспечением. Уровень представления служит ин-


терфейсом между различными приложениями и программ-
ным обеспечение сеансового уровня. Например, сюда отно-
сятся драйверы Microsoft ODBC, которые позволяют органи-
зовать взаимодействие приложений с Net8. Некоторые при-
ложения могут обращаться напрямую к уровню представле-
ния и, следовательно, не нуждаются в программах сеансового
уровня. К ним относятся большинство утилит Oracle, а для
разработки собственных приложений целесообразно исполь-
зовать механизмы OCI.
Для поддержки используемого сетевого протокола при
установке клиентской части из перечня доступных средств
должен быть выбран подходящий адаптер протокола (напри-
мер, Oracle TCP/IP Protocol Adapter) и программное обеспе-
чение поддержки клиента Net8. После того как программные
компоненты Net8 установлены на рабочих станциях и серве-
рах, они должны быть правильно сконфигурированы.

Конфигурирование сетевых
компонент Oracle
Для настройки Net8 Oracle предоставляет специализиро-
ванные средства с графическим интерфейсом, например Net8
Easy Config. Тем не менее дадим некоторые общие сведения,
поясняющие суть процесса конфигурирования. Начнем с сер-
вера баз данных. Каждый сервер обладает именем. Имя сер-
вера относится к физической машине, на которой находится
база данных Oracle. В сети каждый сервер имеет свой кон-
кретный, уникальный адрес. Обратиться к серверу можно по
имени или по сетевому адресу. Для идентификации базы дан-
ных на сервере служит имя сервиса. Имя сервиса — это стро-
ковая переменная, включающая название базы данных и до-
мен. По умолчанию Oracle использует типовой домен .world.
Чтобы взаимодействие с сервером Oracle было возмож-
ным, на сетевом узле, где находится сервер баз данных, дол-
43
Раздел 1
жен быть запущен, как минимум, один прослушивающий
процесс. После его запуска, независимо от того, как он был
запущен, появляется возможность приема входящих запро-
сов, их обработки, а в случае разъединения сохраняется
возможность поддержки других соединений.
При запуске прослушивающий процесс считывает необ-
ходимую ему управляющую информацию из специального
файла параметров. Место расположения этого файла зависит
от операционной системы, его имя, как правило, listener.ora.
Чаще всего этот файл расположен в каталоге
$ORACLE_HOME/NETWORK/ADMIN (UNIX) или
%ORACLE_HOME\NET8\ADMIN (Windows), где переменная
ORACLE_HOME задает конкретный путь (например,
D:\ORANT). Упрощенный вариант файла listener.ora пред-
ставлен в листинге 2.

LISTENER_EDUC =
(ADDRESS_LIST =
(ADDRESS =
(PROTOCOL = TCP)
(Host = ora_server)
(Port = 1521) )
STARTUP_WAIT_TIME_LISTENER_EDUC = 0
CONNECT_TIMEOUT_LISTENER_EDUC = 10
TRACE_LEVEL_LISTENER_EDUC = ADMIN
SID_LIST_LISTENER_EDUC =
(SID_LIST =
(SID_DESC =
(SID_NAME = EDUC)))

Листинг 2. Содержание файла конфигурации прослу-


шивающего процесса listener.ora

Рассмотрим, какие параметры указываются в файле


listener.ora. С помощью одного файла можно настроить более
одного прослушивающего процесса, поэтому секция настрой-
ки конкретного процесса начинается с указания его имени. В
44
Архитектура распределенных систем обработки данных
/
нашем примере это — LISTENER_EDUC. Затем в секции
ADDRESS_LIST указывается нахождение сервера базы дан-
ных в сети и используемого для связи с ним протокола (пара-
метры PROTOCOL, HOST и PORT). Символическое имя сер-
вера ora_server должно быть правильно отображено на реаль-
ный IP-адрес. Настройку отображения должен выполнить ад-
министратор локальной сети с помощью соответствующих
сетевых служб. В файле listener.ora можно задавать и IP-
адрес.
. В следующем разделе файла listener.ora указывается спи-
сок экземпляров, баз данных и сервисов, с которыми взаимо-
действует прослушивающий процесс. В нашем примере это
раздел SID_LIST_LISTENER_EDUC. Параметр SID_NAME
содержит системный идентификатор базы данных (SID). Его
значение указывается при создании базы данных. Остальные
параметры необязательны и предназначены для тонкой на-
стройки прослушивающего процесса, например, параметр
CONNECT_TIMEOUT_LISTENER_EDUC устанавливает ко-
личество секунд, в течение которых прослушивающий про-
цесс ожидает получения запроса к базе данных.
Для запуска прослушивающего процесса предназначена
утилита Isnrctl. Следующий пример иллюстрирует ее исполь-
зование:

D:\ORANT\BIN>lsnrctl
LSNRCTL for 32-bit Windows: Version 8 . 1 . 5 . 0 . 0 -
Production on 04-FEB-02 19:12:18
(c) .Copyright 1998 Oracle Corporation. All
rights reserved.
Welcome to LSNRCTL, type "help" for information.
LSNRCTL> start
System parameter f i l e is
D:\0rant\net8\admin\listener.ora
.Listening on:
(ADDRESS=(PROTOCOL=TCP)(Host=ora_server)
(Port=1521))
STATUS of the LISTENER
45
Раздел 1

Alias LISTENER
Version TNSLSNR for 32-bit Windows: Version
8 . 1 . 5 . 0 . 0 - Production
Start Date 04-FEB-02 19:18:01
Uptime 0 days 0 hr. 0 min. 2 sec.
Trace Level off
Security ON
SNMP OFF
Listener Parameter File System parameter f i l e is~
D:\0rant\net8\admin\listener.ora
Services Summary...
EDUC has 1 service h a n d l e r ( s )
The command completed successfully

Листинг З. Протокол запуска прослушивающего про-


цесса с использованием утилиты Isnrctl

Существуют другие пути запуска прослушивающих про-


цессов. Например, в Windows для этого достаточно запустить
соответствующую службу, используя команды операционной
.системы.
Для настройки Net8 на рабочих станциях предназначен
конфигурационный файл tnsnames.ora. В нем хранится ин-
формация о локальных именах специального высокоуровне-
вого протокола Oracle TNS (Transparent Network Substrate).
Копии файлов конфигурации sqlnet.ora и tnsnames.ora должен
иметь каждый клиент. Эти файлы обычно располагаются в
каталоге %ORACLE_HOME\NET8\ADMIN (для Windows).
Файл tnsnames.ora содержит информацию о серверах и спосо-
бах связи с ними, которая для клиента именуется как строка
связи (connect string). Рассмотрим пример, когда для связи с
сервером используется протокол TCP/IP, порт 1521, а имя
сервера ora_server. Упрощенный вариант файла tnsnames.ora
представлен в листинге 4.

ORA8EDUC.WORLD =
(DESCRIPTION =
46
Архитектура распределенных систем обработки данных
(ADDRESS_LIST =
(ADDRESS =
(PROTOCOL = TCP)
(Host = ora_server)
(Port = 1521}))
(CONNECT_DATA = (SID = EDUCJ))

Листинг 4. Содержание файла конфигурации


tnsnames.ora

В файле tnsnames.ora требуется описать нахождение сер-


вера баз данных. Для этого служат параметры, указанные в
секции ADDRESS_LIST. Список параметров зависит от ис-
пользуемого протокола. Для TCP/IP необходимо указать
HOST и PORT. В разделе CONNECTION_DATA указывается
SID, в нашем примере EDUC, другие параметры служат для
тонкой настройки клиентской части Net8.
Таким образом, в файле tnsnames.ora указывается имя
сервиса или строка связи. Для соединения с базой данных
клиентская часть Net8 должна разрешить строку соединения,
то есть фактически установить сетевой маршрут к сервису,
который включает нахождение прослушивающего процесса
через протокольный адрес и глобальное имя базы данных,
содержащее как имя базы данных, так и имя ее домена. Кли-
ентская часть раскладывает глобальное имя базы данных на
составляющие, чтобы определить, с какой базой данных не-
обходимо связаться. После определения нахождения сервера
и имени базы данных клиентская программа обращается к
прослушивающему процессу, запущенному на этом сервере,
чтобы установить соединение с базой данных.
Когда клиент выполняет какие-либо действия, прослуши-
вающий процесс проверяет переданную ему информацию,
сверяет данные, зарегистрированные в сервисе базы данных
со своим файлом listener.ora, и выясняет, можно ли выпол-
нить запрос пользователя на соединение. Если все корректно
и соединение можно установить, то для обслуживания клиен-
та прослушивающий процесс создает новый пользователь-
47
Раздел 1

ский процесс или использует процесс, созданный заранее.


Именно этот процесс делает возможной связь между пользо-
вателем и базой данных. После того как данный клиентский
запрос обработан, процесс продолжает прослушивать сеть и
принимать новые запросы на соединение.
Для настройки соединений также служит файл sqlnet.ora.
Он содержит некоторые более тонкие параметры конфигура-
ции Net8, которые здесь не рассматриваются. Для большин-
ства простых систем файл sqlnet.ora изменять не требуется.
При необходимости работы с большим числом различ-
ных баз данных могут возникнуть проблемы с обновлением
файлов tnsnames.ora на клиентских компьютерах, особенно
если число компьютеров велико. В этом случае следует ис-
пользовать серверы Oracle Names.
Сервер баз данных — основа любой распределенной сис-
темы. Доминирование технологий Oracle в первую очередь
вызвано удачными решениями при проектировании своего
основного продукта.

Архитектура сервера Oracle


Высокое качество сервера Oracle как программного сред-
ства обеспечивается как использованием самых современных
максимально эффективно запрограммированных алгоритмов
обработки данных, так и хорошо спроектированной архитек-
турой. Внутренняя архитектура OracleS ориентирована на
обеспечение наибольшей производительности, безопасности
и эффективного использования вычислительных ресурсов.
Она позволяет обеспечить многопользовательский доступ к
большим объемам данных с сохранением их целостности и
непротиворечивости. Рассмотрим основные элементы архи-
тектуры для понимания того, как система управления базами
данных справляется с решением возложенных на нее задач.
Для работы сервера должны быть активными системные
и пользовательские процессы Oracle. К обязательным систем-
48
Архитектура распределенных систем обработки данных

ным процессам относятся: PMON — монитор процессов,


SMON ;— системный монитор, DBWR — процесс записи в
базу данных, LGWR — процесс записи в журнал. Дополни-
тельно к системным процессам для подключений к базе дан-
ных должны существовать пользовательские процессы. Поль-
зователь должен подключиться к базе данных, прежде чем он
сможет обратиться к какому-либо ее объекту. Пользователь-
ские процессы логически состоят из двух частей: кода серве-
ра, который транслирует и выполняет операторы SQL, читает
файлы и области памяти базы данных, и инструментальной
части, которая является исполняемым кодом используемого
программного средства.
Процессы в ходе своей работы используют файлы, сово-
купность которых является физическим представлением базы
данных. Существуют три основные группы файлов, состав-
ляющих базу данных: файлы базы данных, управляющие
файлы и журнальные файлы. В файлах базы данных распола-
гаются собственно данные, а управляющие и журнальные
файлы поддерживают функционирование сервера. Все три
набора файлов должны присутствовать, быть открытыми и
доступными Oracle.
Память, используемая, сервером Oracle, имеет следую-
щую структуру. Системная память для всей базы данных на-
зывается SGA (system global area — системная глобальная
область). Данные и управляющие структуры в SGA являются
разделяемыми и все системные и пользовательские процессы
могут к ним обращаться. Например, в SGA в течение некото-
рого времени хранятся дерево синтаксического разбора и
план выполнения для каждого оператора SQL и если проис-
ходит повторное выполнение такого же оператора, то повтор-
ный анализ не производится и используется находящийся в
SGA план выполнения. Таким образом, повышается быстро-
действие системы за счет устранения дублирования операций.
Для процессов Oracle выделяет PGA (process global area
— глобальную область процесса) в памяти сервера и, кроме
того, — PGA для системных процессов. Эта область памяти
49
Раздел 1

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


цесса и между процессами не разделяется.
Введем основополагающее определение экземпляра. Эк-
земпляр — это совокупность процессов, разделяющих опре-
деленную область памяти и управляющих одной или не-
сколькими базами данных. Обычно существует один экземп-
ляр для базы данных, хотя возможна работа нескольких эк^
земпляров с одним набором -файлов базы данных. Каждый
экземпляр может управлять одной или несколькими базами
данных. Каждая конкретная база данных имеет собственное
имя и соответствует некоторому экземпляру, под управлени-
ем которого она была создана. Для каждой базы данных су-
ществует ее файл конфигурации, который создается при вы-
полнении создании базы данных. Это обычный текстовый
файл и может быть изменен администратором базы данных в
целях настройки сервера. Параметры файла определяют зна-
чения ресурсов, ассоциированных с конкретной базой дан-
ных. Каждый раз, когда администратор запускает новый эк-
земпляр Oracle, для настройки конфигурации считывается
этот файл. Запущенный экземпляр получает уникальный
идентификатор — SID. После запуска администратором эк-
земпляра базы данных и ее открытия пользователи могут при-
соединяться к базе данных, но при этом пользователь должен
знать соответствующий идентификатор экземпляра. Обычно
информация об идентификаторе экземпляра описывается в
файле конфигурации Net8 и пользователь использует ее кос-
венно через указание строки связи.
Логически база данных — это множество разделов
(схем), каждая из которых идентифицируется своим именем,
уникальным в данной БД. Информация о структуре объектов
базы данных, их расположении, правах доступа и т. п., хра-
нится в словаре данных.
Словарь данных — база метаданных о собственно базе
данных. Информация словаря данных хранится в виде таблиц,
над которыми созданы многочисленные представления, и
пользователь, обладающий необходимыми правами доступа,
50
Архитектура распределенных систем обработки данных

может получить необходимую информацию по текущему со-


стоянию базы, используя запросы на языке SQL. Большинст-
во представлений словаря данных доступно любому пользо-
вателю. Назначение представления характеризуется его пре-
фиксом.
Все представления словаря данных можно разделить на
три группы: DBA-представления, содержащие информацию
обо всех объектах базы данных; ALL-представления, содер-
жащие информацию только о тех объектах, которые доступ-
ны пользователю; USER-представления, содержащие инфор-
мацию обо всех объектах базы данных, принадлежащих
пользователю. Например, сведения о таблицах, которые
находятся в схеме текущего пользователя, можно посмотреть
в представлении USER_TABLES.
Для просмотра текущей активности сервера можно ис-
пользовать специальные представления (с префиксом V$).
Например, сведения о текущих сессиях можно получить, об-
ратившись к представлению V_$SESSION.
После создания базы данных и ее запуска, требуется, ис-
пользуя учетные записи SYS или SYSTEM (пароль по умол-
чанию MANAGER, регистр в Oracle значения не имеет), вой-
ти в СУБД для создания учетных записей других пользовате-
лей. Наряду с системными учетными записями, как правило,
создается еще несколько. Например, учетная запись SCOTT
(пароль TIGER). Они предназначены либо для демонстраци-
онных примеров, либо для администрирования дополнитель-
ных продуктов и картриджей. Пароли пользователей SYS,
SYSTEM и других учетных записей, устанавливаемые по
умолчанию, рекомендуется сразу же изменить.
При установке с дистрибутива сервера Oracle автомати-
чески создается одноименный экземпляр сервера баз данных,
для которого в Windows создается автоматически запускаемая
при загрузке операционной системы служба.
Для большинства Unix-систем запуск экземпляра может
быть выполнен утилитой sqldba. Пример запуска экземпляра: .

51
Раздел 1

oracle@sun-server$ sqldba lmode=y


SQL*DBA: R e l e a s e , 8 . 0 . 5 . 0 - Production on Tue Feb
05 0 9 : 3 2 : 5 9 2002
Copyright (c) Oracle Corporation 1979, 1996. All
rights reserved.
OracleS Enterprise Edition ,0.5.0.0 - Production
With the Partition option
SQLDBA>connect internal
Connected.
SQLDBA>startup
ORACLE instance started.
Database mounted.
Database opened.
Total System Global Area 31140380 bytes
Fixed Size 49760 bytes
Variable Size 20817852 bytes
Database B u f f e r s 10240000 bytes
Redo B u f f e r s 32768 bytes
SQLDBA>exit
SQL*DBA complete.

Листинг1 5. - Протокол запуска экземпляра Oracle на


SUN Solaris • ' ' ,

Завершая работу с базой данных, администратор размон-


тирует ее, отсоединяя от экземпляра, а затем останавливает
экземпляр. В процессе останова сервера базы данных Oracle
завершает запущенные процессы и закрывает файлы опера-
ционной системы, в которых хранится информация базы дан-
ных.
Для большинства UNIX-систем останов экземпляра мо-
жет быть выполнен утилитой slqdba. Приведем пример оста-
нова экземпляра (oracle@sun-server$ — стандартная подсказ-
ка системы):

pracle@sun-server$ sqldba lmode=y


SQL*DBA: Release 8 . 0 . 5 . Q -- Production on Tue Feb
05 09:32:59 2002
52
Архитектура распределенных систем обработки данных
Copyright (с) Oracle Corporation 1979, 1996. All
rights reserved.
OracleS Enterprise Edition 8 . 0 . 5 . 0 . 0 - Production
With the Partition option
SQLDBA>connect internal
Connected.
SQLDBA> shut down
Database closed.
Database dismounted.
ORACLE instance shut down.
SQLDBA>exit
SQL*DBA complete.
oracle@sun-server$

Листинг б. Протокол останова экземпляра Oracle на


SUN Solaris

Для Windows достаточно остановить соответствующую


службу операционной системы.
В завершение проследим этапы обработки оператора
SQL. Ниже приводится алгоритм выполнения оператора
SELECT, осуществляющего выборку данных:
— пользователь запускает на рабочей станции приложе-
ние (например, SQL*Plus), вводит имя пользователя Oracle и
пароль;
— Oracle подтверждает имя пользователя и пароль, све-
рившись со словарем данных, и посылает ответ приложению
для подтверждения соединения;
— пользователь вводит оператор SQL, используя тексто-
вый редактор приложения;
— Oracle должен произвести разбор этого оператора
прежде, чем выполнить его, поэтому вызывается синтаксиче-
ский анализатор и оптимизатор Oracle. Если бы какой-либо
пользователь ранее уже ввел точно такой же оператор, "разо-
бранная" версия могла бы находиться в области разделяемого
пула в памяти. Oracle в этом случае использует результаты
разбора, так что для данного оператора никакой дополни-
тельный анализ не выполняется;
53

.
Раадел 1

— чтобы транслировать оператор, Oracle должен полу-


чить имена объектов, указанных в операторе, и другую ин-
формацию из словаря данных. Если пользователь выполняет
оператор сразу после запуска базы, то область кэша словаря
данных не содержит информации о таблицах. Поэтому анализ
оператора приостанавливается для считывания информации;
— Oracle выполняет рекурсивный оператор SQL (опера-
тор, генерируемой системой), чтобы загрузить информацию
об объектах из таблиц словаря данных, находящихся в файлах
базы данных, в кэш словаря данных в памяти;
— разбор исходного пользовательского оператора про-
должается, и оптимизатор Oracle строит план выполнения
запроса, чтобы определить способ выполнения оператора;
— оператор обращается к данным. Предположим, что
блоки данных таблиц не находятся в буферном кэше. Требуе-
мые блоки Oracle читаются из файлов базы данных и переда-
ются в область кэша SGA;
— Oracle выполняет оператор и возвращает пользовате-
лю результаты.
Выбор конкретного средства для работы с базой данных с
помощью SQL — дело вкуса и привычки, поэтому в даль-
нейшем, если это не оговорено особо, будет приводиться
только содержательная (текстовая) часть команд и сообщений
системы без отображения конкретного интерфейса того или
иного средства. Как правило, таким средством служит
SQL*Plus.
Использование
инструментального средства
SQL*Plus
В составе серверной или клиентской части Oracle на ком-
пьютер по умолчанию устанавливается приложение SQL*Plus
— стандартная утилита Oracle для выполнения операторов
SQL, администрирования базы данных и т. д. С помощью
54
Архитектура распределенных систем обработки данных

SQL*Plus удобно вводить, редактировать, сохранять и запус-


кать операторы SQL и программы PL/SQL, выполнять дейст-
вия по установке и настройке базы данных, форматировать,
сохранять и печатать отчеты. Остановимся подробнее на ос-
новных возможностях SQL*Plus. Дополнительные средства,
такие, как обмен сообщениями между пользователями, пере-
мещение данных, автотрассировка и т. п., мы здесь рассмат-
ривать не будем.
Для запуска приложения SQL*Plus достаточно, щелкнув
по соответствующей иконке Windows, заполнить поля формы
именем пользователя и паролем, а в поле строка связи ввести
ссылку, указанную в файле tnsnames.ora. Менее естественно,
но возможно запустить SQL*Plus и из меню запуска про-
грамм Windows, введя строку plusSOw.
Заметим, что конкретное имя программы зависит от кон-
кретного варианта поставки. Каждый раз, когда запускается
SQL*Plus, выполняются команды SQL*Plus и SQL-
операторы, которые находятся в файлах login.sql и glogin.sql.
Путь к этим файлам указывается в переменных окружения. С
их помощью можно, например, настроить параметры созда-
ваемой сессии. После подключения и выполнения сценариев
файлов login.sql и glogin.sql в окне приложения SQL*Plus
появится информация о подключении, параметрах базы дан-
ных и строка-приглашение.

SQL*Plus: Release 8.0.5.0.0 - Production on Fri


Jan 4 14:44:6 2002
(c) Copyright 1998 Oracle Corporation.
All rights reserved.

Connected by:
OracleS Enterprise. Edition, Release 8.0.5.0.0 -
Production
With the Objects option
PL/SQL Release 8.0.5.1.0 - Production
SQL>

55
Раздел 1

В SQL*Plus можно выполнять: операторы SQL; програм-


мы PL/SQL; команды SQL*Plus.
Вводимые операторы SQL могут расподагаться на одной
или нескольких строчках. Терминальным символом для них
служит ";" или "/". Самый простой способ выполнить опера-
тор SQL в среде, SQL*Plus— в строке-приглашении ввести
текст оператора, нажать клавишу enter, в следующей строчке
ввести символ "/" или ";", и еще раз нажать enter.

SQL> SELECT USER FROM dual


2 /

USER

Ul

Листинг 7. Выполнение SQL-оператора в SQL*Plus

Команды и операторы запоминаются в SQL-буфере —


очень удобная особенность SQL*Plus. Содержимое SQL-
буфера можно повторно выполнить, сохранить на диске, от-
редактировать в текстовом редакторе. SQL-буфер не очища-
ется до тех пор, пока не начнется ввод очередного предложе-
ния SQL или блока PL/SQL. Для просмотра содержимого бу-
фера используется команда LIST.

SQL> LIST
1* SELECT USER FROM dual ,

Листинг 8. Просмотр содержимого SQL-буфера

Для программ PL/SQL порядок их ввода несколько иной


— каждый блок PL/SQL начинается с зарезервированного
слова DECLARE, или, если блок не имеет декларативной час-
ти, со слова BEGIN. Ввод любого из этих слов заставляет
56
Архитектура распределенных систем обработки данных

SQL*Plus очистить SQL-буфер, войти в режим ввода и игно-


рировать ";" как терминальный символ. Заканчивая ввод бло-
ка PL/SQL, можно не вводить одиночную точку. Если вместо
точки ввести в очередной строке одиночную наклонную чер-
ту (/), то блок PL/SQL сохранится в SQL-буфере и выполнит-
ся. Если SQL-буфер содержит оператор SQL или программу
PL/SQL, то для их выполнения нужно ввести команду RUN
или просто наклонную черту:

SQL> set serveroutput on


SQL> BEGIN
2 DBMSJDUTPUT.PUT_LINE(SYSDATE);
3 END;
4 /

08-04-2002

PL/SQL procedure successfully completed.

Листинг 9. Выполнение в SQL*Plus блока PL/SQL

Для просмотра ошибок при компиляции программ


PL/SQL можно использовать команду SHOW ERRORS.
Любое SQL-выражение или программу PL/SQL можно
сохранить в текстовом файле из SQL*Plus с помощью коман-
ды SAVE. Для редактирования этого файла можно использо-
вать редактор SQL*Plus. Для того чтобы снова сохранить его,
требуется ввести команду SAVE ... REPLACE. Для использо-
вания другого текстового редактора требуется выполнить ко-
манду EDIT. При этом запустится указанный в настройках
SQL*Plus текстовый редактор. Если имя файла не указывать,
то SQL*Plus сохранит содержимое SQL-буфера в файл и от-
кроет этот файл в редакторе. После редактирования и сохра-
нения изменений в файле его содержимое SQL*Plus перепи-
шет в SQL-буфер. Чтобы загрузить файл в буфер, используйте
команду GET. Примеры этих команд приведены ниже.
57

-.
Раздел 1

SAVE имя_файла
SAVE имя_файла REPLACE
EDIT имя_файла
GET имя_файла
X '

В операторах SQL и анонимных блоках PL/SQL можно


использовать средства подстановки переменных SQL*Plus.
SQL* Plus будет запрашивать значение каждой переменной,
имеющей префикс &, перед выполнением оператора SQL или
блока PL/SQL. Например, перед выполнением следующего
запроса SQL*Plus запросит значение atl:

SQL> SELECT COUNT(1) с FROM Tab!


2 WHERE Atl=&atl;

Enter value for atl: 2


old.1: SELECT COUNT(l) с FROM Tabl WHERE Atl=&atl
new 1: SELECT COUNT(1) с FROM Tabl WHERE At1=2'

10

Листинг 10. Использование переменных подстановки


SQL*Plus

Из SQL*Plus можно вызывать хранимые программы с


помощью команды EXECUTE, не используя конструкции
BEGIN ... END, В следующем примере вызывается процедура
DBMS OUPUT.PUT LINE:

SQL> set serveroutput on


SQL> EXECUTE DBMS_OUTPUT.PUT_LINE('Kello, word');
Hello, word

Листинг 11. Использование команды EXECUTE


58
Архитектура распределенных систем обработки данных

В том случае, если SQL*Plus используется для получения


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

SQL> set line 250


SQL> col sid format a3
SQL> col serf format a5
SQL> col program format a40
SQL> col username format a8
SQL> col osuser format a8
,SQL> col machine format a8
SQL> col command format alO
SQL> set heading on
SQL> SELECT s.sid sid,
2 s.serial sertt,
"3 s.username username, s.osuser, s.machine,
4 substr (upper (s .program) , 1, 60) program,,
5 substr(a.name,1,13) command
6 .FROM v$session s, sys.audit_actions a
7 WHERE a.action=s.command
8 AND s.sid>5
9 ORDER BY 1,2
10 ./ -

SID SER# USERNAME OSUSER MACHINE PROGRAM COMMAND

9 4 Ul UD DFORT PLUS80W SELECT

Листинг 12. Форматирование отчетов в SQL*Plus

Здесь мы с помощью команд COLUMN и SET HEADING .


установили вывод заголовков столбцов и их ширину. Более
полное руководство по использованию SQL*Plus можно по-
лучить в разделе документации Oracle SQL*Plus User's Guide
and Reference.
Следует отметить, что для работы с Oracle существуют
более удобные интегрированные средства. В частности, это
программные продукты фирмы Quest Software: SQL
Navigator, Instance Monitor, TOAD и другие. Ознакомитель-
ные версии программ находятся на сайте компании —
www.quest.com.
59
Раздел 1

Информация о результатах
операции
Выполнение какой-либо операции клиентского приложе-
ния или оператора SQL на сервере может завершиться с раз-
личными итогами. Успешность завершения операции опреде-
ляется значениями возвращаемых ею параметров, характери-
зующих итог выполнения операции, *ши сообщениями об
ошибках. Сообщения об ошибках специфичны для различных
продуктов Oracle. Во всех сообщениях об ошибках указыва-
ется префикс, указывающий на то, какое приложение выдает
ошибку. Например, префикс IMP указывает на то, что ошибка
произошла при импорте данных с использованием утилиты
импорта.
Для сервера Oracle ошибки имеют префикс ORA, а соот-
ветствующие параметры передаются в форме двух кодов за-
вершения: SQLCODE, SQLERRM. Значение SQLERRM со-
держит развернутое текстовое сообщение об ошибке с указа-
нием ее причин. Пятисимвольное значение параметра
SQLCODE определяется международным стандартом, фор-
мируемым Международной организацией стандартизации
(ISO). Нулевое значение параметра свидетельствует об ус-
пешном завершении операции, отрицательные значения соот-
ветствуют завершению операции с некоторой ошибкой, л по-
ложительные — завершению с предупреждением о возмож-
ной ошибке или предназначены для передачи параметров,
характеризующих особенности завершения операции (напри-
мер, отсутствие данных, удовлетворяющих критерию запро-
са).
Таким образом, это — две различные формы представле-
ния информации, характеризующей успешность завершения
оператора языка SQL.
Для облегчения поиска причин ошибок и их исправления
в сообщениях об ошибках указываются имена объектов, при
60
Архитектура распределенных систем обработки данных

операциях над которыми произошли ошибки, типы ошибок и


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

IMP-00058: ORACLE error 1017 encountered


ORA-01017: invalid username/password;logon denied
IMP-00005: all allowable logon attempts failed
IMP-00000: Import terminated unsuccessfully

При подключении к базе данных произошла ошибка, о


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

ORA-00600: internal error code,


arguments:[num],[],[], U , U , U

За текстом сообщения может встретиться до 6 аргумен-


тов, которые указывают происхождение и признаки ошибки.
Первый аргумент — номер внутренний ошибки. Другие ар-
61
Раздел 1

гументы — различные числа и символьные значения. При


появлении сообщения о внутренней ошибке авторы отдель-
ных публикаций рекомендуют поздравить пользователя: "С
этого момента Вы — настоящий ораклоид" и обратиться в
службу технической поддержки Oracle. Практическая же ре-
комендация — регулярно выполнять полный экспорт базы
данных и при серьезных сбоях восстанавливать ее с резерв-
ной копии.

Поддержка мультиязычности
в Oracle
Для корректной работы приложений с русским языком
требуется специальная настройка. Поддержка национальных
языков Oracle (National Language Support — NLS) позволяет
взаимодействовать с сервером на различных языках, поддер-
живая различные схемы кодирования символов. Oracle под-
держивает как однобайтовые, так и мультибайтовые схемы.
Поскольку зависящие от языка данные хранятся отдельно от
обрабатывающего их кода, можно легко добавлять новые
языки и зависящие от языка средства, не изменяя приложе-
ний. Символьный набор, который будет использоваться для
хранения данных в базе, определяется при ее создании. На-
стройке также подлежат язык вывода сервером информаци-
онных сообщений, чисел, дат и т. д.
Для конфигурирования NLS предназначены параметры.
NLSJLANGUAGE и NLSJTERRITORY. Они определяют ис-
пользуемый по умолчанию формат дат, чисел и других
свойств обработки данных. Просмотреть текущие значения
параметров NLS можно в системном представлении
V$NLS_PARAMETERS, а изменить оператором ALTER
SYSTEM (ALTER SESSION). Изменение параметров NLS
также можно осуществить на уровне сессии или даже одного
оператора.

62
Архитектура распределенных систем обработки данных

Рассмотрим использование параметров NLS в функциях


SQL. Все символьные функции поддерживают как однобай-
товые, так и мультибайтовые символы. Все функции SQL,
поведение которых зависит от параметров NLS, позволяют
специфицировать параметры NLS. Это функции TO_CHAR,
TOJDATE, TO_NUMBER, NLSJUPPER, NLS_LOWER,
NLSJNITCAP, NLSSORT.
Обычно строки символов сравниваются через их двоич-
ные значения. Один символ "больше" другого, если он имеет
большее двоичное значение в наборе символов базы данных.
Поскольку упорядоченность символов по их двоичным зна-
чениям может не соответствовать алфавитной упорядоченно-
сти, такие сравнения могут нарушать правила национального
языка.
Механизм лингвистической сортировки работает путем
замещения каждой сортируемой строки символов двоичной
строкой, формируемой по некоторым правилам. Сравнение
строк во фразе WHERE с помощью NLSSORT позволяет при-
ложениям выполнять сравнения строк в соответствии с со-
глашениями национального языка.Можно гибко использовать
параметры NLS в конкретных функциях и операторах SQL,
независимо от текущих значений параметров NLS. Это хоро-
шо демонстрирует пример оператора, которые содержат чис-
ла и даты в виде строк. Следующий оператор выполняется
корректно лишь в том случае, если используется язык
RUSSIAN и задан подходящий формат даты по умолчанию:

SELECT * FROM Tab! -


WHERE A t l > '20-ФЕВ-2001'

Чтобы сделать оператор независимым от параметров


NLS, следует использовать функции преобразования типов,
например:

SELECT * FROM Tab!


WHERE Atl > TO_DATE('20-02-2001','DD-MM-YYYY')

63
Раздел 1

ИЛИ

SELECT * FROM Tab!


WHERE Atl>TO_DAT.E( ' 20-FEB-2001' , ' DD-MON-YYYY',
1
NLS_DATE_LANGUAGE = AMERICAN')

На наш взгляд, предпочтительным является первый вари-


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

64
Архитектура распределенных систем обработки данных

Соглашения, принятые
для описания команд
В книге используются приведенные ниже соглашения для
представления синтаксиса команд.

Символ "верти- 1 Любой, предшествующий знаку |,


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

65

3. Заказ № 1628.
Раздел 2

SQL — ЯЗЫК
ОБРАБОТКИ ДАННЫХ
ORACLE

SQL является фактическим стандартом языковых средств


обработки данных для современных СУБД. Практически ка-
ждый производитель СУБД определяет собственный вариант
языка, учитывающий особенности архитектуры и позициони-
рование системы на рынке. В настоящее время существуют
три стандарта языка SQL, принятых Американским Нацио-
нальным Институтом Стандартов (ANSI): SQL89, SQL92,
SQL3. Каждый последующий стандарт в этой цепочке уточ-
няет и расширяет предыдущий. Следование стандартам не
является обязательным, хотя практически все производители
систем управления базами данных строго выполняют требо-
вания стандарта SQL89 и, в значительной части, — требова-
ния SQL92.
Операторы SQL можно разбить, на несколько отдельных
групп: DML (Data Manipulation Language) — операторы ма-
нипуляции данными, DDL (Data Definition Language) — опе-
раторы определения данных, группа операторов управления
транзакциями и группа операторов предоставления доступа.
Операторы DDL предназначены для создания, модификации
и удаления объектов базы данных.

66
SQL — язык обработки данных Oracle

Основные объекты Oracle


Oracle поддерживает реляционную модель данных, по-
этому естественно, что к числу основных объектов базы дан-
ных относятся: таблица, представление и пользователь.
Пользователь (USER) — объект, обладающий воз-
можностью создавать и использовать другие объекты Oracle,
а также запрашивать выполнение функций сервера. К числу
таких функций относится организация сессии, изменение со-
стояния базы данных и др. Следует отметить, что в некоторых
других системах управления базами данных, например, IBM
DB2, объект базы данных "пользователь" отсутствует. С
пользователем Oracle связана схема (SCHEMA), которая яв-
ляется . логическим набором объектов базы данных, таких,
как таблицы, последовательности, хранимые программы,
принадлежащих этому пользователю. Схема имеет только
одного пользователя-владельца, ответственного за создание и
удаление этих объектов. При создании пользователем первого
объекта неявно создается соответствующая схема. При созда-
нии им других объектов они по умолчанию становятся частью
этой схемы. Для просмотра объектов схемы текущего пользо-
вателя можно использовать представление словаря данных
USER_OBJECTS.
При массовом выполнении DDL-предложений можно
создать несколько объектов и назначить для них привилегии
за одну операцию, используя оператор CREATE SCHEMA. _
Оператор CREATE SCHEMA применяется тогда, когда тре-
буется гарантировать успешное создание всех объектов и на-
значение привилегий за одну операцию. Если при создании
объектов произошла ошибка, происходит возвращение к
исходному состоянию.
Схема может содержать следующие объекты: кластеры,
связи баз данных, триггеры, библиотеки внешних процедур,
индексы, пакеты, последовательности, хранимые функции и

67
Раздел 2

процедуры, синонимы, таблицы, представления, снимки, объ-


ектные таблицы, объектные типы, объектные представления.
Объекты схемы могут состоять из других объектов, назы-
ваемых подобъектами схемы. К ним относятся столбцы таб-
лиц и представлений, секции таблиц, ограничения целостно-
сти, триггеры, пакетные процедуры и функции и другие эле-
менты, хранимые в пакетах (курсоры, типы и т. п). К объек-
там, не принадлежащим схеме, но хранимым в базе данных,
относятся каталоги, профили, роли, сегменты отката, таблич-
ные области и пользователи.
Таблица (TABLE) является базовой структурой реля-
ционной модели. Как известно, вся информация в реляцион-
ной базе данных хранится в таблицах. Полное имя таблицы в
базе данных состоит из имени схемы и собственно имени
таблицы. Таблицы состоят из множества поименованных
столбцов или атрибутов. Множество допустимых значений
атрибута называют доменом значений или просто доменом.
Множество допустимых значений столбца также может быть
уточнено с помощью статических ограничений целостности.
Таблицы могут быть связаны между собой отношениями
ссылочной целостности. Таблица может быть пустой или со-
стоять из одной или более строк значений атрибутов. Строки
значений атрибутов таблицы называются также кортежами.
Для однозначной идентификации строки в таблице служит
идентификатор (ROWID) — указатель, имеющий специаль-
ный формат. В OracleS появились вложенные таблицы
(NESTED TABLES), которые позволяют объявить таблицу
как тип значения столбца родительской таблицы. Подробно
они рассмотрены в разделе "Объектные расширения в
OracleS". Для повышения скорости доступа к данным таблица
может быть индексно организована (INDEX-ORGANIZED
TABLE). Физическое пространство для хранения данных таб-
лицы выделяется частями, называемыми экстентами. Размеры
начального и дополнительных экстентов определяются при
создании таблицы.

68
SQL — язык обработки данных Oracle

Представление (VIEW) — это поименованная, дина-


мически поддерживаемая сервером выборка из одной или не-
скольких таблиц. По сути, представление — это производное
множество строк, которое является результатом выполнения
некоторого запроса к базовым таблицам. В словаре данных
хранится только определение представления и, когда в опера-
торе SQL встречается название представления, Oracle обра-
щается к словарю за определением и подставляет его в ис-
ходный запрос. Запрос, определяющий выборку, ограничива-
ет видимые пользователем данные. Представления позволяют
упростить сложные запросы и сделать более понятными их
логику. Используя представления, администратор безопасно-
сти ограничивает доступную пользователю часть базы дан-
ных только теми данными, которые реально необходимы для
выполнения его работы. Представления также можно исполь-
зовать для поддержки приложений при изменении структуры
таблицы. Например, при добавлении нового столбца в табли-
цу создать представление, его не включающее.,
Синоним (SYNONYM) — это альтернативное имя иди
псевдоним объекта Oracle, который позволяет пользователям
базы данных иметь доступ к данному объекту. Синоним мо-
жет быть частным и общим. Общий (PUBLIC) синоним по-
зволяет всем пользователям базы данных обращаться к соот-
ветствующему объекту по альтернативному имени. Харак-
терным применением общих синонимов является сокрытие
информации о схеме, в которой расположен объект. Наличие
синонима позволяет обращаться к объекту по имени, которое
является абсолютным в масштабе базы данных. Реальная
привязка объекта к некоторой схеме при этом скрыта от поль-
зователя или приложения.
Для управления эффективностью доступа к данным
Oracle поддерживает следующие объекты: индекс, табличная
область, кластер и хэш-кластер.

69
Раздел 2

Индекс (INDEX) — это объект базы данных, предна-


значенный для повышения производительности выборки дан-
ных. Индекс создается для столбцов таблицы и обеспечивает
более быстрый доступ к данным за счет хранения указателей
(ROWID) на месторасположение строк. При обращении к ин-
дексированному столбцу сервер по предъявляемому значе-
нию находит в индексе указатели на эти строки, а потом не-
посредственно обращается к ним. Если все требуемые значе-
ния столбцов имеются в индексе, обращение к таблице не
происходит вовсе. Имеется несколько типов индексов —
В*Тгее (двоичное дерево, каждый узел которого содержит
указатель на следующий и предыдущий), масочный индекс,
индекс с реверсированным ключом, кластерный индекс. Под-
робнее о них рассказывается в разделе "Методы повышения
производительности".
Кластер (CLUSTER) — объект, задающий способ хра-
нения данных нескольких таблиц, содержащих информацию,
обычно обрабатываемую совместно, например, значения
столбцов таблиц, часто участвующих в эквисоединениях.
Строки таких таблиц, имеющие одинаковое значение в кла-
стеризованных столбцах, хранятся в базе данных специаль-
ным образом: на логическом уровне — в нормализованном
виде, а на физическом — в ненормализованном. Кластериза-
ция столбцов таблиц позволяет уменьшить время выполнения
выборки.
При использовании хэшированных кластеров
(HASH CLUSTER) организация таблиц базируется на резуль-
татах хэширования их первичных ключей. Для получения
данных из такого кластера запрашиваемое значение ключа
обрабатывается хэш-функцией, полученное значение опреде-
ляет, в каком блоке кластера хранятся данные.
Табличная область (TABLESPACE) -— именован-
ная часть базы данных, используемая для распределения па-
мяти для таблиц, индексов и других объектов. В табличную
область входит один или несколько файлов. Это предоставля-
70
SQL — язык обработки данных Oracle

ет возможность гибко настроить хранение данных в зависи-


мости от порядка и интенсивности их использования. Напри-
мер, можно отвести одну табличную область для таблиц, а
другую — для индексов. В каждой базе данных есть таблич-
ная область SYSTEM, с которой связаны все системные объ-
екты, например таблицы словаря данных. Доступность таб-
личных областей может устанавливаться переводом в авто-
номный или оперативный режим.
Для эффективного управления разграничением доступа к
данным Oracle поддерживает объект роль.
Роль (ROLE) — именованная совокупность привилегий,
которые могут быть предоставлены пользователям или дру-
гим ролям. Oracle поддерживает несколько предопределен-
ных ролей. Для систем, в которых количество пользователей
и приложений велико, роли могут заметно облегчить разгра-
ничение доступа, например, возможно динамически назна-
чать роли для изменения набора привилегий пользователя при
работе с различными приложениями. Также роли можно за-
щищать паролем.
Специфичными для распределенных систем являются
объекты Oracle: снимок и связь базы данных.
Снимок (SNAPSHOT) — локальная копия таблицы уда-
ленной базы данных, которая, используется либо для тиражи-
рования (копирования) всей или части таблицы, либо для ти-
ражирования результата запроса данных из нескольких таб-
лиц. Снимки могут быть модифицируемыми или предназна-
ченными только для чтения. Снимки только для чтения воз-
можно периодически обновлять, отражая изменения основной
таблицы. Изменения, сделанные в модифицируемом снимке,
распространяются на основную таблицу и другие копии.
Связь базы данных (DATABASE LINK) — это
объект базы данных, который позволяет обратиться к объек--
там удаленной базы данных. Имя связи базы данных можно
рассматривать как ссылку на параметры механизма доступа к
удаленной базе данных (имя узла, протокол и т. п.).

71
Раздел 2

Сегмент отката (ROLBACK SEGMENT) — объект


базы данных, предназначенный для обеспечения многополь-
зовательской работы. В сегментах отката находятся обнов-
ляемые и удаляемые данные в пределах одной транзакции.
При отмене изменений старая версия данных всегда доступна,
так как находится в сегментах отката. В начале транзакции и
в каждой контрольной точке текущие значения данных копи-
руются в сегмент отката. Кроме того, сегменты отката ис-
пользуются при других операциях сервера. Размер и доступ-
ность сегментов отката в сильной степени влияют на произ-
водительность сервера баз данных и их настройка должна
быть выполнена самым тщательным образом.
Для программирования алгоритмов обработки данных,
реализации механизмов динамической поддержки целостно-
сти базы данных Oracle использует следующие объекты: про-
цедуры, функции, пакеты, тела пакетов и триггеры.
Процедура (PROCEDURE) — это поименованный,
структурированный набор конструкций языка PL/SQL, пред-
назначенный для решения конкретной задачи.
Функция (FUNCTION) — это поименованный, структу-
рированный набор конструкций языка PL/SQL, предназна-
ченный для решения конкретной задачи и возвращающий
значение.
Пакет (PACKAGE) — это поименованный, структури-
рованный набор переменных, процедур и функций и других
объектов, связанных функциональным замыслом. Пакет со-
стоит из двух самостоятельных частей: заголовка и тела. За-
головок содержит описание переменных, констант, типов,
процедур, функций и других конструкций языка PL/SQL. Те-
ло пакета содержит реализацию алгоритмов процедур и
функций и хранится отдельно. Например, Oracle предоставля-
ет стандартный пакет UTL_FILE, который содержит процеду-
ры и функции, предназначенные для организации файлового
ввода-вывода из программ на языке PL/SQL.

72
SQL — язык обработки данных Oracle

Триггер (TRIGGER) — это хранимая процедура, кото-


рая автоматически выполняется тогда, когда происходит свя-
занное с триггером событие. Обычно события связаны с вы-
полнением операторов вставки, модификации и удаления
данных. С помощью триггеров можно реализовать правила
динамической проверки целостности данных и дополнитель-
ного контроля доступа.
Библиотеки (LIBRARY) — объекты базы данных,
предназначенные для взаимодействия программ PL/SQL с
модулями, написанными на других языках программирова-
ния.
Типы (TYPE) и коллекции типов — новые виды объек-
тов базы данных для OracleS, предназначенные для реализа-
ции объектных расширений.
Каталог (DIRECTORY) — объект, предназначенный
для организации файлового ввода-вывода и работы с боль-
шими двоичными объектами.
Профиль (PROFILE) — объект, ограничивающий ис-
пользование пользователем системных ресурсов, например
процессорного времени или числа операций ввода-вывода.

Средства манипулирования
данными языка SQL
В языке SQL предусмотрено четыре ключевых слова для
операций манипулирования данными: SELECT, INSERT,
UPDATE и DELETE. Предложения с оператором SELECT
занимают особое место, поскольку они предназначены для
выборки данных, а основная часть активности пользователей
связана с выполнением запросов на выборку данных. Кроме
того, умение правильно и оптимально написать сложный за-
прос является одной из лучших характеристик квалифициро-
ванного специалиста в области систем управления базами

73
Раздел 2

данных. Часто часть языковых средств, отвечающую за вы-


борку данных, называют языком запросов.
Структура запроса.
Оператор SELECT используется для выборки атрибутов
одной лли нескольких таблиц в соответствии с указанным
критерием отбора. В запросе можно использовать встроенные
функции и, более того, пакетные функции, не изменяющие
состояние базы данных (обладающие необходимым "уровнем
чистоты"). Последовательность операций при прохождении
оператора SELECT через архитектуру сервера Oracle была
приведена в разделе "Архитектура распределенных систем
обработки данных".
Всякий запрос начинается с ключевого слова SELECT.
После ключевого слова SELECT следует список, определяю-
щий перечень выводимых столбцов и, возможно, элементы
форматирования. Ключевое слово FROM определяет табли-
цы, представления или снимки, из которых будут отбираться
данные. Ключевое слово WHERE определяет логическое ус-
ловие отбора данных. Если ключевое слово WHERE опущено,
то осуществляется выбор из декартова произведения таблиц,
представлений и снимков, указанных в перечне значений по-
сле ключевого слова FROM.
Простейшие запросы
Хотя выводить все атрибуты таблицы обычно требуется
редко, стандарт SQL поддерживает простой способ запроса
на вывод всех атрибутов. Для этого используется специаль-
ный символ "*" (звездочка). Проиллюстрируем использова-
ние простейших запросов на таблице, созданной и заполнен-
ной предложениями:

CREATE TABLE Tab! (Atl CHAR(3),At2 NUMBER);


INSERT INTO Tabl VALUES('A', 1);
INSERT INTO Tabl VALUES('B', 2);
INSERT INTO Tabl VALUES('С', 2);

74
SQL — язык обработки данных Oracle

Запрос, выполняющий вывод всех данных таблицы Tabl,


задается оператором SELECT * FROM Tabl:

SQL> SELECT * FROM Tabl;

ATI AT2

A 1
В 2
С 2

Листинг 13. Запрос, выводящий все данные из таб-


лицы Tabl

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


пользователя, то в запросе необходимо указать полное имя
таблицы, то есть как имя схемы, так и имя таблицы. Пусть
пользователь ul выполняет выборку из таблицы Tabl пользо-
вателя и2. Запрос, выполняющий вывод всех данных таблицы
Tabl схемы пользователя и2, задается оператором:

SQL> SELECT * FROM u2.Tabl;

ATI AT2

A 1
В 2
С 2

Листинг 14. Запрос, выводящий все данные из таб-


лицы ТаЫ из схемы пользователя и2

Как перечень, так и порядок вывода столбцов может быть


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

75
Раздел 2

порядке, отличающемся от порядка, заданного при описании


таблицы, задается следующим оператором:

SQL> SELECT At2,Atl FROM ТаЫ;

AT2 ATI

1 A •
2 В
2 С

Листинг 15. Запрос, выводящий данные столбцов At2


и Atl таблицы ТаЫ в указанном порядке

Дополнительно пользователь может указать в списке вы-


вода выражения, зависящие от значений столбца и заголовок,
который будет выведен на соответствующей позиции.
Ниже приведен пример запроса, выполняющего выборку
значений столбца At2/10 с соответствующим заголовком и
значения столбца Atl с присоединенной строкой:

SQL>SELECT At2/10 "At2/lQ",


2 'ATI = Ч |Atl "Header Atl" FROMVTabl;

At2/10 Header Atl

.1 ATI = A
.2 ATI = В
.2 ATI = С

Листинг 16. Запрос, выводящий значения At2/10 и


Atl с присоединенной строкой и с измененны-
ми заголовками

Результатом выполнения операции выборки является


мультимножество, то есть, если это не указано явно, устране-
ние повторяющихся строк не производится. Для устранения
76
SQL — язык обработки данных Oracle

повторяющихся строк используется ключевое слово


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

SQL> SELECT At 2 FROM Tabl;

AT2

1
2
2

SQL> SELECT DISTINCT At 2 FROM Tabl;

AT 2

1
2

Листинг 17. Запросы без устранения повторяющихся


строк и с устранением повторяющихся строк

Формирование критерия отбора


Вычисление раздела WHERE производится по следую-
щим правилам.
Пусть R — результат вычисления раздела FROM. Тогда
условие отбора применяется ко всем стрбкам R, и результа-
том раздела WHERE является множество, состоящее из тех
строк R, для которых истинны значения результатов вычис-
ления условий отбора. Если условие выборки включает под-
запросы, то каждый подзапрос вычисляется для каждой стро-
ки таблицы R. В стандарте используется термин "эффектив-
но вычисляется" в том смысле, что результат вычисления

77
Раздел 2
подзапроса должен быть таким, как если бы каждый под-
запрос действительно вычислялся заново для каждой строки
R, хотя реально это обычно не требуется.
В качестве базовой конструкции для формирования кри-
терия отбора часто используется совокупность двухместных
предикатов, соединенных логическими связками. Язык SQL
поддерживает двухместные предикаты с операциями:

= Равно
> Больше чем
< Меньше чем
>= Больше или равно
<= Меньше или равно
!=, о Не равно

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


значений. Для символьных строк их определение зависит от
конкретной среды выполнения, в том числе операционной
системы и набора конкретных символов используемого на-
ционального языка. Обратите внимание, что в кодировке
ASCII все символы верхнего регистра меньше чем все симво-
лы нижнего регистра, поэтому 'Z' < 'а', а все номера — мень-
ше, чем все символы, поэтому 'Г < 'Z'.
Проиллюстрируем использование простейшего критерия
отбора, задаваемого двухместным предикатом, на примере
следующего запроса:

SQL> SELECT * FROM Tab!


2 WHERE At2 <> 1;

ATI AT2

В 2
С 2

Листинг 18. Запрос с использованием критерия от-


бора, заданного двухместным предикатом
78
SQL — язык обработки данных Oracle

Обратите внимание на то, что в переменных типа CHAR


строка дополняется пробелами до длины переменной. Харак-
тер обработки дополнительных пробелов задается специ-
альным образом в файле параметров базы данных, поэтому
при сравнении с литеральной строкой, содержащей заверша-
ющие пробелы, необходимо проявлять некоторую осторож-
ность. Результат сравнения "одинаковых" строк типа CHAR и
VARCHAR2 также может оказаться неожиданным.

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


критерия отбора

Обратите внимание, что стандарт SQL допускает наличие


в базе данных неопределенных значений, поэтому вычисле-
ние условия отбора должно производиться не в булевой, а в
трехзначной логике со значениями TRUE, FALSE и
UNKNOWN (неизвестно). Для любого предиката известно, в
каких ситуациях он может порождать значение UNKNOWN.
Булевские операции AND, OR и NOT работают в трехзначной
логике следующим образом:

Таблица 1. Таблица истинности для операций с пе-


ременной, принимающей неопределенное значе-
ние

Операция Результат
TRUE AND UNKNOWN UNKNOWN
FALSE AND UNKNOWN FALSE
UNKNOWN AND UNKNOWN UNKNOWN
TRUE OR UNKNOWN TRUE
FALSE OR UNKNOWN UNKNOWN
UNKNOWN OR UNKNOWN UNKNOWN
NOT UNKNOWN UNKNOWN

79
Раздел 2

Среди предикатов условия отбора в соответствии со стан-


дартом SQL используются следующие предикаты: предикат
сравнения, предикат BETWEEN, предикат IN, предикат
LIKE, предикат IS NULL, предикат EXISTS и предикат с
квантором. Заметим, что во всех реализациях SQL на эффек-
тивность выполнения запроса существенно влияет наличие в
условии отбора простых предикатов сравнения (предикатов,
задающих сравнение столбца таблицы с константой).
Язык SQL допускает связывание предикатов логическими
связками AND, OR, и NOT. Применение логического отрица-
ния NOT возможно как к отдельному (в том числе и одноме-
стному) предикату, так и выражению, образованному из пре-
дикатов с помощью логических связок. Для устранения неод-
нозначности и потенциальных ошибок при ^конструировании
сложных критериев рекомендуется использовать круглые
скобки для группирования.
Следует иметь в виду, что последовательность вычисле-
ния истинности предикатов умышленно не определена и ме-
няется в зависимости от выражения. Как только значение вы-
ражения вычислено на основе некоторого набора предикатов,
истинность остальных предикатов не вычисляется. В зависи-
мости от плана выполнения запроса последовательность вы-
числений также изменяется. В результате может быть полу-
чен неожиданный эффект. Рассмотрим следующий пример.

SQL> SELECT * FROM Tab!


2 WHERE 1=1 OR 1/0=1;

ATI AT2

A 1
В 2
С 2

SQL> SELECT * FROM Tabl


2 WHERE 1=1 AND 1/0=1;

80
SQL — язык обработки данных Oracle
1/0=1
*
error at line 2:
ORA-01476: divisor is equal to zero

Листинг 19. Пример, иллюстрирующий различные спо-


собы вычисления логических выражений

Язык описания данных Oracle


К числу основных функций языка описания данных мож-
но отнести:
— идентификацию типов данных;
— присвоение уникальных имен различным типам дан-
ных;
— спецификацию структуры объекта базы данных;
— спецификацию ключей.
В число дополнительных функций языка описания дан-
ных можно включить:
— определение частных характеристик элементов дан-
ных;
— определение ограничений целостности;
— описание элементов физического уровня хранения
данных.
Под частными характеристиками элементов данных
обычно понимается определение длины символьных строк,
масштаба и точности числовых данных и т. п. Обратите вни-
мание, что формат хранения не обязательно совпадает с фор-
матом, в котором пользователь получает данные. Сервер
Oracle поддерживает возможность переформатирования зна-
чений данных.
Указание ограничений целостности используется для по-
вышения достоверности ввода данных. Автоматический кон-
троль хорошо структурированных данных повышает досто-
верность информации в базе данных.

81
Раздел 2,

Средства описания физического уровня хранения данных


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

Типы данных Oracle


Данный раздел представляет типы данных, поддерживае-
мые Oracle. Все типы данных, перечисленных в стандарте
ANSI SQL92, полностью поддерживаются в OracleS. Типы
данных, специфичные для сервера Oracle, отмечены строкой
[Только для Oracle].
Строки символов
Тип CHARACTER используется для хранения строк фик-
сированной длины. Для хранения строк резервируется опре-
деленное в параметре длина пространство. При необходимо-
сти короткая строка дополняется пробелами.
Синтаксис: СНАДАСТЕК[(дл«на)], СНАЩдлина)].
Если длина строки не указана явно, она полагается равной 1.
Максимальное значение параметра длина — 255 символов.
Пример
strl CHAR(IO)
Str2 CHARACTER

Тип VARCHAR используется для хранения строк пере-


менной длины. Для хранения строк резервируется реально
необходимое пространство.
Синтаксис: VARCHAR [(длина)], CHAR VARYING
[(длина)], CHARACTER VARYING [(длина)].' Если длина
строки не указана явно, она полагается равной 1. Максималь-
ное значение параметра длина — 4000 символов.
Пример
varstrl VARCHAR(10)
82
SQL — язык обработки данных Oracle

varstr2 CHARACTER VARYING(5)

Тип VARCHAR2 [Только для Oracle] используется для


хранения строк переменной длины. Для хранения строк ре-
зервируется реально необходимое пространство. Основная
причина введения типа VARCHAR2 состоит в том, что фир-
ма-производитель декларирует неизменность этого типа в бо-
лее поздних реализациях Oracle, в то время как тип
VARCHAR будет соответствовать требованиям стандартов
SQL.
Синтаксис: VARCHAR2 (длина). Длина строки долж-
на быть указана явно. Минимальное значение параметра дли-
на — 1 символ, максимальное значение параметра длина —
4000 символов.
Пример
.. strlora VARCHAR2(10)

Между этими типами есть различие — данные типа


CHAR имеют фиксированную длину и могут содержать до
255 символов, a VARCHAR2 имеет переменную длину и мо-
жет содержать до 4000 символов. По умолчанию в SQL все
строковые литералы имеют тип CHAR. Значение любого
столбца типа CHAR(255) занимает 255 байт дискового про-
странства и также 255 байтов в листьевом наборе индекса.
Эти различия следует учитывать при проектировании струк-
туры таблиц, выделении места для хранения данных и срав-
нениях строк в SQL-выражениях. Если две строки имеют раз-
ную длину, то при сравнении более короткая строка дополня-
ется пробелами до длины второй строки. В том случае, если
ограничение в 4000 символов существенно и есть необходи-
мость хранить более длинные тексты именно в VARCHAR2,
можно создать таблицу, каждая запись которой будет содер-
жать одну строку текста и для ускорения доступа поместить
ее в однотабличный кластер.

83
Раздел 2

Для хранения символьных данных с использованием на-


циональных алфавитов предназначены типы NCHAR и
NVARCHAR2.
Тип LONG [Только для Oracle] используется для хране-
ния больших строк переменной длины. Для хранения строк
резервируется реально необходимое пространство. Использо-
вание переменных типа LONG имеет следующие ограниче-
ния:
— таблица не может содержать более одного столбца с
типом данных LONG;
— для столбцов типа LONG не разрешено построение
индекса;
— столбцы типа LONG не могут включаться в ограниче-
ния целостности (кроме ограничения NULL или NOT NULL);
— их нельзя использовать в выражениях вида INSERT
INTO ... SELECT ... FROM;
— столбцы этого типа нельзя использовать в конструк-
циях GROUP BY, CONNECT BY.
Фирма-производитель считает тип LONG устаревшим и
не рекомендует его использовать. Тип данных LONG может
не поддерживаться в более поздних версиях Oracle.
Синтаксис: LONG [(длина)]. Если длина строки не
указана явно, она полагается равной 2 мегабайтам. Макси-
мальное значение параметра длина — 2 гигабайта символов.
Пример
longstr LONG(10000)
morelongstr LONG
Числовые типы
Тип INTEGER используется для представления целых
чисел в диапазоне от -231 до 231.
Синтаксис: INTEGER, INT.
Пример
varintl INTEGER
varint2 I-NT

84
SQL — язык обработки данных Oracle

Тип NUMBER [Только для Oracle] используется для


представления чисел с заданной точностью.
Синтаксис: NUMBER [(точность [, масштаб])]. Ес-
ли значение параметра точность не указано явно, оно пола-
гается равным 38. Значение параметра масштаб по умолча-
нию предполагается равным 0. Значение параметра точность
может изменяться от 1 до 38, значение параметра масштаб
может изменяться от -84 до 127. Использование отрицатель-
ных значений масштаба означает сдвиг десятичной точки в
сторону старших разрядов. Например, определение NUMBER
(7,-3) означает округление до тысяч.
Пример
varcounter NUMBER

В таблице 2 приведены представления числа 123456.789 с


различной точностью и масштабом.

Таблица 2. Представления числа 123456.789 с раз-


личной точностью и масштабом

Определение Представление
при выполнении действий
NUMBER 123456
NUMBER(7,1) 123456.7
NUMBER(5,2) ошибка в данных
NUMBER(8,3) 123456.789
NUMBER(7,-2) 123500

Для совместимости с другими СУБД Oracle поддержива-


ет типы данных DECIMAL, DOUBLE_PRECISION,
NUMERIC, DEC и REAL. Все типы числовых данных реально
хранятся в одном и том же внутреннем формате Oracle.
Типы DECIMAL И NUMERIC полностью эквивалентны
типу NUMBER.

85

.
Раздел 2

Синтаксис: DECIMAL [(точность [, масштаб])],


DEC [(точность [, масштаб])], NUMERIC [(точность [,
масштаб])].
Пример
vardecl DEC
vardec2 DEC(5)
vardecS D'ECIMAL (8, 3)
varnum NUMERIC
Тип ROWID
ROWID — специальный тип данных, который служит для
представления указателей на запись в таблице. При создании
строки в таблице ей сразу присваивается ROWID, который
остается неизменным до ее удаления или реорганизации дан-
ных. Использование ROWID — самый быстрый способ дос-
тупа к строке в таблице.

SQL > SELECT ROWID FROM Tabl WHERE ROWNUM=1;

ROWID

AAADFlAADAAAGnPABX

Листинг 20. Вычисление ROWID

Так как значение ROWID является уникальным для лю-


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

SQL> CREATE TABLE Tabl (Atl NUMBER, At2 NUMBER);


Table created.

SQL> INSERT INTO Tabl VALUES(1,2);


1 row created.

86.
SQL — язык обработки данных Oracle
SQL> INSERT'INTO таы VALUES(i,2);
1 row created.
SQL> DELETE FROM Tab!
2 WHERE ROWID NOT IN (SELECT MIN(ROWID)
3 FROM Tabl
4 GROUP BY Atl,At2)
5 /
1 row deleted.

Листинг 21. Пример удаления записей-дубликатов

Битовые строки
Тип RAW [Только для Oracle] используется для хранения
двоичных строк переменной длины. Отличие типа RAW от
типов CHAR, VARCHAR2 состоит в том, что для типов сим-
вольных строк Oracle производит автоматическое преобразо-
вание данных при их передаче между клиентом и сервером.
Утилиты Import и Export также производят автоматическое
преобразование символьных строк при логической разгрузке
и загрузке баз данных в соответствии с настройками средств
поддержки национальных языков. Oracle выдает данные типа
RAW в шестнадцатеричном виде.
Синтаксис: RAW [(длина)]. Параметр длина измеряет-
ся в байтах. Максимальное значение параметра длина — 2000
байт.
Пример
bitarrayl R A W ( 1 0 )

Тип LONG RAW [Только для Oracle] используется для


хранения больших битовых строк переменной длины.
Синтаксис: LONG RAW [(длина)]. Параметр длина
измеряется в байтах. Если длина строки не указана явно, она
полагается равной 2 мегабайтам. Максимальное значение па-
раметра длина — 2 гигабайта символов. Для переменных типа
LONG RAW невозможно построение индекса.

87
Раздел 2

Пример
verylongstrl LONG RAW(1000000)
Дата и время
Тип DATE [Только для Oracle] используется для хране-
ния даты и времени. Допускаются даты с 1 января 4712 г. до
н.э. до 31 декабря 4712 г. н.э. Для формирования значения
типа DATE в SQL и PL/SQL обычно используется встроенная
функция ТО_ОАТЕ('сгшвольная_строка_даты', 'фор-
мат_даты *). При определении даты без уточнения времени
по умолчанию принимается время полуночи. Функция
SYSDATE возвращает текущее значение даты и времени.
Значение функции определяется средствами операционной
системы компьютера, на котором работает сервер Oracle.
Синтаксис: DATE.
Пример
birthday DATE

Наличие специального типа для хранения даты и времени


позволяет поддерживать специальную арифметику дат и вре-
мен. Добавление к переменной типа DATE целого числа ин-
терпретируется Oracle как определение более поздней даты, а
вычитание выполняется как определение более ранней. Рас-
смотрим несколько примеров:

SQL > SELECT SYSDATE - FROM dual;

SYSDATE

16-04-2002

SQL> SELECT SYSDATE+10 "sysd+10" FROM dual;

SYSD+10

26-04-2002

88
SQL — язык обработки данных Oracle
SQL> SELECT SYSDATE-10 "sysd-10" FROM dual;

SYSD-10

06-04-2002

Листинг 22. Запросы, иллюстрирующие арифметику


дат Oracle

Также возможно использование юлианской даты. Юли-


анская дата — это число дней, прошедших с 1 января 4712 г.
до нашей эры. Реализация юлианской даты в Oracle не имеет
компоненты времени. Для использования юлианской даты в
функциях TO_CHAR и TO_DATE применяется маска форма-
та "J".

SQL> SELECT TO_CHAR(TOJDATE('01-01-2002',


2 'DD-MM-YYYY1),'J') JDATE FROM dual;

JDATE

2452276

Листинг 23. Использование юлианской даты

Время хранится с точностью до секунды. Когда нужно


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

89
Раздел 2

LOB-объекты
Тип BLOB [Только для Oracle] используется для хране-
ния двоичных данных размером до 4 гигабайт. Для работы с
большими двоичными объектами используется стандартный
пакет DBMS_LOB, о котором рассказывается в разделе
"PL/SQL — процедурное расширение языка SQL".
Синтаксис: BLOB.
Пример
doc BLOB

Тип CLOB [Только для Oracle] используется для хране-


ния символьных данных переменЯой длины размером до 4
гигабайт, использующих однобайтовую кодировку.
Синтаксис: CLOB.
Пример
cdoc CLOB

Тип NCLOB [Только для Oracle] используется для хране-


ния символьных данных размером до 4 гигабайт, использую-
щих одно- или многобайтовую кодировку.
Синтаксис: NCLOB.
Пример
ncdoc NCLOB

Тип BFILE [Только для Oracle] используется для хране-


ния указателей на двоичные данные, находящиеся во внеш-
них по отношению к СУБД файлах. Сами файлы хранятся в
файловой системе.
Синтаксис: BFILE.
Пример
f i l e doc BFILE

90
SQL — язык обработки данных Oracle

Таблицы. Представления.
Пользователи
Создание и удаление таблиц
в Oracle
Таблица является базовой структурой реляционной моде-
ли. Как известно, вся основная информация реляционной ба-
зы данных хранится в таблицах. Таблицы состоят из множе-
ства поименованных столбцов. Множество допустимых зна-
чений столбца может быть уточнено с помощью ограничений
целостности.
Оператор определения таблиц Oracle содержит довольно
большое число ключевых слов и параметров. Рассмотрим со-
кращенное множество конструкций. Полный синтаксис опе-
ратора CREATE TABLE может быть получен из соответст-
вующего раздела документации OracleS SQL Reference.

CREATE TABLE [имя_схемы.]имя_ та блицы


((ограничение_целостности_таблицы \ имя_столбца
тип_данных_столбца [ DEFAULT выражение]
[ограничение_целостности_столбца . . . ] } , ... )
[{ CLUSTER имя_кластера ( имя_столбца , [...]) |
(PCTFREE целое | PCTUSED целое | INITRANS целое |
MAXTRANS целое 1
TABLESPACE имя_табличной_области \
STORAGE размер_памяти \
{RECOVERABLE | UNRECOVERABLE}} . . . ]
[PARALLEL возможность_параллельной_обработки ]
[{ENABLE проверяемые_ограничения_целостности \
DISABLE игнорируемые_ограничения_целостности}...]
[AS запрос]
[CACHE | NOCACHE]

Ключевое слово DEFAULT указывает на то, что при вво-


де данных соответствующему столбцу будет присвоено зна-
чение, определенное переменной выражение, если в операто-
ре INSERT не указано явно другое значение столбца.
91
Раздел 2

Тип. данных выражение должен соответствовать типу


данных столбца и выражение не должно содержать ссылок
на другие выражения.
Ключевые слова PCTFREE, PCTUSED, INITRANS,
MAXTRANS, TABLESPACE, STORAGE, RECOVERABLE,
UNRECOVERABLE характеризуют пространство, распреде-
ляемое при работе с таблицей.
Когда таблица создается, то система автоматически ре-
зервирует место как для данных, так и для индексов. Это ме-
сто делится на две части, называемые сегментами: сегмент
данных и сегмент индексов. Сегменты состоят из блоков. За-
писи заносятся в таблицу в физической последовательности.
Первая запись хранится в первом блоке первого экстента.
Следующие за ней записи заносятся в первый блок до тех
пор, пока он не заполнится. Блок считается заполненным, ко-
гда очередной записи не хватает оставшегося свободного
пространства в блоке. Когда по мере занесения записей за-
полняются все блоки первого экстента, выделенного таблице,
для данных выделяется первый дополнительный экстент. Ко-
гда будет заполнен и этот экстент, сервер выделит следую-
щий.
После выделения таблице экстента данных или индекса
он не освобождается до тех пор, пока таблица не будет унич-
тожена. Однако если все данные удалены из блока данных, то.
этот блок становится доступным для повторного использова-
ния этой же таблицей или кластером.
Ключевое слово PCTFREE определяет процент простран-
ства блока, который резервируется для нужд модификации
данных таблицы. Допустимые значения от 0 до 99. Значение
по умолчанию 10. То есть, если данный параметр не указан,
то при заполнении каждого блока 10% пространства остается
не использованным. Это пространство используется для запи-
си в него данных при выполнении в дальнейшем операций
модификации строк таблицы.
Ключевое слово PCTUSED определяет минимальный
процент использования пространства блока, при котором в
92
SQL — язык обработки данных Oracle

него вводятся данные. Допустимые значения от 1 до 99. Зна-


чение по умолчанию 40. То есть, если в блоке занято менее
40% пространства в него вводятся данные при выполнении
операции вставки. Сумма значений параметров PCTFREE и
PCTUSED не должна превышать 100.
Ключевое слово INITRANS определяет начальное число
параллельных транзакций, которые могут выполняться для
модификации данных блока. Значение по умолчанию 1. Клю-
чевое слово MAXTRANS определяет максимальное число
параллельных транзакций, которые могут выполняться для
модификации данных блока. В большинстве случаев явное
задание этих параметров не требуется.
Ключевое слово TABLESPACE определяет имя таблич-
ной области, в которой будет размещена таблица. Если значе-
ние параметра не определено, то таблица размещается в таб-
личной области, заданной по умолчанию для пользователя,
который является владельцем схемы, содержащей таблицу.
Ключевое слово STORAGE определяет объем внешней
памяти, выделяемый под таблицу. Для больших таблиц целе-
сообразно явно выделять требуемую память для уменьшения
запросов на динамическое выделение пространства для таб-
лицы.
Для управления записью в журнал контрольной инфор-
мации используются ключевые слова RECOVERABLE и
UNRECOVERABLE. Значение UNRECOVERABLE может
быть использовано только с ключевым словом AS подзапрос,
при этом операция создания таблицы выполняется быстрее за
счет исключения записи управляющей информации в журнал.
Но при этом автоматическое восстановление операции созда-
ния таблицы в случае сбоя становится невозможным.
Ключевое слово CLUSTER указывает привязку столбцов
таблицы к кластеру. Обычно столбцы кластера образуют из
элементов первичного ключа.
Ключевое слово ENABLE указывает на включение огра-
ничений целостности для данной таблицы. Соответствующее
ограничение целостности должно быть определено в данном
93
Раздел 2

предложении создания таблицы. По умолчанию все ограни-


чения целостности, определенные в предложении, включают-
ся.
Ключевое слово DISABLE указывает на выключение ог-
раничений целостности для данной таблицы. Соответствую-
щее ограничение целостности должно быть определено в дан-
ном предложении создания таблицы.
Конструкция AS запрос включает в создаваемую таблицу
строки, являющиеся результатом выполнения запроса. Обра-
тите внимание на необходимость определенной осторожности
при использовании вставки строк через подзапрос и опреде-
ление ограничений целостности в том же предложении. (Если
результат запроса не соответствует ограничениям целостно-
сти, то Oracle не создает таблицу и возвращает сообщение об
ошибке.)
Ключевое слово CACHE указывает на то, что блоки, вы-
бираемые из таблицы, помечаются в системном кэше, как
наиболее используемые. Рекомендуется-для маленьких таб-
лиц, используемых, для преобразований кодов в значения. По
умолчанию используется значение NOCACHE, для которого
выбранные блоки помещаются в конец таблицы частот обра-
щений к кэшу.
Таблицы и столбцы можно документировать с помощью
конструкции COMMENT.
Рассмотрим пример создания таблицы Tab! с тремя атри-
бутами Atl, At2, At3 в схеме пользователя ul. Ограничение
pk_Tabl_Atl, указывает, что атрибут Atl является первичным
ключом, ограничение nn_Tabl_At2, указывает, что атрибут
At2 не допускает ввода неопределенных значений, значение
атрибута At3 по умолчанию есть текущая дата.

SQL» CREATE TABLE ul.Tabl


2 (Atl NUMBER CONSTRAINT pk_Tabl_Atl PRIMARY KEY,
3 At2 NUMBER CONSTRAINT nn Tabl At2 NOT NULL,

94
SQL — язык обработки данных Oracle

4 At3 DATE DEFAULT SYSDATE);


Table created.

Листинг 24. Протокол создания таблицы с размеще-


нием в определенной табличной области и оп-
ределенными параметрами хранения

Следующий пример демонстрирует создание таблицы


ТаЬ2 с двумя атрибутами Atl и At2, размещенной в таблич-
ной области app_data (которая должна быть создана заранее)
с ассоциированным с первичным ключом индексом, разме-
щенным в табличной области index_data. Под таблицу резер-
вируется начальный экстент в 100 килобайт и определяется
экстент приращения в 50 килобайт.

SQL> CREATE TABLE Tab2


2 (Atl NUMBER CONSTRAINT pk_Tabl_Atl PRIMARY KEY
' 3 USING INDEX TABLESPACE index_data,
4 At2 NUMBER)
5 TABLESPACE app_data
6 STORAGE (INITIAL 100K NEXT 5 0 K ) ;
Table created.

Листинг 25. Протокол создания таблицы с размеще-


нием в определенной табличной области и оп-
ределенными параметрами хранения

Существующие таблицы могут быть модифицированы с


помощью команды ALTER TABLE. С ее помощью можно
добавить один или несколько новых столбцов, ограничения
целостности, модифицировать определение существующего
столбца (тип данных, длину, умалчиваемое значение или ог-
раничение целостности NOT NULL), модифицировать пара-
метры хранения и транзакций (PCTFREE, PCTUSEDj
INITRANS, MAXTRANS, NEXT, PCTINCREASE). Изменение
таблицы, особенно включение/отключение ограничений це-
95
Раздел 2

лостности, имеет свои особенности, рассмотренные в разделе


"Средства обеспечения целостности данных в Oracle".
Для удаления из базы данных таблицы (вместе с ее со-
держимым) используется оператор DROP TABLE. Для вы-
полнения операции уничтожения таблицы необходимо быть
либо владельцем таблицы, либо иметь привилегию DROP
ANY TABLE. Когда таблица уничтожается, все блоки стано-
вятся свободными для использования под данные или индек-
сы других таблиц. Оператор удаления таблицы Oracle исполь-
зует следующий синтаксис: DROP TABLE [имя_схемы.]
имя_таблщы [ CASCADE CONSTRAINTS ].
Все индексы и триггеры, ассоциированные с таблицей,
даже если они были созданы другим пользователем, удаляют-
ся. Все хранимые программы, зависящие от таблицы, остают-
ся, но становятся недействительными (непригодными для ис-
пользования). Все синонимы удаленной таблицы остаются, но
возвращают ошибку при обращении к ним. Представления,
синонимы и программы вновь становятся актуальными, если
таблица создается заново (после их перекомпиляции).
Если указано ключевое слово CASCADE CONSTRAINTS,
то удаляются все ограничения целостности, ссылающиеся на
первичные и уникальные ключи данной таблицы. Если такие
ссылки существуют, CASCADE CONSTRAINTS отсутствует,
то удаление таблицы не выполняется и сервер возвращает
сообщение об ошибке. Перед удалением таблицы рекоменду-
ется определить через представление словаря данных
USER_CROSS_REFS зависимости других таблиц от данной
таблицы.Рассмотрим пример предложения для уничтожения
таблицы ТаЫ.

SQL> DROP TABLE ТаЫ;


Table dropped;

Листинг* 26. Пример предложения для уничтоже-


ния таблицы ТаЫ
96
SQL — язык обработки данных Oracle

Средства определения
и уничтожения представлений
Представление — это поименованная, динамически под-
держиваемая сервером выборка из одной или нескольких таб-
лиц или других представлений. Оператор SELECT, опреде-
ляющий выборку, ограничивает видимые пользователем дан-
ные. Кроме того, представление позволяет эффективно огра-
ничить данные, которые пользователь может модифициро-
вать. Используя представления, администратор базы данных
ограничивает доступную пользователям часть логического
пространства базы данных только теми данными, которые
реально им необходимы. Оператор определения представле-
ний Oracle использует следующий синтаксис:

CREATE [OR REPLACE] [{FORCE | NO FORCE}] VIEW


[имя_схемы. ] имя__представления
[ (алътернативное_имя [альтернативное_имя...] ) ]
AS запрос WITH { READ ONLY | CHECK OPTION
[CONSTRAINT ограничение_целостности]}

Ключевые слова OR REPLACE указывают на принуди-


тельное замещение старого представления новым. Использо-
вание этого параметра позволяет не выполнять повторного
предоставления привилегий, которое было бы необходимо,
если использовать команды DROP VIEW и CREATE VIEW
для уничтожения и создания представления заново. .
Ключевое слово FORCE указывает на принудительное
создание представления вне зависимости от того, существуют
ли базовые таблицы представления, и есть ли у пользователя,
создающего представление, привилегии на выборку из базо-
вых таблиц. Если предложение CREATE VIEW не имеет син-
таксических ошибок, то Oracle может создать представление
даже в том случае, когда определяющий представление за-
прос не может быть выполнен. Такое представление считает-
ся "созданным с ошибками".

97
4. Заказ М» 1628.
Раздел 2

Конструкция NO FORCE (используемая по умолчанию)


указывает на обязательность существования базовых таблиц и
представлений и наличия у пользователя, создающего пред-
ставление, привилегий на доступ к базовым таблицам. При
нарушении какого-либо из этих условий представление не
создается.
Параметр запрос используется для обозначения любого
синтаксически правильного запроса, не содержащего ключе-
вого слова ORDER BY или конструкции FOR UPDATE.
Ключевое слово WITH READ ONLY указывает на запре-
щение для базовых таблиц операций модификации данных с
указанием представления.
Ключевое слово WITH CHECK OPTION указывает на то,
что строки в базовых таблицах, изменяемые и вставляемые
через представление, должны соответствовать критерию от-
бора в запросе, определяющем представление.
Ключевое слово CONSTRAINT определяет имя ограни-
чения, используемое для проверки.
Представление является изменяемым, то есть по отноше-
нию к нему можно использовать оператор DELETE, INSERT
и UPDATE, в том случае, если выполняются следующие ус-
ловия для образующего представление запроса:
— в списке выборки не указано ключевое слово
DISTINCT;
— каждое арифметическое выражение в списке выборки
представляет собой одну спецификацию столбца, и специфи-
кация одного столбца не появляется более одного раза;
— в условии выборки раздела WHERE не используются
подзапросы;
— в запросе отсутствуют конструкции GROUP BY и
HAVING.
Если в списке выборки спецификации запроса имеется
хотя бы одно арифметическое выражение, состоящее не из
одной спецификации столбца, или если имя хотя бы одного
столбца участвует в списке выборки более одного раза, опре-
деление должно содержать список имен столбцов таблицы.
98
SQL — язык обработки данных Oracle

Более просто, нужно явно именовать столбцы представляе-


мой таблицы, если эти имена не наследуются от столбцов
таблиц раздела FROM спецификации запроса.
Требование WITH CHECK OPTION в определении пред-
ставления имеет смысл только в случае определения изме-
няемой представляемой таблицы, которая определяется спе-
цификацией запроса, содержащей раздел WHERE. При нали-
чии этого требования не допускаются изменения представ-
ляемой таблицы, приводящие к появлению в базовых таб-
лицах строк, не видимых в представляемой таблице (то есть
таких строк, которые не удовлетворяют условию поиска раз-
дела WHERE спецификации запроса). Если WITH CHECK
OPTION в определении представления отсутствует, такой
контроль не производится.
С помощью специального представления словаря данных
USERJJPDATABLE_COLUMNS можно узнать, какие из
столбцов, включенных в представление, доступны для изме-
нения. Обсуждение вопросов, связанных с обновляемыми
представлениями, построенными над несколькими базовыми
таблицами, выходят за рамки этой книги.
Рассмотрим пример создания представления Vul с огра-
ничением только для чтения. Попытка вставки данных через
представление Vul отвергается системой, несмотря на явное
предоставление привилегии пользователю и2. Вставка дан-
ных в базовую таблицу ТаЬ2 выполняется успешно. Ниже
приведен протокол создания,и использования представления
Vul.

SQL> CONNECT ul/ulpsvf@educ;


Connected.-

SQL> CREATE TABLE Tab2(At1 NUMBER, At2 NUMBER);


Table created.

SQL> CREATE VIEW Vul AS


2 SELECT * FROM Tab2 W I T H READ ONLY;

99
Раздел 2
View created.

SQL> GRANT INSERT ON Tab2 TO u2;


Grant succeeded.

SQL> GRANT INSERT ON Vul TO u2;


Grant succeeded.

SQL> CONNECT u2/u2psw@educ;


Connected.

SQL> INSERT INTO ul.Vul VALUES (1,2);


INSERT INTO ul.VUl VALUES (1,2)
*'
ERROR at line 1:
ORA-01732: data manipulation operation not legal
on this view

SQL> INSERT INTO u l . T a b 2 VALUES ( 1 , 2 ) ;


1 row created.

Листинг 27. Протокол создания представления с ог-


раничением только для чтения

Рассмотрим пример создания представления Vu2 с про-


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

SQL> CONNECT ul/ulpsw@educ;


Connected.

SQL> CREATE VIEW Vu2 AS SELECT * FROM Tab2


2 WHERE Atl > 1 WITH CHECK OPTION;
View created^.

SQL> GRANT INSERT, SELECT ON Vu2 TO u2;


Grant succeeded.

100
— язык обработки данных Oracle
SQL> CONNECT u2/u2psw@educ;
Connected.

SQL> INSERT INTO u l . V u 2 VALUES (1,2);


INSERT INTO U1.VU2 VALUES (1,2)
*
ERROR at line 1:
ORA-01402: view WITH CHECK OPTION where-clause
violation

SQL> INSERT INTO u l . V u 2 VALUES ( 2 , 3 ) ;


'1 row created.

SQL> SELECT * FROM u l . V u 2 ;

ATI AT2

2 3

Листинг 28. Протокол создания представления с


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

Как отмечено выше, для того, чтобы конструктивно рабо-


тать с представлением, пользователь должен, как минимум,
иметь привилегию SELECT для всех таблиц, которые учас-
твуют в запросе, формирующем представление. Поэтому при-
вилегии, которыми обладает пользователь на базовые табли-
цы, наследуются представлением для пользователя, который
его создает. Если пользователь обладает любой комбинацией
привилегий INSERT, UPDATE, DELETE для базовых таблиц,
то эти привилегии будут автоматически наследоваться пред-
ставлением. В то же время пользователь, не имеющий приви-
легий на модификацию строк базовых таблиц, не может по-
лучить соответствующие привилегии в представлении.
Еще одно полезное свойство представлений состоит в
том, что они позволяют реализовать доступ пользователей к
данным, которые являются производными отданных базовых
таблиц. Например, пусть пользователь ul создает представле-
ние, в котором для таблицы ТаЬ2 вычисляется поэлементная
101
Раздел 2

сумма и среднее значение значений в столбцах Atl и At2 со-


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

SQL> CONNECT ul/ulpsw@educ;


Connected.
SQL> CREATE VIEW Vu3 (Satl, AVGAt2)
2 AS SELECT SUM (Atl),AVG .(At2) FROM Tab2;
View created.

SQL> GRANT SELECT ON Vu3 TO u2;


Grant succeeded.

SQL> CONNECT u2/u2psw@educ;


Connected.

SQL> SELECT * FROM ul.Vu3;

SAT1 AVGAT2

5 2.67

SQL> SELECT * FROM ul.Tab2;


SELECT * FROM U1.TAB2
* ~\
ERROR at line 1:
ORA-01031: insufficient privileges

Листинг1 29. Протокол создания представления и вы-


полнения операций выборки данных из пред-
ставления и базовой таблицы

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


VIEW. Для удаления представления необходимо быть его
владельцем или иметь привилегию DROP ANY VIEW. Ис-
пользуется следующий синтаксис:

DROP VIEW [имя_схемы.]имя_представления


102
SQL — язык обработки данных Oracle

При удалении представления объекты, ссылающиеся на


удаляемое представление, не уничтожаются, а становятся не-
действительными. Привилегии на удаляемое представление
также отменяются. Рассмотрим пример удаления представле-
ния Vu3:

SQL> DROP VIEW Vu3;


View droped.

Листинг 30. Пример удаления представления

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

CREATE USER имя_пользователя IDENTIFIED


{ BY пароль \ EXTERNALLY }
[DEFAULT TABLESPACE имя_табличной_области!]
[TEMPORARY TABLESPACE имя_табличной_области2]
[QUOTA {число_единиц [{ К | М }] | UNLIMITED }
ON имя_табличной_области]
[PROFILE имя_профиля]

Параметр имя пользователя задает имя, под которым


пользователь регистрируется в системе. Имя пользователя
должно быть указано в кодировке, поддерживаемой сервером.
Ключевое слово BY указывает, что подтверждающий
подлинность пользователя пароль будет указан явно в пара-
метре пароль. Обратите внимание, что существуют некоторые
ограничения на использование двухбайтовых кодировок. В
103
Раздел 2

частности, Oracle рекомендует использовать по крайней мере


один символ из однобайтового набора ASCII и по сути за-
прещает использование в паролях символов "$" и "#". Если
указан параметр EXTERNALLY, то сервер проверяет соот-
ветствие зарегистрированного операционной системой поль-
зователя и пользователя Oracle.
Конструкция DEFAULT TABLESPACE указывает имя
табличной области, задаваемое параметром имя_таблич-
ной_обдасти1, которая используется для объектов создавае-
мого пользователя по умолчанию. Если она не указана, то для
объектов создаваемого пользователя будет использоваться
табличная область SYSTEM. Учитывая то, что в табличной
области SYSTEM размещен словарь данных, использовать ее
для пользовательских объектов нецелесообразно.
Конструкция TEMPORARY TABLESPACE указывает
системе имя табличной области, задаваемое параметром
имя_табличной_обласпш2, которая используется по умолча-
нию для временных сегментов создаваемого пользователя.
Временные сегменты используются для хранения промежу-
точных данных. Если ключевое слово TEMPORARY
TABLESPACE не указано, то для временных сегментов соз-
даваемого пользователя будет использоваться табличная об-
ласть SYSTEM. Для многопользовательской системы, к кото-
рой предъявляются повышенные требования по производи-
тельности, табличные области для временных сегментов и
для объектов пользователя желательно разнести по различ-
ным физическим носителям.
Ключевое слово QUOTA задает ограничения на исполь-
зуемое пользователем пространство в конкретной табличной
области. Максимально допустимое пространство задается па-
раметром число_единиц в мегабайтах, если указано ключевое
слово М, килобайтах, если указано ключевое слово К, или в
байтах, если не указано ни М, ни К. Указание ключевого сло-
ва UNLIMITED разрешает пользователю использовать про-
странство без ограничений. Обратите внимание, что при реги-
страции пользователя можно использовать ключевое слово
104
SQL — язык обработки данных Oracle

QUOTA несколько раз и определить для пользователя допус-


тимое пространство в нескольких табличных областях.
Ключевое слово PROFILE назначает пользователю про-
филь,-задаваемый параметром имя_профиля. Если ключевое
слово PROFILE не указано, пользователю приписывается про-
филь DEFAULT.
Для регистрации пользователей необходимо иметь при-
вилегию CREATE USER.
Рассмотрим пример создания пользователя ul, который
использует пароль U1PSW и которому назначена табличная
область по умолчанию app_data с ограничением на исполь-
зуемое пространство в 1 мегабайт, и разрешением использо-
вать табличную область tools с ограничением на исполь-
зуемое пространство 500 килобайт.

SQL> CREATE USER ul IDENTIFIED BY U1PSW


2 DEFAULT TABLESPACE app_data
3 QUOTA 1M ON app_data
4 QUOTA 500K ON tools;
User created.

Листинг 31. Протокол операции регистрации пользо-


вателя

Для изменения пользователей используется оператор


ALTER USER. Оператор изменения пользователей Oracle ис-
пользует следующий синтаксис:

ALTER USER имя_пользователя


IDENTIFIED { BY пароль \ EXTERNALLY }
[DEFAULT TABLESPACE имя_табличной_области!]
[TEMPORARY' TABLESPACE имя_табличной_области2]
[QUOTA {число_единиц [{ К | М }] | UNLIMITED }
ON имя_табличной_области]
[PROFILE имя_профиля]

105
Раздел 2

Рассмотрим пример, иллюстрирующий изменение пароля


пользователя:

SQL> ALTER USER ul IDENTFIED BY newulpsw;


User altered.

Листинг 32. Пример выполнения операции изменения


пароля пользователя

Для исключения из базы данных пользователя использу-


ется оператор DROP USER. При исключении пользователя
должны быть удалены все объекты, принадлежащие этому
пользователю. Для выполнения операции исключения пользо-
вателя необходимо иметь привилегию DROP USER.
Оператор исключения пользователя Oracle использует
следующий синтаксис: DROP USER имя пользователя [
CASCADE]
Параметр имя пользователя задает имя пользователя в
системе. Если указано ключевое слово CASCADE, то автома-
тически удаляются все объекты исключаемого пользователя.
Если ключевое слово CASCADE не указано, а в схеме пользо-
вателя содержатся объекты, возвращается сообщение об
ошибке. Также будет возвращено сообщение об ошибке, если
пользователь подключен в момент лопытки его исключения.
Обратите внимание на то, что если указано ключевое сло-
во CASCADE, то автоматически удаляются все ограничения
целостности, которые имеют ссылки на первичные и уни-
кальные ключи удаляемых таблиц исключаемого пользова-
теля. Представления, синонимы, функции и процедуры, ссы-
лающиеся на объекты исключаемого пользователя, помеча-
ются как недействительные.
Рассмотрим пример, иллюстрирующий выполнение опе-
рации исключения пользователя:

106
SQL — язык обработки данных Oracle

SQL> DROP USER ul;


DROP USER Ul
*
ERROR at line 1:
ORA-01922: CASCADE must be specified to drop 'ul'
SQL> DROP USER ul CASCADE;
User dropped.
Листинг 33. Пример выполнения операции исключения
пользователя

Операция вставки строк


Операция INSERT используется для вставки строк в таб-
лицу или базовые таблицы представления. Предложение
INSERT имеет следующий синтаксис:

INSERT INTO { [ и м я _ с х е м ы , ] { имя_таблицы \


имя_представления } [@имя_связиБД] \
( подзапрос_1 ) }
[ ( имя_столбца [/ имя_столбца . . . ] ) ]
{VALUES (выражение [ , выражение ] . . . ) |
подзапрос_2]

Фразы предложения INSERT должны быть записаны в


указанном порядке. При вставке строк с использованием
представления строки добавляются в базовые таблицы пред-
ставления. Необязательный параметр гшя_схемы использует-
ся для уточнения имени схемы, в которой находится соответ-
ствующий объект Oracle. По умолчанию используется схема
пользователя, выполняющего операцию.
Параметр имя_связиБД устанавливает имя связи с уда-
ленной базой данных. Если имя связи с удаленной базой дан-
ных не указано, предполагается, что соответствующий объект
Oracle расположен в основной базе данных.
Параметр подзопрос_1 задает подзапрос, который в дан-
ном контексте рассматривается как представление.
107
Раздел 2

Параметр выражение заменяется на вычисляемое выра-


жение, обычно базирующееся на данных столбцов из таблиц,
представлений и снимков, указанных в перечне значений
ключевого слова INTO.
Параметр подзапрос_2 задает подзапрос, который фор-
мирует множество вводимых строк.
Рассмотрим примеры применения оператора INSERT.
Проиллюстрируем использование оператора вставки строк на
таблицах Tab! и ТаЬ2, созданных и заполненных предложе-
ниями:

CREATE TABLE Tab! (Atl .CHAR(3), At2 NUMBER);


CREATE TABLE Tab2 (Atl NUMBER);

Простейшим вариантом ввода данных является вставка


строки явным указанием списка значений.

SQL> INSERT INTO Tab! V A L U E S ( ' A ' , 1 ) ;


1 row created.
Листинг 34. Вставка строки явным указанием списка
значений

Если значение какого-либо атрибута не определено и


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

SQL> INSERT INTO Tabl V A L U E S ( ' В 1 , NULL);


1 row created.
Листинг 35. Вставка строки с неопределенным зна-
чением одного из атрибутов

Данные, вводимые в таблицу, могут быть результатом за-


проса к другой таблице, снимку или представлению.

108
SQL — язык обработки данных Oracle

SQL> INSERT INTO Tab2 SELECT At2 FROM Tabl WHERE


Atl = ' A ' ;
1 row created. ,

Листинг 36. Вставка данных, являющихся результа-


том запроса к некоторой таблице или пред-
ставлению

Данные, вводимые в таблицу, могут быть элементом по-


следовательности или результатом функции. Обычно таким
образом формируются уникальные (за счет свойств последо-
вательности) идентификаторы и временные метки. Проиллю-
стрируем использование оператора вставки строк на таблице
ТаЬЗ и последовательности IdSeq, созданных предложениями:

SQL> CREATE TABLE ТаЬЗ (Atl DATE, At2 NUMBER);


Table created.

SQL> CREATE SEQUENCE IdSeq;


Sequence created."

SQL> INSERT INTO ТаЬЗ VALUES (SYSDATE,


2 IdSeq.NEXTVAL);
1 row created.

Листинг 37. Вставка данных, являющихся элементом


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

Операция удаления строк


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

109
Раздел 2
DELETE [FROM]
{ [имя_схемы. ] { имя_,таблицы | имя_представления }
[@имя_связиБД ] | подзапрос }
[ альтернативное_имя] [WHERE условие ]

Фразы предложения DELETE должны быть записаны в


указанном порядке. При удалении строк с указанием пред-
ставления удаляются строки из базовых таблиц представле-
ния. Необязательный параметр имя_схемы используется для
уточнения имени схемы, в которой находится соответствую-
щий объект Oracle. По умолчанию используется схема поль-
зователя, выполняющего операцию.
Параметр имя_связиБДустанавливает имя связи с удален-
ной базой данных. Если имя связи с удаленной базой данных
не указано, предполагается, что соответствующий объект
. Oracle расположен в основной базе данных.
Параметр подзапрос задает подзапрос, который в данном
контексте рассматривается как представление.
Если ключевое слово WHERE отсутствует, то из таблицы
удаляются все строки. Если же ключевое сл.ово WHERE ис-
пользуется, удаляются строки, для которых условие выполня-
ется. Все удаляемые строки и соответствующие индексы ос-
вобождают занимаемую ими память.
Рассмотрим пример, иллюстрирующий применение опе-
ратора DELETE. Выполнение первого предложения приводит
к удалению из таблицы.Tab! всех строк, для которых значе-
ние атрибута Atl не превышает 100. Второе предложение уда-
ляет все строки из таблицы Tab!.

SQL> DELETE FROM Tabl WHERE Atl < = 100


1 row deleted.

SQL> DELETE FROM Tabl;


1 row deleted.
Листинг 38. Удаление строк с использованием кри-
терия отбора и безусловное удаление строк

110
— язык обработки данных Oracle

Операция модификации строк


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

UPDATE {[имя_схемы.]{ имя_таблицы |


имя_представления \ имя_снимка }
[@имя_связиБД] | подзапрос_1 }
[ альтернативяое_имя]
SET { [ ( имя^столбца [, имя_столбца ...] ) =
( подзалрос_2 ) ] \
имя_столбца = { выражение \ подзапрос_3 } } ...
[WHERE условие ]

Фразы предложения UPDATE должны быть записаны в


указанном порядке. При модификации строк с параметром
имя_представленш изменяются строки из базовых таблиц
представления. Необязательный параметр шля_схемы исполь-
зуется для уточнения имени схемы, в которой находится соот-
ветствующий объект Oracle. По умолчанию используется схе-
ма пользователя, выполняющего операцию.
Параметр гшя_связиБД устанавливает имя связи с удален-
ной базой данных. Если имя связи с удаленной базой данных
не указано, предполагается, что соответствующий объект
Oracle расположен в локальной базе данных.
Параметры подзапрос_1, подзапрос_2, подзапрос^ за-
дают подзапросы, которые в данном контексте рассматрива-
ется также представление.
Параметр выражение представляет собой вычисляемое
выражение, обычно базирующееся на данных столбцов из
таблиц.
Рассмотрим несколько примеров, иллюстрирующих при-
менение оператора UPDATE. В таблице Tab! выполняется
модификация строк с использование критерия отбора моди-
фицируемых строк.

ill
Раздел 2

SQL> SELECT * FROM Tabl;

ATI AT2

1 AAA
2 BBB

SQL> UPDATE Tabl SET At2 = 'CCC' WHERE Atl = 1;


1 row updated.

SQL> SELECT * FROM Tabl;

ATI AT2

1 CCC
2 BBB

SQL> UPDATE Tabl SET Atl = Atl*1.5


2 WHERE At2 LIKE 'B%';
1 row updated.

SQL> SELECT * FROM Tabl;


ATI AT2

1 . CCC
3 BBB

Листинг 39, Примеры модификации строк таблицы

Специальные предикаты SQL


При выполнении выборки данных в критерии отбора, за-
даваемом ключевым словом WHERE, используются специ-
альные предикаты IN, BETWEEN, LIKE, EXIST, IS NULL и
предикаты с квантором. Ниже приводятся синтаксические
конструкции и примеры использования этих предикатов.

112
SQL — язык обработки данных Oracle

Предикат IN

Предикат IN определяет множество, вхождение в которое


определяет истинность предиката.
Предикат IN определяется следующими синтаксическими
правилами:

Предикат IN : : = выражение [NOT] IN [подзапрос \


[список_значений]}

Типы левого операнда выражение и значений из списка


правого операнда должны быть сравнимыми. Напомним, что
результирующий набор записей подзапроса должен содер-
жать ровно один столбец.
Значение предиката равно TRUE в том и только в том
случае, когда значение левого операнда совпадает хотя бы с
одним значением из списка правого операнда. Если список
правого операнда пуст (так может быть, если правый операнд
задается подзапросом) или значение подразумеваемого пре-
диката сравнения х = у (где х — значение арифметического
выражения левого операнда) равно FALSE для каждого эле-
мента у списка правого операнда, то значение предиката IN
равно FALSE.
По определению значение предиката х NOT IN S равно
значению предиката NOT (x IN S).
Обычно запрос с предикатом IN используется для про-
верки вхождения в явно определенное множество небольшой
размерности или во множество, формируемое подзапросом.
Проиллюстрируем использование предиката IN на таблице,
созданной и заполненной предложениями:

CREATE TABLE Tab! (Atl C H A R ( 3 ) , At2 NUMBER);


INSERT INTO Tabl V A L U E S ( ' A 1 , 1);
INSERT INTO Tabl V A L U E S ( ' B ' , 2 ) ;
INSERT INTO Tabl V A L U E S ( ' C ' , 3);

113
Раздел 2

Следующие запросы демонстрируют варианты использо-


вания предиката IN:

SQL> SELECT. * FROM Tab!


2 WHERE At1 IN ('A','С','E')
3 AND At2 NOT IN- (2,4,8);

ATI AT2

A 1
С 3

SQL> SELECT * FROM Tabl WHERE Atl IN


2 (SELECT Atl FROM Tabl WHERE Atl > 'A');

ATI AT2

В 2
С 3

Листинг 40. Запросы, характеризующие использова-


ние предиката IN. с множеством, задаваемым
явным перечислением, и множеством, задавае-
мым подзапросом
ч —————— . • ——————-
Предикат BETWEEN
Оператор BETWEEN похож на оператор IN. В отличие от
определения элементов множества перечислением или с по-
мощью подзапроса, как это делается для предиката IN, пре-
дикат BETWEEN определяет диапазон, принадлежность зна-
чения к которому определяет истинность предиката. Ключе-
вое слово BETWEEN указывается перед начальным значени-
ем, затем идет ключевое слово AND и завершает конс-
трукцию конечное значение. Для предиката BETWEEN по-
рядок следования начального и конечного значений важен.
Предикат BETWEEN имеет следующий синтаксис:

114
SQL — язык обработки данных Oracle
Предикат BETWEEN ::= выражение [NOT]
BETWEEN начальное_значение AND конечное_значение

По определению результат х BETWEEN у AND z тот же


самый, что результат логического выражения х > = у AND х <
= z. Результат х NOT BETWEEN у AND z тот же самый, что
результат NOT (x BETWEEN у AND z).
Обычно запрос с предикатом BETWEEN используется
для проверки вхождения значения в диапазон дат или число-
вой диапазон.
Проиллюстрируем использование предиката BETWEEN
на таблице, созданной и заполненной предложениями:

CREATE TABLE Tab! (Atl DATE, At2 NUMBER);


INSERT INTO Tabl VALUES(TOJ3ATE('01-01-2002'),1);
INSERT INTO Tabl V A L U E S ( T O _ D A T E ( ' 0 1 - 0 7 - 2 0 0 2 ' ) , 3 ) ;
INSERT INTO Tabl V A L U E S ( T O _ D A T E ( ' 0 1 - 0 8 - 2 0 0 2 ' ) / 5 ) ;

Следующие запросы демонстрируют два варианта ис-


пользования предиката BETWEEN (напомним, что функция
SYSDATE возвращает текущую дату и Oracle поддерживает
естественную арифметику дат):

SQL> SELECT Atl,At2, SYSDATE FROM Tabl


2 WHERE Atl BETWEEN SYSDATE-150 AND SYSDATE;

ATI AT2 SYSDATE

01-01-2002 1 11-04-2002-

SQL> SELECT * FROM Tabl


2 WHERE SIN(At2) BETWEEN 0 AND 1;

ATI AT2

01-01-2002 1

115
Раздел 2
01-07-2002 3

Листинг 41. Запросы, характеризующие использова-


ние предиката BETWEEN с диапазоном дат и
чисел

Сравните результат предыдущего запроса с результатом


следующего запроса:

SQL> SELECT * FROM Tab!


2 WHERE SIN(At2) BETWEEN 1 AND 0;
no rows selected

Листинг1 42. Запрос, характеризующий использование


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

Предикат LIKE
Предикат LIKE применим только к полям типа CHAR,
VARCHAR и VARCHAR2. Предикат принимает истинное
значение при вхождении определенной подстроки в строку. В
качестве механизма формирования условия используется
шаблон, состоящий из специальных символов и обычных
символов используемой кодировки. В роли специальных сим-
волов выступают:
символ подчеркивания (_), замещающий любой одиноч-
ный символ;
символ процента (%), замещающий последовательность
любого числа символов (включая пустой символ).
Например, на шаблоне 'А_' предикат LIKE принимает
истинное значение для всех двухсимвольных значения атри-
бутов, первый из которых символ 'А', а на шаблоне 'А%'
предикат LIKE принимает истинное значение для всех значе-
ния атрибутов, первый из которых символ 'А', а длина произ-
вольна. Если ограничение накладывается на значения индек-
сированного столбца, а шаблон начинается со специального
116
SQL — язык обработки данных Oracle

символа'%', то использование индекса в этом случае, как пра-


вило, невозможно.
Предикат LIKE имеет следующий синтаксис:

Предикат'LIKE ::= имя_атрибута [NOT] LIKE шаблон

Типы данных столбца левого операнда и образца должны


быть типами символьных строк. Значение предиката истинно,
если шаблон определяет подстроку заданного значения атри-
бута. Обратите внимание, что значение предиката LIKE не
определено (UNKNOWN), если значение атрибута не опреде-
лено.
Проиллюстрируем использование предиката LIKE на таб-
лице, созданной и заполненной предложениями:

CREATE TABLE Tabl (Atl VARCHAR2(3));


INSERT INTO Tabl VALUES('AB');
INSERT INTO Tabl VALUES('ABC');
INSERT INTO Tabl VALUES('ACB1);
INSERT INTO Tabl VALUES('ADC');
INSERT INTO Tabl VALUES('CAB');

Следующие запросы демонстрируют варианты поиска


значений атрибутов, задаваемых различными шаблонами:

SQL> SELECT * FROM Tabl WHERE Atl LIKE 'A%';

ATI

AB
ABC
ACB
ADC

SQL> SELECT * FROM Tabl WHERE Atl LIKE '%B';

ATI

AB
117
Раздел 2
АСВ
CAB

SQL> SELECT * FROM Tabl WHERE Atl LIKE 'A%B';

ATI

ACB

SQL> SELECT * FROM Tabl WHERE Atl LIKE 'A_C';

ATI

ABC
ADC

Листинг 43. Запросы, характеризующие использова-


ние предикатг1 LIKE с различными шаблонами

Предикат IS NULL
Распространенной является ситуация, когда в некоторых
записях таблицы присутствуют атрибуты с неопределенными
значениями, например, потому что значение атрибута не было
введено. В языке SQL для указания неопределенного значе-
ния атрибута используется значение NULL. Когда значение
атрибута есть NULL, подразумевается, что атрибут не принял
никакого конкретного значения. Значение NULL поддержи-
вается специальным образом и не имеет какого-либо типа
данных. Атрибут с любым типом данных может иметь значе-
ние NULL.
Для OracleS (а также младших версий) для символьных
значений переменной длины значения " и NULL эквивалент-
ны. Это же верно для типов CHAR, VARCHAR, VARCHAR2,
RAW, LONG RAW, LONG, DATE, ROWID, BLOB, CLOB,
MLSLABEL.
Выражение типа Atl = NULL или Atl IN (NULL) будет
иметь неопределенное значение, независимо от значения Atl.

118
SQL — язык обработки данных Oracle

Для операций со значением NULL применяются следую-


щие правила: результатом сравнения любого значения со зна-
че.нием NULL всегда является NULL; применение логическо-
го оператора NOT к значению NULL все равно возвращает
NULL; если в условном операторе выражение возвращает
значение NULL, то последовательность операторов, указан-
ная в этом условном операторе, не выполняется.
Для обработки неопределенных значений в языке SQL
используется специальный оператор IS NULL.
Предикат IS NULL имеет следующий синтаксис:

Предикат IS NULL ::= имя_столбца IS [NOT] NULL

Предикат IS [NOT] NULL всегда принимает значения


TRUE или FALSE. При этом значение х IS NULL равно TRUE
тогда и только тогда, когда значение х не определено. Значе-
ние предиката х IS NOT NULL равно значению NOT (x IS
NULL).
Проиллюстрируем использование предиката IS NULL на
таблице, созданной и заполненной предложениями:

CREATE TABLE Tab! (Atl C H A R ( 3 ) , At2 NUMBER);


1
INSERT INTO Tabl V A L U E S ( ' A , 1);
INSERT INTO Tabl V A L U E S ( ' В ' , N U L L } ;

Следующие запросы демонстрируют использование пре-


диката IS NULL:

SQL> SELECT * FROM Tabl WHERE At2 IS NULL;


ATI AT2

В .

SQL> SELECT * FROM Tabl WHERE At2 IS NOT NULL;

119


Раздел 2

ATI AT2

A 1

Листинг 44. Примеры использования предиката IS


NULL

Предикат EXISTS
Предикат EXISTS принимает истинное значение, если не
пуст результат некоторого подзапроса. Предикат EXISTS мо-
жет вычисляться автономно или в комбинации с другими
предикатами, соединенными логическими связками. Данный
предикат не может принимать неопределенного значения, то
есть его значением всегда является TRUE или FALSE. Значе-
ние равно TRUE тогда и только тогда, когда результат вычис-
ления подзапроса не пуст.
Предикат EXIST использует следующий синтаксис:

Предикат EXISTS ::= EXISTS подзапрос

Проиллюстрируем использование предиката EXISTS на


таблице, созданной и заполненной предложениями:
CREATE TABLE Tab! (Atl CHAR(l), At2 NUMBER);
INSERT INTO Tabl VALUES ('A',1);
INSERT INTO Tabl VALUES ('B\2);

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


предиката EXISTS выполняется выборка всех строк таблицы
ТаЫ, для которых есть (существует) строка, у которой атри-
бут At2 имеет меньшее значение:

SQL> SELECT * FROM ТаЫ a WHERE EXISTS


2 (SELECT * FROM Tabl b WHERE a.At2 > b.At2);

120
SQL — язык обработки данных Oracle
ATI AT2

В 2

Листинг1 45. Пример использования предиката EXISTS


для вложенного подзапроса

Обратите внимание на распространенную ошибку при


использовании предиката EXISTS. Следующий запрос выдает
все .строки таблицы Tabl, а не вторую строку, как можно
ошибочно ожидать:

SELECT * FROM Tabl WHERE EXISTS


(SELECT Atl FROM-Tabl WHERE At2 >1);

На самом деле подзапрос, указанный в скобках, возвра-


щает что-то и, следовательно, предикат EXISTS принимает
истинное значение для любой строки таблицы Tabl.
Oracle допускает использование агрегирующих функций
в подзапросе. При этом необходимо осознавать сомнитель-
ность подобных конструкций: ведь если найдены какие-либо,
данные для вычисления функции, предикат EXISTS возвра-
щает истинное значение независимо от результата функции.-
Предикаты с кванторами
ALL, ANY и SOME
Предикат ALL несет стандартную нагрузку квантора все-
общности, а предикаты ANY и SOME соответствуют стандар-
тно понимаемому квантору существования. Предикаты ANY
и SOME в Oracle несут одинаковую смысловую нагрузку и
полностью взаимозаменяемы. В любом запросе вместо пре-
диката ANY можно использовать SOME и наоборот — ре-
зультат будет одинаков. Использование двух равнозначных
ключевых слов, видимо, обусловлено стремлением облегчить
составление запросов для англоязычных пользователей. Пре-
дикаты с кванторами имеют следующий синтаксис:

121
Раздел 2

Предикат с квантором ::= выражение {•-= \ О \ >=


|<= I > I < }
{ALL I SOME | ANY } подзапрос

Дня пояснения механизма вычисления результата запроса


обозначим через х результат вычисления выражения левой
части предиката, а через S результат вычисления подзапроса.
Предикат (х операция ALL S) принимает значение TRUE,
если S пусто или значение предиката х операция s истинно
для каждой строки s, входящей в S. Предикат х операция ALL
S имеет значение FALSE, если значение предиката х операция
s ложно хотя бы для одной строки s, входящей в S.
Предикат (х операция SOME S) принимает значение
TRUE, если значение предиката х операция s истинно хотя бы
для одной строки s, входящей в S. Предикат (х операция
SOME S) принимает значение FALSE, если S пусто или зна-
чение предиката х операция s ложно для каждой строки s,
входящей в S.
Предостережем читателя, знакомого с математической
логикой, от поспешных формально-логических выводов. Дей-
ствительно, любой запрос, содержащий предикат SOME, мо-
жет быть сформулирован с предикатом EXISTS, но обратное
утверждение неверно. Отличие обработки предиката с
EXISTS от обработки предиката с SOME или с ALL в том, как
обрабатываются пустые значения (NULL). С формальной
точки зрения можно построить любой правильный запрос,
пользуясь только предикатами EXISTS и IS NULL. Тем не
менее многие пользователи находят применение предикатов
SOME и ALL более удобным.

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

122
SQL — язык обработки данных Oracle

Операции, поддерживаемые в Oracle, интерпретируются


.следующим образом:
UNION — формальное объединение результатов всех ис-
ходных запросов в виде отношения (то есть с устранением
повторяющихся строк);
UNION ALL — формальное объединение результатов
всех исходных запросов с сохранением повторяющихся
строк;
INTERSECT — формальное пересечение; включает
строки, входящие во все результаты составляющих запросов,
повторяющиеся строки исключаются;
MINUS — результирующее множество содержит все
строки, вошедшие в результат первого запроса, но не вошед-
шие в результат второго; повторяющиеся строки исклю-
чаются.
Все теоретико-множественные операции имеют одина-
ковый приоритет и выполняются слева направо. Очевидно,
что, за исключением MINUS, операции коммутативны. По-
скольку в последующих версиях Oracle для совместимости с
планируемыми международными стандартами, возможно,
приоритет операции INTERSECT будет выше, чем остальных
теоретико-множественных операций, целесообразно для уст-
ранения неоднозначности расставлять скобки, явно опреде-
ляющие порядок выполнения операций.
Естественно, что результаты запросов во всех множест-
вах, участвующих в теоретико-множественной операции,
должны быть согласованы по количеству столбцов и их ти-
пам.
Обратите внимание, что допускается проведение опера-
ции, если в части результатов данные имеют тип CHAR, a
часть — VARCHAR2. Соответствующие данные результата
всегда имеют тип VARCHAR2.
При выполнении теоретико-множественных операций,
отличных от UNION ALL, неявно выполняется выборка всех
записей и их сортировка, поэтому время выполнения запроса
может оказаться неожиданно большим.
123
Раздел 2

Проиллюстрируем использование теоретико-множест-


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

CREATE TABLE Tab! (Atl NUMBER);


CREATE TABLE Tab2 (Atl NUMBER);
INSERT INTO Tabl VALUES (1);
INSERT INTO Tabl VALUES (2);
INSERT INTO Tabl VALUES (3);
INSERT INTO Tab2 VALUES (1);
'INSERT INTO Tab2 VALUES (3);
INSERT INTO Tab2 VALUES (5);

Следующие запросы демонстрируют использование тео-


ретико-множественных операций:

SQL> SELECT * FROM Tabl UNION SELECT * FROM Tab2;

ATI

I
2
3
5

SQL> SELECT * FROM Tabl


2 UNION ALL SELECT * FROM Tab2;

ATI

1
2
3
1
3
5

SQL> SELECT * FROM Tabl


2 INTERSECT SELECT * FROM Tab2;

124
SQL — язык обработки данных Oracle
ATI

1
3

SELECT * FROM Tab! MINUS SELECT * FROM Tab2;

ATI

2
Листинг 46. Примеры использования теоретико-
множественных операций в запросах

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

CREATE TABLE Tab! (Atl NUMBER, At2 VARCHAR2(1) ) ;


CREATE TABLE Tab2 (Atl NUMBER, At2 VARCHAR2(1)) ;
INSERT INTO Tabl VALUES (1, 'A')
INSERT INTO Tabl VALUES (2, 'B')
'INSERT INTO Tabl VALUES (3, 'C')
INSERT INTO Tab2 VALUES (1, 'a')
INSERT INTO Tab2 VALUES (3, 'b')
INSERT INTO Tab2 VALUES (5, 'с')

125
Раздел 2

Рассмотрим пример декартова произведения таблицы


Tab! на таблицу ТаЬ2 и простого объединения, где критерием
отбора служит равенство значений атрибутов Atl таблиц
Tab! и ТаЬ2.

SQL> SELECT Tabl.Atl,Tabl.At2,Tab2.Atl,Tab2.At2


2 FROM TAB1,TAB2;

ATI AT2 ATI AT2

1A l a
2В l a
3С l a
1 A 3 b
2 В 3 b
3 С 3 b
1 A 5 с
2 В 5 с
3С . 5 с
9 rows selected.

SQL> SELECT * FROM Tabl,Tab2


2 WHERE Tabl.Atl=Tab2.Atl;

ATI AT2 ATI AT2

1 A l a
3 С 3 b

Листинг 47. Примеры декартова произведения и про-


стого соединения для запросов, содержащих
две таблицы

Внешнее объединение (outer join) в общем случае отби-


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

126
SQL — язык обработки данных Oracle

пользуемому критерию отбора ни с одной строкой другой


таблицы.
Внешнее объединение отображается в конструкции фра-
зы WHERE в одной из двух форм:

[таблица!.]столбец = [таблица2.]столбец (+)


[таблица2,]столбец ( + ) = [таблица!.]столбец

Символ внешнего объединения (+) должен следовать не-


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

SQL> SELECT * FROM Tabl,Tab2


2 WHERE T a b l . A t l = T a b 2 . A t l ( + ) ;

ATI A ATI A

1 A l a
2 В
3 С 3 b

SQL> SELECT * FROM Tabl,Tab2


2 WHERE Tabl.Atl(+) = Tab2.Atl;

ATI A ATI A

1 А 1 а
з• С 3 b
5 с -

Листинг 48. Примеры внешнего объединения, зада-


ваемого на столбцах различных таблиц

127
Раздел 2

Сортировка
Для сортировки результатов запроса по возрастанию или
убыванию используется ключевое слово ORDER BY. Без ука-
зания этого ключевого слова строки извлекаются в произ-
вольном порядке.
Сортировка задается использованием следующей синтак-
сической конструкции:

ORDER BY{выражение\ -положение |


альтернативное_имя_ столбца}
[ASC I DESC] [ , . . . ]

Параметр выражение принимает значение выражения,


базирующегося на одном или нескольких столбцах, перечис-
ленных после ключевого слова SELECT. Строки с одинако-
выми значениями по первому выражению упорядочиваются
по второму выражению (если оно определено) и так далее.
Параметр положение задает число, идентифицирующее
позицию столбца в перечислении после ключевого слова
SELECT, то есть вместо указания имен столбцов можно ука-
зать номер позиции столбца в списке SELECT.
Ключевые слова ASC или DESC определяют возрастаю-
щий или убывающий соответственно порядок сортировки.
Обратите внимание на то, что значение NULL рассмат-
ривается как "самое тяжелое" и размещается в конце списка
при сортировке в порядке возрастания (ASC) и в начале спи-
ска — при сортировке в порядке убывания (DESC).
На использование ключевого слова ORDER BY нало-
жены ограничения:
— ключевое слово ORDER BY в предложении SELECT
должно быть размещено после всех остальных ключевых
слов за исключением FOR UPDATE. Фрагменты с ключевы-
ми словами ORDER BY и FOR UPDATE можно менять мес-
тами;

128
SQL — язык обработки данных Oracle

— если в предложении SELECT присутствует ключевое


слово DISTINCT, то в списке ORDER BY не должны присут-
ствовать столбцы, не упоминавшиеся в списке отбора
SELECT;
— ключевое слово ORDER BY нельзя использовать в
подзапросах для операторов INSERT, UPDATE, CREATE
TABLE и CREATE VIEW;

Проиллюстрируем механизм сортировки на таблице, соз-


данной и заполненной предложениями:

CREATE TABLE Tab! (Atl NUMBER, At2 VARCHAR2(1));


INSERT INTO Tabl VALUES (1, NULL);
INSERT INTO Tabl VALUES (1, 'A1);
INSERT INTO Tabl VALUES (2, 'B');
INSERT INTO Tabl VALUES (3, 'C');
INSERT INTO Tabl VALUES (3, 'A');

Рассмотрим пример сортировки с использованием двух


выражений Atl* 10 и At2, заданных в списке сортировки их
положениями в списке SELECT.

SQL> SELECT Atl-*10, At2 FROM Tabl


2 ORDER BY 1 ASC, 2 DESC;

AT1*10 AT2

10
10 A
20 В
30 С
30 A

Листинг 49. Пример сортировки с использованием


двух выражений в списке сортировки

В любом случае на сортировку тратится значительное ко-


личество ресурсов. При использовании режима сортировки
129
5. Заказ № 1628.
Раздел 2

обязательно надо учитывать, что сортировка неявно произво-


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

Иерархии
Выдача данных на основании их иерархической упоря-
доченности осуществляется с использованием ключевых слов
CONNECT BY и START WITH. Ключевое слово CONNECT
BY определяет структуру иерархической связи. CONNECT
BY определяет как строки, выбираемые в иерархическом по-
рядке, так и отношение, используемое для объединения строк
в иерархию (заданием ключевого слова PRIOR).
Иерархическое упорядочение задается использованием
следующей синтаксической конструкции:

[START WITH условие] CONNECT BY условие

Ключевое слово PRIOR, задаваемое в параметре условие


после ключевого слова CONNECT BY, определяет порядок
выборки элементов иерархии. Нисходящая выборка по иерар-
хии (от корня к листьям дерева) или восходящая (от листьев к
корню дерева) определяется положением ключевого слова
PRIOR относительно атрибутов, задающих отношение иерар-
хии. Количество уровней CONNECT BY ограничивается дос-
тупной пользователю памятью.

130
SQL — язык обработки данных Oracle

Ключевое слово CONNECT BY нельзя использовать вме-


сте с подзапросами и объединениями.
Ключевое слово START WITH идентифицирует строки
(или строку), которые будут использоваться в качестве корня
дерева. Соответствующие строки (строка) определяются че-
рез условие, которому они должны удовлетворять. Отсутст-
вие ключевого слова START WITH означает начало выборки
иерархий со всех столбцов, удовлетворяющих условию, за-
данному ключевым словом WHERE. В предложении START
WITH допустимы подзапросы.
В любом запросе автоматически определяется и может в
нем использоваться псевдостолбец LEVEL, которому при-
сваивается значение 1 для корневого элемента иерархии, 2 —
для вершин, непосредственно связанных с корневым элемен-
том и т. д.
Проиллюстрируем технику иерархической выборки на
таблице, в которой атрибут Atl задает номер вершины-роди-
теля, а атрибут At2 задает номер вершины-потомка.
Пусть таблица Tab! создана и заполнена предложениями:

CREATE TABLE Tab! (Atl NUMBER, At2 NUMBER);


INSERT INTO Tabl VALUES (1, 2)
INSERT INTO Tabl VALUES (1, 3)
INSERT INTO Tabl VALUES (2, 4)
INSERT INTO Tabl VALUES (3, 5)
INSERT INTO Tabl VALUES (4, 6)
INSERT INTO Tabl VALUES (5, 7)

Рассмотрим запрос, в котором выборка осуществляется в


направлении "родитель-потомок" (ключевое слово PRIOR
справа от знака равенства). Выводимый псевдостолбец
LEVEL показывает уровень вложения в иерархии. Корневая
вершина имеет значение атрибута Atl равное 1.

SQL> SELECT LEVEL, Atl, At2 FROM Tabl


2 CONNECT BY Atl = PRIOR At2

131
Раздел 2
-3 START WITH Atl = 1;

LEVEL ATI AT2

1 1 2
2 2 4
3 4 6
1 1 3
2 3 5
3 5 7

Листинг 50. Пример иерархической выборки с на-


правлением "родитель-потомок" (нисходящая
выборка)

Сопоставьте результат предыдущего запроса с результа-


том запроса, в котором выборка осуществляется в обратном
направлении (ключевое слово PRIOR слева от знака равенст-
ва). Корневая вершина имеет значение атрибута At2 равное 7.

SQL> SELECT LEVEL, Atl, At2 FROM Tabl


2 CONNECT BY PRIOR Atl = At2
3 START WITH At2 = 7;

LEVEL ATI AT2

1 5 7
2 3 5
3 1 3

Листинг 51. Пример иерархической выборки с восхо-


дящим направлением выборки

132
SQL — язык обработки данных Oracle

Группирование
и агрегатные функции
Для организации группирования отобранных данных с
целью их совместной обработки используется ключевое сло-
во GROUP BY. Совместная обработка данных обычно сво-
дится к вычислению некоторой функции: суммы, среднего
значения, числа элементов множества отобранных значений и
т. п. Ключевое слово HAVING используется для формирова-
ния дополнительных условий включения групп в результи-
рующее множество.
Использование ключевого слова GROUP BY приводит к
тому, что оператор SELECT выдает одну производную строку
для каждой группы строк, формируемых на основе одинако-
вых значений для столбцов или выражений. Следует отме-
тить, что, как правило, все столбцы, которые указываются в
конструкции GROUP BY и по которым осуществляется груп-
пировка, должны присутствовать в списке после ключевого
слова SELECT. В противном случае при выполнении запроса
можно получить сообщение о том, что группирующая функ-
ция не является одногрупповой.
Синтаксис конструкции группирования строк:

GROUP BY выражение [, выражение ]


[HAVING условие]

Элемент выражение может быть атрибутом, константой


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

133
Раздел 2

1. Из рассмотрения удаляются * все строки, не


удовлетворяющие условию WHERE;
2. Вычисляются и формируются группы в соответствии с
предложением GROUP BY;
3. Из результирующего множества удаляются все группы, не
удовлетворяющие условию HAVING.
Если присутствуют оба ключевых слова (GROUP BY и
HAVING), они могут задаваться в любом порядке.
Проиллюстрируем использование ключевых слов GROUP
BY и HAVING на таблице, созданной и заполненной предло-
жениями:

CREATE TABLE Tabl (Atl NUMBER, At2 NUMBER);


INSERT INTO Tabl VALUES(1, 1);
INSERT INTO Tabl VALUES(1, 2);
INSERT INTO Tabl VALUES(2, 3);
INSERT INTO Tabl VALUES(2, 4);

Следующие запросы демонстрируют использования


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

SQL> SELECT Atl, AVG(At2) "Среднее At2"


2 FROM Tabl GROUP BY Atl;

ATI Среднее At2

1 1.5
2 3.5

SQL> SELECT Atl, AVG(At2) "Среднее At2"


2 FROM Tabl GROUP BY Atl HAVING AVG(At2) > 2;

ATI Среднее At2

2 3.5
Листинг 52. Примеры расчетов безусловного средне-
го и условного среднего

134
SQL — язык обработки данных Oracle

Обратите внимание, что условие, заданное ключевым


словом HAVING, должно относиться к сформированной ус-
ловием GROUP BY группе, а не к конкретным значениям ат-
рибута. Если условие отбора относится не к группе, а к атри-
бутам, то оно должно быть указано после ключевого слова
WHERE. Приведенный пример иллюстрирует сказанное:

SQL> SELECT A t l , A V G ( A t 2 ) "Среднее A t 2 "


2 FROM Tabl GROUP BY Atl HAVING At2 > 1;
*

ERROR at line 2:
ORA-00979: not a GROUP BY expression'

SQL> SELECT Atl, AVG(At2) "Среднее At2"


2 FROM Tabl WHERE At2 > 1 GROUP BY Atl;
Ч

ATI Среднее At2

1 2
2 «• 2.5

Листинг 53. Примеры формирования условий, опреде-


ляющих группу для групповой функции

Групповые функции возвращают результаты, вычислен-


ные по группе строк, которые сформированы запросом с
предложением GROUP BY оператора SELECT.
При выполнении вычислений для групповых функций по
умолчанию используется ключевое слово ALL, которое ука-
зывает, что результат включает все значения атрибута, в том
числе и дублирующие. Если в запросе использовано ключевое
слово DISTINCT, то групповые функции рассматривают
только отличающиеся значения атрибутов или выражений.
Все групповые функции, кроме COUNT(*), не учитывают в
вычислениях атрибутов, имеющих неопределенное значения
(NULL). Для замены неопределенного значения числовых

135
Раздел 2

атрибутов на 0 обычно используют встроенную функцию


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

CREATE TABLE Tabl (Atl NUMBER);


INSERT INTO Tabl V A L U E S ( 1 ) ;
INSERT INTO Tabl V A L U E S ( 1 ) ;
INSERT INTO Tabl V A L U E S ( 2 ) ;
INSERT INTO Tabl V A L U E S ( N U L L ) ;
Функция вычисления среднего значения AVG возвращает
среднее значение числового аргумента выражение, не вклю-
чая в вычисления значения NULL. Функция использует сле-
дующий синтаксис:

AVG([DISTINCT I ALL] выражение)

Для пояснения различий, связанных с включением или


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

SQL> SELECT AVG(Atl) " (1+1+2)/3" FROM Tabl;

(1+1+2)/3

1.3333333

SQL> SELECT AVG( DISTINCT Atl) " (1+2)/2"


2 FROM Tabl;

(1+2)/2

1.5

SQL> SELECT AVG( NVL(Atl,0)) " (1+1+2+0)/4"


2 FROM Tabl;

(1+1+2+0)74

136
SQL — язык обработки данных Oracle

Листинг 54. Примеры, иллюстрирующие учет включе-


ния в группу конкретных значений" атрибутов
f

Функция вычисления суммы SUM возвращает сумму зна-


чений числовых атрибутов, не включая в вычисления значе-
ния NULL. Функция использует следующий синтаксис:

SUM({DISTINCT j ALL] выражение)


Функция вычисления дисперсии (стандартного уклоне-
ния) STDDEV возвращает дисперсию значений числовых ат-
рибутов, не включая в вычисления значения NULL. Функция
использует следующий синтаксис:

STDDEV( [DISTINCT |. ALL] выражение)

Функция VARIANCE вычисляет квадрат дисперсии зна-


чений числовых атрибутов, не включая в вычисления зна-
чения NULL. Функция использует следующий синтаксис:

VARIANCE([DISTINCT | ALL] выражение)

Приведенный ниже пример иллюстрирует применение


статистических групповых функций:

SQL> SELECT S U M ( A t l ) , S T D D E V ( A t l ) ,
2 SQRT(VARIANCE(Atl)) FROM Tabl ;

SUM(ATl) STDDEV(ATl) SQRT(VARIANCE(ATI))

4 .57735027 .57735027

Листинг 55. Пример вычисления квадратичных груп-


повых функций

137
Раздел 2
Функция подсчета числа отобранных строк COUNT воз-
вращает количество выбранных строк. Особый вариант ис-
пользования функции COUNT(*) возвращает число строк в
таблице, включая дубликаты и атрибуты с неопределенными
значениями. Функция использует следующий синтаксис:

COUNT([DISTINCT I ALL] выражение \ *)

Дня пояснения различий в подсчетах при использовании


функции COUNT рассмотрим пример.

SQL> SELECT COUNT(DISTINCT A t l ) , C O U N T ( A t l ) ,


2 COUNT(*) FROM Tabl;

COUNT(DISTINCT A T I ) COUNT(ATI) C O U N T ( * )

2 3 4

Листинг 56. Пример различий в вычислении функции


числа строк

Функция выбора наибольшего значения МАХ возвращает


максимальное значение параметра. Функция использует сле-
дующий синтаксис:

МАХ([DISTINCT | ALL] выражение)

Функция выбора наименьшего значения MIN возвращает


минимальное значение параметра. Функция использует сле-
дующий синтаксис:

MIN([DISTINCT | ALL] выражение)'

Для примеров использования групповых функций МАХ и


MEM используем таблицу, созданную и заполненную предло-
жениями:
CREATE TABLE Tabl (Atl VARCHAR2(1), At2 DATE);
INSERT INTO Tabl VALUES ('АЧ, ' 15-06-2001');
138
SQL — язык обработки данных Oracle
INSERT INTO Tabl V A L U E S ( ' B ' , ' 2 1 - 0 9 - 2 0 0 1 ' ) /
INSERT INTO Tabl V A L U E S ( ' С ' , N U L L ) ;

Рассмотрим пример определения максимального и мини-


мального значения столбца.

SQL> SELECT MAX(Atl), MIN(At2) FROM Tabl;

MAX(Atl) MIN(At2)

С 15-06-2001

Листинг 57. Пример определения максимального и


минимального значения столбца

Синтаксис языка запросов


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

SELECT [DISTINCT | ALL] { *| { [имя_схемы.]{


имя_таблицы | имя_представления \ имя_снимка }.*\
выражение [ [AS] альтернативное_имя_столбца ] }
[ , { [имя_схемы. ] { имя_таблицы \ имя_представления
I имя_ снимка } . * | выражение
[ [AS] альтернативное_имя_столбца ] } ] ... }
FROM {[имя_схемы . ] { { имя_таблицы \
имя_представления \ имя_снимка } [@имя_связиБД]
} | (имя__подзапроса) }
[ локальное_альтернативное_имя]
[, { [имя_схемы . ] { { имя_таблицы \
имя__представления \ имя_снимк'а } [@имя_связиБД]
}| (имя_ подзапроса) }
[ локальное_альтернативное_имя] ] ...
[WHERE условие ]
139
Раздел 2
{ { [GROUP BY - выражение [ , выражение ] ....
[HAVING условие ] }
I { [ S T A R T WITH условие] CONNECT BY условие]} . ..
[{UNION | UNION ALL | INTERSECT | MINUS}
предложение^ ELECT ]
[ORDER BY { выражение \ положение \
альтернативное_имя_столбца }
[ASC I DESC]
[, { выражение I положение \
альтернативное_имя_столбца ] [ASC | DESC]] . . . ]
[FOR UPDATE [OF [[имя_схемы . ] { имя_таблицы | .
имя_представлёния ]] имя_столбца . [ , [имя_схемы .]
{имя_таблицы | имя_представления }] имя_столбца
...] [NOWAIT]]

Описание полного синтаксиса оператора выборки


достаточно велико. Поэтому будем рассматривать сокращен-
ное множество конструкций оператора SELECT. Полное опи-
сание синтаксиса доступно в соответствующей части доку-
ментации OracleS SQL Reference.
Фрагменты предложения SELECT должны быть записа-
ны в указанном порядке. Указание ключевого слова
DISTINCT приводит к устранению из отобранных данных
повторяющихся строк. Указание ключевого слова ALL при-
водит к предъявлению всех отобранных данных, включая по-
вторяющиеся строки. По умолчанию используется значение
ALL.
Наличие параметра * (звездочка) означает выбор всех
столбцов из всех таблиц, представлений и снимков, указан-
ных в перечне значений ключевого слова FROM.
Конкретный выбор значения параметра {шля_таблщы \
имя представления \ имя_снимка}.* означает выбор всех
столбцов из таблицы, представления или снимка. Необяза-
тельный параметр имя_схемы используется для уточнения
имени схемы, в которой находится соответствующий объект.
По умолчанию используется схема пользователя, выполняю-
щего запрос.

140
SQL — язык обработки данных Oracle

Параметр выражение заменяется на вычисляемое выра-


жение, которое обычно базируется на данных столбцов из
таблиц, представлений и снимков, указанных в перечне зна-
чений ключевого слова FROM.
Параметр альтернативное_имя_столбца задает альтер-
нативное имя столбца или выражения для формирования за-
головка при выводе ответа на запрос. Заданное значение па-
раметра'может также использоваться в выражении ORDER
BY.
Ключевое слово FROM определяет таблицы, представле-
ния или снимки, из которых будут отбираться данные.
Параметр имя_связиБД устанавливает имя связи с уда-
ленной базой данных. Если имя связи с удаленной базой дан-
ных не указано, предполагается, что соответствующий объект
расположен в основной базе данных.
Параметр имя_подзапроса задает подзапрос, который в
данном контексте рассматривается так же, как представление.
Параметр локальное_альтернативное_имя задает альтер-
нативное, обычно короткое, имя, которое в контексте данного
запроса является обязательным для ссылок именем соответ-
ствующей таблицы, представления или снимка.
Ключевое слово WHERE определяет логическое условие
отбора данных. Если ключевое слово WHERE опущено, то
возвращается декартово произведение всех таблиц, представ-
лений и снимков, указанных в перечне значений ключевого
слова FROM.
Ключевые слова GROUP BY и HAVING используются
для формирования некоторой обобщающей информации о
группах строк, имеющих определенные значения в одном или
нескольких полях, описываемые параметрами выражение и
условие. Для каждой группы строк, формируемой предложе-
нием GROUP BY выражение, создается одна строка произ-
водных данных. Множество групп может быть уточнено ло-
гическим условием отбора, определяемым предложением
HAVING.

141
Раздел 2

Ключевые слова START WITH и CONNECT BY задают


иерархический порядок отбора данных запроса. Конкретная
иерархическая упорядоченность задается параметрами усло-
вие.
Ключевые слова UNION, UNION ALL, INTERSECT,
MINUS задают теоретико-множественные операции объеди-
нения результатов нескольких запросов, сформированных в
соответствии со значением параметра предложение JSELECT.
Для объединенных результатов не допускается использование
конструкции FOR UPDATE.
Ключевое слово ORDER BY определяет порядок, в кото-
ром будут выдаваться строки результирующего отношения.
Параметр выражение определяет значение, по которому вы-
полняется сортировка. Базис сортировки может также быть
указан параметром положение, то есть порядковым номером
в списке вывода (задаваемом после ключевого слова
SELECT). По умолчанию используется сортировка по возрас-
танию (ASC).
Конструкция FOR UPDATE определяет необходимость
блокировки отобранных строк. Необязательное ключевое
слово OF уточняет перечень таблиц или представлений, дан-
ные из которых должны быть заблокированы.
Необязательное ключевое слово NOWAIT указывает на
то, что в случае, если требуемые для блокировки строки не-
доступны (то есть заблокированы другим процессом), воз-
вращается сообщение об ошибке (как правило, ORA-00054).
Если ключевое слово NOWAIT не указано, то .выполнение
запроса будет приостановлено.до тех пор, пока не будут ос-
вобождены все требуемые для блокировки строки.

142
SQL — язык обработки данных Oracle

Связи с удаленными базами


данных. Снимки данных
Создание связей с удаленной базой
данных Oracle

Для создания связи с удаленной базой данных использу-


ется SQL-оператор CREATE DATABASE LINK. Поддержи-
ваются связи как с удаленными базами данных под управле-
нием Oracle, так и с базами данных некоторых других произ-
водителей, например DB2 фирмы IBM. Естественно, что и на
локальной, и на удаленной базе данных должно быть уста-
новлено специальное программное обеспечение.
Для создания связи с удаленной базой данных необхо-
димо иметь учетную запись в удаленной базе данных. Для
этой учетной записи имя пользователя может совпадать с
именем пользователя, который создает связь, а может и раз-
личаться.
Оператор создания связи с удаленной базой данных
Oracle использует следующий синтаксис:

CREATE [PUBLIC] DATABASE LINK имя_связиБД


[CONNECT TO имя_пользователя
IDENTIFIED BY пароль_пользователя]
USING 'строка_связи'

Если ключевое слово PUBLIC опущено, создается связь,


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

143
Раздел 2

Создав связь с удаленной базой данных, можно обра-


щаться к таблицам удаленной базы в запросах, ссылаясь на
них во фразе FROM с тем же эффектом, что и при прямом
подключении к удаленной базе данных. Если в предложении
создания связи конструкция, содержащая имя пользователя и
пароль, отсутствует, будут использоваться имя и пароль те-
кущего пользователя. Для доступа к объектам удаленной ба-
зы данных к их именам добавляется имя связи (@имя_связи).
Запросы, выполняемые с использованием связи с удален-
ной базой данных, подчиняются следующим ограничениям:
— максимальное количество связей с удаленными база-
ми, которые можно использовать в одном запросе, определя-
ется значением параметра OPENJLINKS файла параметров;
— использование команд языка манипулирования дан-
ными INSERT, DELETE, UPDATE требует наличия установки
для сервера Oracle возможностей, реализуемых компонентой
Distributed Options.
Рассмотрим пример определения связи sun_orajink, ко-
торая использует учетную запись пользователя ul с паролем
ulpsw в удаленной базе данных, определяемой строкой связи
sunora. После успешного создания связи с удаленной базой
данных можно выполнить запрос к ее таблицам, как показано
в приведенном примере:

SQL> CREATE DATABASE LINK sun_ora_link


2 CONNECT TO ul IDENTIFIED BY ulpsw
3 USING 'sunora';
Database link created.

SQL> SELECT * FROM Tabl@sun_ora_link;


ATI

1
2
i
Листинг 58. 'Протокол создания связи с удаленной
базой данных и запроса с использованием со-
зданной связи
144
SQL — язык обработки данных Oracle

Для того чтобы скрыть от пользователя факт, что таблица


Tab! пользователя ul находится в удаленной базе данных,
можно использовать синоним. Приведенный в листинге 59
пример иллюстрирует данный метод.

SQL> CREATE SYNONYM suntabl


2 FOR ul.Tabl@sun_ora_link;
Synonym created.

SQL> SELECT * FROM suntabl;

ATI

1
2

Листинг 59. Протокол создания синонима для неяв-


ной поддержки связи с удаленной базой дан-
ных и запроса с его использованием

Для удаления связи с удаленной базой данных использу-


ется команда DROP DATABASE LINK. Для выполнения этой
команды необходимо либо быть владельцем связи с удален-
ной базой данных, либо иметь привилегию DROP ANY DA-
TABASE LINK. Оператор уничтожения связи с удаленной
базой данных Oracle использует следующий синтаксис:

DROP [PUBLIC] DATABASE LINK имя_связиБД

Параметр PUBLIC должен быть определен для удаления


общей связи с удаленной базой данных. Параметр
гшя_связиБД задает имя удаляемой связи. Рассмотрим пример
отмены (удаления) связи с удаленной базой данных по имени
sun ora link.

SQL> DROP DATABASE link sun_ora_link;


145
Раздел 2
Database link dropped.

Листинг 60. Пример, удаления Ьвязи с удаленной ба-


зой данных

Средства определения
и уничтожения снимков

Снимок — это поименованная динамически поддержи-


ваемая сервером выборка из одной или нескольких таблиц
или представлений, обычно размещенных на удаленной базе
данных. Сервер гарантирует актуальность снимка в рамках
принятой технологии: а именно, формирование снимка (мате-
риализация соответствующего запроса) производится в соот-
ветствии с некоторым расписанием. Используя снимки, адми-
нистратор безопасности обеспечивает доступ пользователям к
тем частям удаленных баз данных, которые реально необхо-
димы для выполнения их работы.
Для того чтобы механизм снимков работал, на серверах
локальной и удаленной баз данных должен быть установлен
пакет DBMS_SNAPSHOT, в котором находятся процедуры,
выполняющие обновление снимков. Для серверов Oracle с
Procedural Option такой пакет устанавливается автоматически,
для остальных версий поставки для создания пакета необхо-
димо, чтобы пользователь SYS выполнил сценарии
dbmssnap.sql и prvtsnap.plb. Для создания снимков, исполь-
зующих таблицы и представления удаленной базы данных,
необходимо, чтобы сервер был установлен с дополнительны-
ми возможностями, реализуемыми компонентой Distributed
Option.
Оператор определения снимков Oracle использует сле-
дующий синтаксис:

CREATE SNAPSHOT [*иш_ схемы.]имя_снимка


[{PCTFREE целое | PCTUSED целое | .INITRANS целое
I MAXTRANS целое |
TABLESРАСЕ имя_табличной_области\
146
SQL — язык обработки данных Oracle
STORAGE размер__памяти } ]
[CLUSTER имя_кластера ( имя_столбца [ , . . . ] ) ]
[USING INDEX]
[{PCTFREE целое \ PCTUSED целое | INITRANS целое
\ MAXTRANS целое I
TABLESPACE имя_табличной_области\
STORAGE размер_памяти}] ]
[REFRESH [{FAST I COMPLETE | FORCE }]
[START WITH дата_1 } [NEXT ,дата_2 ] ]
[FOR UPDATE] AS запрос

Ключевые слова PCTFREE, PCTUSED, INITRANS,


MAXTRANS, TABLESPACE, STORAGE характеризуют про-
странство, распределяемое при работе со снимком.
Ключевое слово PCTFREE определяет процент блоков,
резервируемых для дальнейшей модификации данных табли-
цы. Допустимые значения от 0 до 99. Значение по умолчанию
10, то есть если данный параметр не указан, то при заполне-
нии каждого блока 10% пространства остается не использо-
ванным для записи в него данных для выполнения в даль-
нейшем модификации строк снимка.
Ключевое слово PCTUSED определяет минимальный
процент использования пространства блока, при котором в
него вводятся данные. Допустимые значения от 1 до 99. Зна-
чение по умолчанию 40, то есть, если в блоке занято менее
40% пространства, в него вводятся данные при выполнении
операции вставки. Сумма значений параметров PCTFREE и
PCTUSED не должна превышать 100.
Ключевое слово INITRANS определяет начальное число
параллельных транзакций, которые могут выполняться для
модификации данных блока. Значение по умолчанию 1. Клю-
чевое слово MAXTRANS определяет максимальное число
параллельных транзакций, которые могут выполняться для
модификации данных блока. В большинстве случаев явное
задание этих параметров не требуется.
Ключевое слово TABLESPACE определяет имя таблич-
ной области, в которой будет размещена таблица. Если значе-
147
Раздел 2

ние параметра не определено, то таблица размещается в таб-


личной области, заданной по умолчанию для пользователя,
который является владельцем схемы, содержащей снимок.
Ключевое слово STORAGE определяет объем внешней
памяти, выделяемый под снимок. Для больших снимков целе-
сообразно явно выделять требуемую память для уменьшения
запросов на динамическое выделение пространства.
Ключевое слово CLUSTER указывает привязку столбцов
снимка к кластеру. Обычно столбцы кластера образуют из
элементов первичного ключа базовых таблиц.
Ключевое слово USING INDEX определяет создание ин-
декса для уменьшения времени доступа к данным снимка.
При этом ключевые слова PCTFREE, PCTUSED, INITRANS,
MAXTRANS, TABLESPACE, STORAGE характеризуют про-
странство, распределяемое для индекса снимка, и имеют тот
же смысл, что и соответствующие параметры, характеризую-
щие пространство самого снимка.
Ключевое слово REFRESH определяет технологию об-
новления снимка. Если задан параметр COMPLETE, то для
обновления данных снимка заново выполняется запрос, фор-
мирующий данные снимка. Если задан параметр FAST (быст-
рое обновление), то для обновления данных снимка исполь-
зуется информация об измененных данных в мастер-таблице,
хранящаяся в журнальном файле снимка. При используемом
по умолчанию параметре FORCE, решение о технологии об-
новления снимка принимается системой (обычно это быстрое
обновление).
Ключевое слово START WITH определяет с помощью
параметра дата_1 дату первого автоматического обновления
снимка. Естественно, параметр дата_1 должен быть выраже-
нием типа дата. Ключевое слово NEXT определяет с помо-
щью параметра дата_2 интервал между автоматическими
обновлениями снимка. Обратите внимание на то, что, если
ключевое слово REFRESH опущено, то автоматического об-
новления данных снимка не происходит. Также не происхо-

148
SQL — язык обработки данных Oracle

дит автоматического обновления данных снимка, если опу-


щены оба ключевых слова START WITH и NEXT.
Ключевое слово FOR UPDATE указывает на возможность
изменения данных снимка. Если сервер Oracle включает под-
держку репликации данных (Replication Option), то модифи-
кация данных снимка приводит к соответствующим измене-
ниям в мастер-таблице.
Ключевое слово AS запрос включает в создаваемый сни-
мок строки, являющиеся результатом выполнения запроса.
Параметр запрос используется для обозначения любого
синтаксически правильного запроса, не содержащего ключе-
вого слова ORDER BY или ключевого слова FOR UPDATE.
Рассмотрим пример создания снимка с таблицы, разме-
щенной на удаленном сервере. Пусть таблица Tab! размеще-
на на удаленном сервере и доступ к ней осуществляется через
связь с именем sun_ora_link. Приводимый пример показывает,
как создается снимок, и иллюстрирует тот факт, что измене-
ния в мастер-таблице не распространяются на данные снимка
автоматически.

SQL> CREATE SNAPSHOT snap_suntabl AS


2 SELECT .* FROM Tabl@sun_ora_link WHERE Atl>0;
Snapshot created.

SQL> SELECT * FROM snap_suntabl;


ATI

1
2
4
Г

SQL> CONNECT ul/ulpsw@sunora


Connected.

SQL> INSERT INTO Tabl VALUES(10);


1 row created. .

SQL> DELETE FROM Tabl WHERE Atl=l;


149
Раздел 2
1' row deleted.

SQL> CONNECT system/manager@sun_ora_link:


Connected.

SQL> SELECT * FROM snap_suntabl;

ATI
1
2 i
4

Листинг 61. Пример создания снимка таблицы уда-


ленной базы данных

Для модификации снимка с целью установки частоты ав-


томатического изменения в 1 час можно воспользоваться ко-
мандой ALTER SNAPSHOT. После того как введением клю-
чевого слова REFRESH снимок сделан обновляемым авто-
матически, изменения, введенные в мастер-таблицу в пре-
дыдущем примере, актуализируются в снимке автоматически.

SQL> ALTER SNAPSHOT snap_suntabl REFRESH COMPLETE


2 START WITH SYSDATE NEXT SYSDATE + 1/24;
Snapshot altered.

SQL> SELECT * FROM snap_suntabl;

ATI

2
4
10

Листинг 62. Пример автоматического изменения


снимка данных с заданным временным 'интерва-
лом

150
SQL — язык обработки данных Oracle

Последовательности.
Синонимы

Создание последовательностей
Последовательностью называется объект базы данных,
генерирующий неповторяющиеся целые числа. Полученные
из последовательности числа обычно используются в качест-
ве значений для первичных ключей.
Числа, создаваемые последовательностью, могут либо
возрастать постоянно, либо только до определенного предела,
либо, по достижении предела, начинать возрастание заново, с
начального значения. Последовательность может создавать
цепочки как увеличивающихся чисел, так и уменьшающихся.
Можно задавать также и приращение значений.
Псевдостолбец NEXTVAL используется для генериро-
вания очередного номера из указанной последовательности.
Ссылка на NEXTVAL приводит к генерированию очередного
номера. Обращение имеет следующий синтаксис:

имя_последовательности.NEXTVAL.

Псевдостолбец CURRVAL используется для ссылки на


текущее значение последовательного номера. В текущем се-
ансе NEXTVAL должен быть использован хотя бы один раз
до ссылки на CURRVAL. Обращение к CURRVAL имеет сле-
дующий синтаксис:
.t i '
имя_лоследовательности.CURRVAL.

На одно предложение SQL генерируется лишь один но-


вый номер; иными словами, если в данном предложении
псевдостолбец NEXTVAL применительно к одной и той же
последовательности встречается несколько раз, то лишь для
первого обращения будет возвращен новый номер послёдова-
151
Раздел 2

тельности, а все остальные обращения в этом же предложе-


нии возвратят тот же самый номер.
Для создания последовательности требуется привилегия
CREATE SEQUENCE. Для создания последовательности,
размещенной в схеме другого пользователя, необходима при-
вилегия CREATE ANY SEQUENCE.
Оператор определения последовательности Oracle ис-
пользует следующий синтаксис:

CREATE SEQUENCE
[имя_схемы. ] имя_последовательности
[INCREMENT BY приращение]
[START WITH начальное_значение]
[MAXVALUE наиболынее_значение \ NOMAXVALUE]
[.MINVALUE наименьшее^значение \ NOMINVALUE]
_[CYCLE | NOCYCLE]
[CACHE число_элементов \ NOCACHE]
[ORDER | NOORDER]

Параметр имя_ последовательности задает имя последо-


вательности. Параметр имя_схемы указывает на схему, в ко-
торой определяется последовательность. Если владелец по-
следовательности не указан явно, то подразумевается пользо-
ватель, выдавший команду CREATE SEQUENCE.
Ключевое слово INCREMENT BY определяет интервал
между последовательными номерами. Если параметр прира-
щение имеет отрицательное значение, то последовательность
убывающая, если положительное — последовательность воз-
растающая. Допустимо любое целое число, не равное нулю.
Значение по умолчанию 1 (возрастающая последовательность
значений).
Ключевое слово START WITH через параметр началь-
ное_значение задает первый генерируемый последовательный
номер. Если ключевое слово не указано, то по умолчанию для
возрастающих последовательностей начальный генерируе-
мый последовательный номер равен значению параметра"

152
SQL — язык обработки данных Oracle

MINVALUE, а для убывающих последовательностей —


MAXVALUE.
Ключевое слово MAXVALUE через параметр наиболъ-
шее_значение задает максимальное значение последователь-
ного номера, которое будет генерироваться. Параметр наи-
большее^значение определяет верхнюю границу последо-
вательности, которая может быть любым целым числом, с
количеством знаков, не превышающим 28 цифр и большим,
чем параметры начальное_значение и наименьшее_значение
(если они заданы). Отсутствие верхней границы указывается
ключевым словом NOMAXVALUE, которое определяет для
убывающих последовательностей значение -1, а для возраста-
27
ющих последовательностей —10 .
Ключевое слово MINVALUE через параметр наимень-
шее_значение задает минимальное значение последова-
тельного номера, которое будет генерироваться. Параметр на-
именьшее _значение определяет нижнюю границу последо-
вательности, которая может быть любым целым числом, с
количеством знаков, не превышающим 28 цифр, меньшим,
чем параметры наибольшее^значение и начальное_значение
(если значение параметров задано). Отсутствие нижней гра-
ницы указывается ключевым словом NOMINVALUE, которое
определяет для убывающих последовательностей значение
-1026, а для возрастающих последовательностей значение -I.
Ключевое слово NOCYCLE является значением, исполь-
зуемым по умолчанию, и предполагает завершение гене-
рирования последовательных номеров по достижении конца
последовательности. Любая попытка получить очередной
элемент последовательности после этого приведет к ошибке.
Если при определении последовательности указан параметр
CYCLE, то после достижения очередным членой последова-
тельности значения параметра наибольшее_значение (для воз-
растающих последовательностей) выдается значение пара-
метра наименьшее^значение. Если параметры наиболъ-
шее^значение и наименьшее_значение не указаны, то исполь-
зуются их значения по умолчанию. Для убывающих последо-
153
Раздел 2

вательностей параметры меняются местами по смыслу поня-


тия убывающей последовательности. Обратите внимание, что
ключевое слово START WITH влияет только на первый эле-
мент последовательности. При возврате на начало последо-
вательность будет начинаться с параметра MINVALUE в слу-
чае возрастающей последовательности и параметра
MAXVALUE — в случае убывающей.
Ключевое слово CACHE указывает на использование тех-
ники предварительной подготовки элементов последова-
тельности, что обеспечивает их быстрое получение при запро-
се. Число последовательных номеров, хранящихся в области
кэша оперативной памяти, определяется параметром чис-
ло_элементов ключевого слова CACHE. Кэширование по-
следовательности обеспечивают более быструю генерацию
элементов последовательности. Заполнение кэша для каждой
данной последовательности происходит после запроса перво-
го элемента этой последовательности. В случае краха сис-
темы все кэшируемые последовательные номера, не исполь-
зованные в зафиксированных транзакциях, теряются. По
умолчанию предполагается, что в памяти будут кэшироваться
20 последовательных элементов для каждой последо-
вательности. Значение параметра число_элементов ключе-
вого слова CACHE не должно превышать разницы парамет-
рами, задаваемыми ключевыми словами MAXVALUE и
MINVALUE.
Ключевое слово ORDER обеспечивает генерацию после-
довательных элементов точно в порядке поступления запро-
сов. В большинстве случаев независимо от того, указано ли
ключевое слово ORDER, элементы последовательности гене-х
рируются в порядке поступления запросов.
Одна последовательность может использоваться для ге-
нерации первичных ключей для нескольких таблиц. Если два
пользователя одновременно обращаются к одной после-
довательности, номера для каждого пользователя могут иметь
промежутки, так как из непрерывной последовательности по-
переменно получают номера оба пользователя. Каждый из
• 154
SQL — язык обработки данных Oracle
двух пользователей не будет видеть последовательные номе-
ра, сгенерированные для другого пользователя. При генера-
ции элемента последовательности счетчик элементов изменя-
ется независимо от того, успешно или неуспешно завершена
транзакция.
Рассмотрим пример создания последовательности с име-
нем Seql. Начальный элемент последовательности определен
равным 2, параметры наибольшее значение и нвименъ-
шее_значение определены равными 3 и 1 соответственно.

SQL> CREATE SEQUENCE Seql


2 MAXVALUE 3'MINVALUE 1 START WITH 2;
Sequence created.

SQL> SELECT Seql.NEXTVAL-FROM dual;

NEXTVAL

SQL> SELECT Seql.NEXTVAL FROM dual;

NEXTVAL

SQL> SELECT Seql.NEXTVAL FROM dual;


ERROR:
ORA-08004: sequence SEQl.NEXTVAL exceeds MAXVALUE
and cannot be instantiated
no rows selected

Листинг 63. Пример создания последовательности и


выборки ее элементов

Изменим предыдущий пример и создадим последова-


тельность с именем Seq2.
Начальный элемент последовательности, параметры наи-
большее^значение и наименьшее _значение определены, как в
155
Раздел 2

предыдущем примере, но дополнительно определим параметр


цикла, равный 2, и параметр кэширования, равный 2, (если
таким образом не определить параметр кэширования, то про-
изойдет ошибка, так как требуется, чтобы значение параметра
число^элементов ключевого слова CACHE не превышало
разности между параметрами, задаваемыми ключевыми сло-
вами MAXVALUE и MINVALUE).

SQL> CREATE SEQUENCE Seq2 MAXVALUE.3


2 MINVALUE 1 START WITH 2 CYCLE CACHE 2;
Sequence created.

SQL> SELECT Seq2.NEXTVAL FROM dual;

NEXTVAL

SQL> SELECT Seq2.NEXTVAL FROM dual;

NEXTVAL

SQL> SELECT Seq2.NEXTVAL FROM dual;

NEXTVAL

Листинг 64. Пример создания последовательности с


циклическим образованием элементов

Для удаления последовательностей используется команда


DROP SEQUENCE. Для выполнения данной операции необ-
ходимо быть владельцем последовательности либо иметь
привилегию DROP ANY SEQUENCE.

156
SQL — язык обработки данных Oracle

Оператор удаления последовательностей Oracle исполь-


зует следующий синтаксис:

DROP SEQUENCE [имя_схемы. ]имя_последовательности

Одной из ситуаций, когда необходимо уничтожение по-


следовательности, является повторный старт последователь-
ности. При этом необходимо учитывать, что объекты, кото-
рые зависят от этой последовательности, станут непригодны-
ми для использования. Поэтому для приведения последова-
тельности к требуемому состоянию (сдвига на требуемое чис-
ло элементов) рекомендуется использовать более изощрен-
ные способы. Например, с помощью анонимного PL/SQL
блока требуемое число раз вычислить следующее значение
для циклической последовательности.
Пример уничтожения последовательности Seql приведен
ниже.

SQL> DROP SEQUENCE Seql;


Sequence dropped.

Листинг 65. Пример уничтожения последовательности

Создание синонимов в Oracle

Синоним — это объект базы данных, используемый для


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

157
Раздел 2

Оператор определения синонима Oracle использует сле-


дующий синтаксис:
CREATE [PUBLIC] SYNONYM [имя_схемы.]имя_синонима
FOR [ имя__ йхемы2. ] имя_ объекта {@ имя_ связиБД]

Ключевое слово PUBLIC определяет, что синоним будет


доступен всем пользователям. По умолчанию синоним досту-
пен только создавшему его пользователю.
Параметр имя синонима — имя синонима, следующее со-
глашениям по именованию объектов Oracle. Параметр
имя_схемы задает имя существующей в базе данных схемы.
Для создания синонима в произвольной схеме нужны соответ-
ствующие привилегии. Если имя схемы для синонима опу-
щено, то предполагается, что синоним создается в схеме
пользователя, выдавшего команду.
Параметр имя_связиБД указывает на существующую
связь к удаленной базе данных. Если параметр имя_схемы
опущен, синоним ссылается к объекту, принадлежащему
пользователю, определенному связью с удаленной базой дан-
ных.
Параметр имя_схемы2 задает имя схемы, в которой нахо-
дится объект, для которого создается синоним. Наконец, па-
раметр имя_объекта указывает на этот объект.
Синоним должен иметь имя, отличное от остальных объ-
ектов данного пользователя. Рассмотрим соответствующий
пример»
Пусть в таблице RefCodes пользователя Administrator на-
ходится информация, необходимая для замены некоторых
кодов на действительные наименования некоторых объектов.
Для пользователя ul заводится одноименный синоним, упро-
щающий обращение к требуемой таблице (конечно, одно-
именность не является обязательным требованием). Наличие
необходимых привилегий у пользователя, создающего сино-
ним, предполагается. Обратите внимание на необходимость
явного разрешения пользователю ul выполнять операцию
158
SQL — язык обработки данных Oracle

выборки из таблицы RefCodes (даже несмотря на то, что она


скрыта за синонимом). Пусть таблица RefCodes создана и за-
полнена пользователем Administrator с использованием сле-
дующих предложений.
v

CREATE TABLE RefCodes(At1 NUMBER,


At2 V A R C H A R 2 ( 5 ) ) f
INSERT INTO ReFCodes V A L U E S ( 1 , ' T e x t l ' ) ;
INSERT INTO RefCodes V A L U E S ( 2 , ' T e x t 2 ' ) ;

Пользователь SYSTEM создает синоним для пользовате-


ля ul, ссылаясь на таблицу RefCodes из схемы пользователя
Administrator. При этом, несмотря на правильность синонима,
объект, на который ссылается синоним, пользователю ul не-
доступен.

SQL> CONNECT system/manager@sunora;


Connected.

SQL> CREATE SYNONYM ul.RefCodes


2 FOR Administrator.RefCodes;
Synonym created.
SQL> CONNECT ul/ulpsw@sunora;.
Connected.

SQL> SELECT * FROM RefCodes;


SELECT * FROM REFCODES
*

ERROR at -line 1:
ORA-00942: table or view does not exist

Листинг 66. Пример создания синонима

После предоставления прав на выполнение операции вы-


борки пользователь ul может оперировать с объектом, скры-
тым за синонимом.

159
Раздел 2

SQL> CONNECT administrator/adminpswgsunora;


Connected.
SQL> GRANT SELECT ON RefCodes TO ul;
Grant succeeded.
SQL> CONNECT ul/ulpsw@sunora;
Connected.

SQL> SELECT *. FROM-RefCodes;


ATI AT2

1 Textl
2 Text2

Листинг 67. Пример создания синонима и установле-


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

Для удаления из базы данных синонима используется ко-


манда DROP SYNONYM. Для удаления синонима необходи-
мо быть его владельцем или иметь привилегию DROP ANY
SYNONYM. Для удаления общего синонима также не-
обходимо быть его владельцем или иметь привилегию DROP
ANY PUBLIC SYNONYM. Оператор удаления синонима
Oracle использует следующий синтаксис:

DROP [PUBLIC] SYNONYM [имя_схемы.]имя_синонима

Необязательное ключевое слово PUBLIC определяет факт


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

SQL> DROP SYNONYM RefCodes;


Synonym dropped.

Листинг 68. Пример удаления синонима


160
SQL — язык обработки данных Oracle

Работа с табличными областями


в Oracle
Оператор определения табличной области Oracle исполь-
зует следующий синтаксис:

CREATE TABLESPACE имя_табличной_области


DATAFILE спецификация_файла_операционной_системы
[SIZE целое_число [ { К | М } ] ]
[AUTOEXTEND {OFF | ON [NEXT целое_число { К | М } ] ]
[MAXSIZE {UNLIMITED| целое_число { К | М } ] , . . . ]
[DEFAULT STORAGE раэмер_памяти ]
[{ONLINE | OFFLINE}] [{PERMANENT | TEMPORARY}]

Параметр имя_табличной_областпи определяет имя со-


здаваемой табличной области. Параметр специфика-
ция^файла_операционной_системы определяет имя файла
операционной системы, в котором будут размещаться данные
создаваемой табличной области.
Ключевое слово SIZE определяет первично распределяе-
мое пространство под табличную область, задаваемое в бай-
тах, килобайтах (указан параметр К) или в мегабайтах (указан
параметр М). Если файл с именем, определенным параметром
спецификация_фата_операционной_системы, не су-
ществует, то указывать ключевое слово SIZE с параметром,
характеризующим выделяемую память, обязательно.
Ключевое слово AUTOEXTEND указывает на разреше-
ние (ON) или запрещение (OFF) автоматического расширения
пространства, выделенного для табличной области. Ключевое
слово NEXT, задает приращение пространства, задаваемое в
байтах, килобайтах (указан параметр К) или в мегабайтах
(указан параметр М). Дополнительно можно определить с
помощью ключевого слова MAXSIZE максимальный размер
выделяемого под табличную область пространства, задавае-
мый в байтах, килобайтах (указан параметр К) или в мегабай-
тах (указан параметр М). Если указано ключевое слово
161
6. Заказ № 1628.
Раадел 2

UNLIMITED, то размер пространства, выделяемого под таб-


личную область, не имеет логических ограничений.
Задаваемое по умолчанию значение ключевого слова
ONLINE обеспечивает автоматический перевод в оператив-
ный режим созданной табличной области. Задаваемое по
умолчанию значение ключевого слова PERMANENT опреде-
ляет создание постоянной табличной области.
Рассмотрим пример создания дополнительной табличной
области app_data, данные которой размещаются в файле
/disk2/oracle/orahome/dbs/appdata.dbf (в файловом пространст--
ве операционной системы SUN Solaris). Под файл для таб-
личной области резервируется один мегабайт дискового про-
странства и допускается автоматическое приращение фраг-
ментами по одному мегабайту. Дополнительно представлен
пример создания табличной области index_data с другими ха-
рактеристиками.

SQL> CREATE TABLESPACE app_data


2 DATAFIbE'/disk2/oracle/orahome/dbs/appdata.dbf'
3 SIZE 1M AUTOEXTEND ON NEXT 1M
4 MAXSIZE UNLIMITED;
Tablespace created.

SQL> CREATE TABLESPACE index_data


2 DATAFILE'/disk2/oracle/orahome/dbs/inddata.dbf
3 SIZE 500K AUTOEXTEND ON NEXT 1M MAXSIZE 10M;
Tablespace created.

Листинг 69. Примеры создания табличных областей

Для изменения параметров табличных областей исполь-


зуется оператор ALTER TABLESPACE. С его помощью мож-
но выполнить для табличной области следующие изменения:
добавить файлы данных; переименовать файлы данных; из-
менить параметры хранения по умолчанию; перевести таб-
личную область в автономный или оперативный режим; на-

162
SQL — язык обработки данных Oracle

чать или завершить копирование; разрешить или запретить


запись в табличную область. В качестве примера запретим
запись в табличную область app_data. Эта операция использу-
ется, скажем, для защиты данных от изменений в нерабочее
время. Установленные режимы табличных областей можно
просмотреть в представлении словаря данных
DBA TABLESPACES.

SQL> ALTER TABLESPACE app_data READ ONLY;


Tablespace altered.

Листинг 70. Пример защиты табличной области от


записи •

Удаление табличной области с возможным удалением


всех объектов базы данных, расположенных в данной таблич-
ной области, осуществляется предложением DROP
TABLESPACE. Для выполнения данной операции необходи-
мо обладать привилегией DROP TABLESPACE. Табличная
область SYSTEM не может быть удалена.
Оператор удаления табличной области Oracle использует
следующий синтаксис:

DROP TABLESPACE имя_табличной_области


[INCLUDING CONTENTS]

Конструкция INCLUDING CONTENTS определяет, что


табличная область должна быть удалена, даже если она со-
держит данные. Если данный параметр опущен и табличная
область не содержит данных, она удаляется. Если же при
опущенном ключевом слове INCLUDING CONTENTS таб-
личная область содержит данные, то возвращается сообщение
об ошибке и табличная область не удаляется.
Перед удалением табличную область рекомендуется пе-
ревести в автономный режим (OFFLINE). Рекомендация свя-

163
Раздел 2

зана с тем, что до тех пор, пока пользователи работают с объ-


ектами табличной области, она не может быть удалена.
Ниже приведен пример удаления табличной области
app_data вместе со всеми содержащимися в ней объектами.

SQL> DROP TABLESPACE app_data INCLUDING CONTENTS;


Tablespace dropped.

Листинг TL. Пример удаления табличной области

164
Раздел 3

PL/SQL — процедурное
расширение языка SQL

PL/SQL — это процедурное расширение Oracle стандарт-


ного языка SQL. Многие фирмы-производители программных
продуктов стремятся расширить и усовершенствовать воз-
можности стандартного языка SQL, поэтому почти каждый
сервер реляционной базы данных поддерживает какое-либо
расширение стандартных возможностей ANSI/ISO SQL. Рас-
ширения SQL обеспечивают пользователю расширение спек-
тра решаемых задач, повышение эффективности или упроще-
ние типовых действий с базой данных. Моделью PL/SQL
служил язык программирования Ада, поэтому PL/SQL обла-
дает набором средств, характерных для любого современного
языка программирования высокого уровня.
Программы, созданные на языке PL/SQL, могут работать
совместно в различных частях прикладной системы, постро-
енной с использованием технологий Oracle. Например, в при-
ложении, разработанном на Oracle Developer 2000, триггер
формы (на стороне клиента) может вызывать для выполнения
некоторого действия хранимую процедуру (на стороне серве-
ра).
Знакомство с PL/SQL необходимо каждому разработчику
приложений для Oracle. С помощью PL/SQL можно улучшить

165
Раздел 3

производительность разрабатываемого приложения и систе-


мы в целом. Вместо интерпретируемых операторов SQL
Oracle позволяет использовать предварительно скомпилиро-
ванные и, следовательно, быстро выполняющиеся програм-
мы. Используя PL/SQL, также можно значительно уменьшить
объем обработки в клиентской части приложения и нагрузку
на сеть. Например, может понадобиться выполнить различ-
ные наборы операторов SQL в зависимости от результата не-
которого запроса. Запрос, последующие операторы SQL и
операторы условного управления могут быть включены в
один блок PL/SQL и пересланы серверу за одно обращение к
сети. С различными версиями сервера Oracle поставляются
различные версии языка PL/SQL, в которых поддерживаются
или не поддерживаются те или иные механизмы. В OracleS
появились новые возможности, в частности поддержка объ-
ектных расширений в программах на PL/SQL.
В этом разделе будут рассмотрены следующие вопросы:
структура программы PL/SQL, переменные, константы и ти-
пы данных PL/SQL, операторы управления выполнением про-
граммы и обработки исключительных ситуаций, различные
виды программ PL/SQL: хранимые процедуры, функции, па-
кеты и триггеры.

Структура программы на PL/SQL


Программа на PL/SQL обычно состоит из трех блоков:
блока описаний, исполнительного блока и блока обработки
исключительных ситуаций. Исполнительный блок может
быть структурирован с использованием операторных скобок
BEGIN и END.
Синтаксически программа на PL/SQL оформляется сле-
дующим образом:
DECLARE
операторы ...
BEGIN
операторы . . .
166
PL/SQL — процедурное расширение языка SQL
EXCEPTION
опера торы ... ..
END;

Программа такого вида называется анонимным блоком. В


блоке DECLARE описываются переменные, константы и оп-
ределяемые пользователем типы данных. Первый оператор
BEGIN отмечает начало тела основной программы. В тело
программы могут быть вложены другие блоки, ограниченные
операторными скобками BEGIN и END. В блоке EXCEPTION
определяются фрагменты программного кода для обработки
исключительных ситуаций в программе. Последний оператор
END указывает конец тела программы. В анонимном блоке
могут отсутствовать блоки DECLARE и EXCEPTION, но обя-
зательно должен присутствовать блок операторов, ограни-
ченный операторными скобками BEGIN и END. В вырожден-
ном случае там может присутствовать только оператор NULL.
В любые части программы на PL/SQL можно включать
комментарии. Текст, который начинается с символов "--" и
продолжается до конца текущей строки, рассматривается как
комментарий. Многострочные комментарии включаются ме-,
жду символами "/*" и "*/". Использование комментариев яв-
ляется хорошей практикой составления программ. Также хо-
рошей практикой программирования является придание тек-
сту программ удобочитаемости с помощью выделения син-
таксических конструкций языка двумя-тремя отступами или
использование для форматирования кода специальных
средств, например PL/Formatter производства^uest Software.
Перед блоком DECLARE могут присутствовать команды
установки переменных окружения для различных инструмен-
тальных средств.

Переменные, константы и типы


В ограниченном операторами DECLARE и BEGIN блоке
программы PL/SQL описываются переменные, типы и кон-
167
Раздел 3

станты. Любая переменная или константа должна иметь один


из допустимых в PL/SQL типов. Константа идентифицируется
ключевым словом CONSTANT и отличается от переменной
тем, что попытка изменить ее значение приводит к сообще-
нию об ошибке. Присваивание значений переменным осуще-
ствляется оператором ": =". Типы данных в PL/SQL практиче-
ски совпадают с описанными выше типами данных SQL за
исключением некоторых несущественных различий (данные
могут иметь отличающуюся максимальную длину, различия в
реализации, имеется специфические для PL/SQL типы данных
PLSJNTEGER, BINARYJNTEGER и т. д.). Наряду со ска-
лярными типами данных в PL/SQL присутствуют составные:
тип RECORD, массивы и PL/SQL-таблицы.
Составной тип данных RECORD предназначен для хра-
нения и обработки записей. Каждая запись имеет атрибуты,
которые могут быть проинициализированы при ^объявлении.
Обращение к атрибутам записи производится с использова-
нием полной нотации, включающей имя переменной и имя
атрибута, отделенное точкой. В переменные типа RECORD
удобно выполнять выборку данных с помощью курсоров.
PL/SQL-таблицы и способы работы с ними будут рассмотре-
ны далее.
Рассмотрим пример простейшей программы, в которой
определяются переменные и выполняются действия по вы-
числению натурального логарифма чисел 2 и 3. Команды ус-
тановки переменных окружения SET SERVEROUTPUT и SET
ECHO определяют режим вывода на терминал пользователя.
Процедура DBMS_OUTPUT.PUT_LINE обеспечивает вывод
данных на терминал пользователя и позже будет рассмотрена
подробно, функция LN вычисляет натуральный логарифм.
Символ "/" указывает на завершение текста анонимного блока
и является командой к интерпретации и выполнению.

SQL> set serveroutput- on;


SQL> set echo on;
168
PL/SQL — процедурное расширение языка SQL
SQL> DECLARE
2 Headerl CONSTANT VARCHAR2(20) :=* 'Логарифм
двух равен ';
3 Header2 CONSTANT VARCHAR2(20) := 'Логарифм
трех равен ';
4 Arg NUMBER := 2; — здесь задается начальное
значение аргумента
5 — Исполнительный блок
6 BEGIN
7 DBMS_OUTPUT.PUT_LINE(Header1||LN(Arg));
. 8 Arg :== Arg+1;
9 DBMS_OUTPUT,PUT_LINE(Header2||LN(Arg));
10 END;
/ - •
Логарифм двух-равен
.6931471805599453094172321214581765680814
Логарифм трех равен
1.'09861228866810969139524523692252570466

PL/SQL procedure successfully completed.

Листинг 72. Пример программы на PL/SQL, вычисляю-


щей логарифмы чисел

Управление выполнением
программы
Операторы большинства языков программирования, в
том числе и PL/SQL, выполняются последовательно. Такая
схема называется потоком команд. В любом развитом языке
присутствует более или менее богатый набор операторов
управления потоком команд. Соответствующие операторы
позволяют выполнять условные переходы, циклически вы-
полнять группу операторов и осуществлять выход из цикла
при выполнении определенных условий. В PL/SQL преду-
смотрено несколько операторов, с помощью которых можно
управлять выполнением потока команд программы. Рассмот-
рим соответствующие программные конструкции.

169
Раздел 3

Оператор ветвления
Оператор IF...THEN...ELSE позволяет проверить условие
и, в зависимости от результатов проверки (TRUE или
FALSE), выполнить различные группы операторов. Альтер-
нативная последовательность операторов определяется клю-
чевым словом ELSE. Границы действия оператора IF опреде-
ляются закрывающей операторной скобкой END IF. Для
расширения структуры ветвления дополнительно
предусмотрены операторные скобки ELSIF, задающие
структуры ветвления более глубокого уровня.
Oracle использует следующий синтаксис конструкции
ветвления в PL/SQL:
* - •

IF условие_1 THEN
операторы_1; -- ветвь!
ELSIF условие_2 THEN
операторы_2; — ветвь2
ELSIF

ELSE операторы_п; -- операторы альтернативы


END IF;

Рассмотрим пример, иллюстрирующий механизм ветвле-


ния в программах на PL/SQL. Программа выводит сообщение
о классе излучения в зависимости от значения вводимого па-
раметра длины волны (длина волны предполагается заданной
в микронах). Для ввода данных используется стандартное со-
глашение SQL*Plus: переменная, имя которой предваряется
знаком "&", вводится с терминала пользователя.

SQL> DECLARE
2 'Lamda NUMBER; — Длина волны
3 Textl VARCHAR2(30):='Инфракрасное излучение';
4 Text2 VARCHAR2 (30.) := 'Видимый свет ' ;
5 Text3 VARCHAR2(30) := 'Ультрафиолет-';
6 — Исполнительный блок
7 BEGIN
170
PL/SQL — процедурное расширение языка SQL
8 Lamda := &Input_Data;
9 DBMS_OUTPUT.PUT_LINE('');
10 IF (Lamda > 0 . 6 5 )
11 THEN DBMS_OUTPUT.PUT_LINE(Textl);
12 ELSIF (Lamda < 0.41)
13 THEN DBMS_OUTPUT.PUT_LINE(TextS);
14 ELSE
15 DBMS_OUTPUT.PUT_LINE(Text2) ;
16 END IF;
17 END;
/
Enter value for input_data:. 0.33
old 8: Lamda := &Input_Data;
new 8: Lamda := 0.33;
Ультрафиолет

PL/SQL procedure successfully completed.

Листинг 73. Пример программы на PL/SQL, исполь-


зующей ветвление

Операторы цикла
Организация цикла оформляется в программе на PL/SQL
несколькими способами. Самый простой — использование
оператора LOOP. Выйти из цикла можно несколькими спосо-
бами. Конструкция EXIT WHEN обеспечивает выход из цик
ла при выполнении условия в соответствующем операторе.
Рассмотрим пример определения числа, факториал которого
является наименьшим числом, большим заданной константы
(например, 1 000 000 000).

SQL> DECLARE
2 Arg NUMBER;— Перем. для выч. факториала
3 I NUMBER; — Переменная-счетчик
4 Limit NUMBER := 1000000000; — Граница
5 Textl VARCHAR2 (80)- := 'Факториал числа,
впервые превышающий 1 000 000 000 ' ;
6 — Исполнительный блок
171
Раздел 3
1 BEGIN
8 I := 0;
9 Arg := 1;
10 LOOP
11 EXIT WHEN ARG > Limit;
12 Arg := A r g * ( I + D ;
13 I := I + 1;
14 END LOOP;
15 DBMS_OUTPUT.PUT_LINE(Textl) ;
16 DBMS_OUTPUT.PUT_LINE(TO_CHAR(Arg) ) ;
17 DBMS_OUTPUT.PUT_LINE(' Искомое число
1
| I TO_CHAR ( I } ) ;
18 END;

Факториал числа, впервые превышающий 1000 000 000


6227020800
Искомое число = 13
PL/SQL procedure successfully completed.

Листинг 74. Пример процедуры на PL/SQL, исполь-


зующей цикл, управляемый оператором EXIT
WHEN

Еще одним распространенным вариантом организации


цикла является цикл, управляемый ключевым словом WHILE.
Управление данного типа обеспечивает выполнение цикла до
тех пор, пока условие, определенное ключевым словом
WHILE, является истинным (TRUE). Модифицируем преды-
дущий пример, изменив константу и задав условие выхода из
цикла ключевым словом WHILE.

SQL> DECLARE
2 -Arg NUMBER; — Перем. для выч. факториала
3 I NUMBER; — Переменная-счетчик
4 Limit NUMBER := 1000000000000; — Граница
5 Textl VARCHAR2(80) := 'Факториал числа,
впервые превышающий 1 000 000 000 000 ';
6 — Исполнительный блок
7 BEGIN
172
PL/SQL — процедурное расширение языка SQL
8 I := 0;
9 Arg := I;
10 WHILE Arg < 1000000000000 LOOP
11 Arg := Arg*(1+1);
12 I := I + I;
13 END LOOP;
14 DBMS JDUTPU.T.PUT_LINE( Text 1);
15 DBMS_OUTPUT.PUT_LINE(TO_CHAR(Arg));.
16 DBMS_OUTPUT.PUT_LINE('Искомое число =
1
| |TO_CHAR(I)};.
17 END;

Факториал числа, впервые превышающий


1 000 000 000 000
1307674368000
Искомое число = 15

PL/SQL procedure successfully completed.

Листинг 75. Пример программы на PL/SQL с циклом,


управляемым оператором WHILE

Цикл, управляемый оператором FOR, используется в том


случае, когда точно известно, сколько раз нужно выполнять
итерацию цикла. Рассмотрим пример расчета факториала за-
данного числа. Обратите внимание, что переменную цикла (в
данном случае I) описывать в блоке DECLARE не нужно.

SQL> DECLARE
2 Arg NUMBER:= 1;— Перем. для выч. факториала
3 Limit NUMBER := 20;.— Граница
4 Textl VARCHAR2(30) := 'Факториал числа 20=';
5 — Исполнительный блок
6 BEGIN
7 FOR I IN 1..Limit LOOP
8 Arg := Arg*I;
9 END LOOP;
10 DBMS_OUTPUT.PUT_LINE(Textl||TO_CHAR(Arg));
11 END;
173
Раздел 3
/

Факториал числа 20 = 2432902008176640000

PL/SQL procedure successfully completed.

Листинг 76. Пример процедуры на PL/SQL, с циклом,


управляемым оператором FOR ,

Оператор GOTO

Оператор перехода GOTO позволяет осуществить пере-


ход по метке, присутствующей в теле программы. С помощью
уникального идентификатора, заключенного в двойные угло-
вые скобки, можно пометить любую часть программы
PL/SQL для организации безусловного перехода по метке.
Апеллируя к классической аргументации Э. Дейкстры, можно
утверждать, что использование данного оператора в програм-
мах не является хорошим стилем для языков, обладающих
развитыми средствами обработки событий и управления по-
током команд.

Курсоры
Ключевым понятием языка PL/SQL является курсор. Кур-
сор — это поименованный запрос, содержащий некоторое
фиксированное число строк в выборке. По существу курсор
является окном, через которое пользователь получает доступ
к информации базы данных. Курсоры, в частности, могут ис-
пользоваться для присваивания конкретных значений пере-
менным программы. PL/SQL неявно объявляет курсор для
всех SQL-предложений манипулирования данными, включая
запросы, возвращающие ровно одну строку. Допустимое ко-
личество курсоров на сессию устанавливается параметром
инициализации OPEN_CURSOR в файле параметров.

174
PL/SQL — процедурное расширение' языка SQL

Пусть в базе данных существует таблица ТаЫ, созданная


и заполненная предложениями:

CREATE TABLE ТаЫ (Atl NUMBER, At2 V A R C H A R 2 ( 1 ) } ;


INSERT INTO ТаЫ VALUES (1, ' A 1 ) ;
INSERT INTO Tabl VALUES (2, r B ' ) ;
INSERT INTO Tabl VALUES (3, ' С ' ) ;

Существует три основных типа курсоров: неявный, явный


и курсорный цикл FOR.
Неявный курсор создается автоматически при выполне-
нии оператора вида SELECT ... INTO. В процессе выполне-
ния курсор открывается, после чего из него выбираются дан-
ные, и закрывается. Все эти действия производятся сервером
за один шаг. Если неявный курсор возвращает более чем одну
строку, возбуждается предопределенная исключительная си-
туация TOO_MANY_ROWS и выдается сообщение об ошиб-
ке. Если неявный курсор вообще не возвращает строк, возбу-'
ждается другая предопределенная исключительная ситуация
NO_DATA_FOUND и также выдается сообщение об ошибке.
Пример выборки данных с использованием неявного курсора
приведен в листинге 77.

SQL> DECLARE
2 Argl NUMBER;
3 Arg2 VARCHAR2(1) ;
4 BEGIN
5 SELECT Atl,At2 INTO Argl,Arg2
6 FROM Tabl WHERE Atl=l;
7 DBMS_OUTPUT.PUT_LINE{TO_CHAR(Argl) I Г' I IArg2);
8 END;
9 /
1 A

SQL> DECLARE
2 Argl NUMBER;
3 Arg2 VARCHAR2(1);
4 BEGIN
175
Раздел 3
5 SELECT At1,At2 INTO Argl,Arg2 FROM Tabl
6 WHERE At 1=4;
7 DBMS_OUTPUT.PUT_LINE(TO_CHAR(Argl) I I '' I IArg2>;
8 END;
9 /
DECLARE
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 5

SQL> DECLARE
2 Argl NUMBER;
3 Arg2 VARCHAR2(1) ;
4 BEGIN
5 SELECT Atl,At2 INTO Argl,Arg2 FROM Tabl
6 WHERE Atl IN ( 1 , 2 ) ;
7 DBMS_6UTPUT\PUT_LINE(TO_CHAR(Argl) | | " | |Arg2) ;
8 END;
9 /
DECLARE
*
ERROR at line 1:
ORA-01422: exact fetch returns more than re-
quested number of rows
ORA-06512: at line 5

Листинг1 77. Пример программы на PL/SQL, осуществ-


ляющей выборку данных с использованием не-
явного'курсбра

Курсорный цикл FOR — это синтаксическая конструк-


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

SQL> DECLARE
176
PL/SQL — процедурное расширение языка SQL
2 CURSOR Curl IS SELECT Atl,At2 FROM Tabl;
3 vl V A R C H A R 2 ( 4 0 0 0 ) ;
4 BEGIN
5 FOR rec IN Curl LOOP
6 vl:=LTRIM(vl||' 4lrec.At2);
7 END LOOP;
8 DBMS_OUTPUT.PUT_LINE(vl) ;
9 END;
10 /
A B C

PL/SQL procedure successfully completed.

Листинг- 78. Пример программы на PL/SQL, осуществ-


ляющей выборку данных с использованием кур-
сорного цикла FOR

Простейший вариант курсорного цикла FOR представля-


ет собой запрос, встроенный в описайие цикла:

SQL> DECLARE
2 vl V A R C H A R 2 ( 4 0 0 0 ) ;
3 BEGIN
4 FOR rec IN (SELECT Atl,At2 FROM Tabl) LOOP
5 vl:=LTRIM(vl||' '||rec.At2);
6 END LOOP;
7 DBMS_OUTPUT.PUTJLJNE(vl);
8 END;
' 9 /
A B C

PL/SQL procedure successfully completed.

Листинг1 79. Пример программы на PL/SQL, осуществ-


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

Рассмотрим пример выборки данных с использованием


явных курсоров. Объявим курсор Curl, ориентированный на
получение данных из таблицы Tabl:
177
Раздел 3

CURSOR Curl IS SELECT * FROM Tabl

Первым шагом, необходимым для работы с курсором, яв-


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

OPEN Curl;

Выборка данных из курсора может быть выполнена в на-


бор переменных подходящих типов, командой FETCH, на-
пример, таким образом:

FETCH Curl INTO Argl,Arg2;

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


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

SQL> DECLARE -
2 Cursor Curl IS SELECT * FROM Tabl;
3 Rec Curl%ROWTYPE;
4 BEGIN
5 OPEN Curl; — Курсор должен быть открыт
6 FOR I IN 1..3 LOOP
7 FETCH Curl INTO rec;
8 DBMS_OUTPUT.PUT_LINE(TO_CHAR(rec.Atl)I
1
||rec.At2); ' .
9 END LOOP;
10 END;
11 /
1 A
2 В

178
PL/SQL — процедурное расширение языка SQL

3 С
PL/SQL procedure successfully completed.

Листинг 80. Пример программы на PL/SQL, осуществ-


ляющей выборку данных с использованием яв-
ного курсора

Программа, представленная в листинге 80, неудачна тем,


что цикл настроен на получение конкретного числа строк,
которых может и не быть в таблице. В PL/SQL для курсоров
предусмотрены специальные методы %NOTFOUND и
%FOUND, принимающих противоположные булевские зна-
V
чения. Метод %NOTFOUND возвращает значения TRUE, ес-
ли выборка в курсор пустая, то есть не содержит строки. Об-
ратите внимание, что после открытия курсора, но до первой
команды FETCH, методы %FOUND и %NOTFOUND прини-
мают неопределенное значение (UNKNOWN). Незнание этого
факта может привести к достаточно распространенной ошиб-
ке. При организации цикла с использованием оператора
WHILE и выполнением проверки на истинность %FOUND на
входе цикл не будет выполнен ни разу, несмотря на наличие
данных, удовлетворяющих запросу.
Метод %ROWCOUNT возвращает число строк, выбран-
ных после открытия курсора.
При объявлении переменных также можно использовать
специальные атрибуты %TYPE и %ROWTYPE. Атрибут
%TYPE предназначен для определения типа данных пере-
менной, константы или столбца. Этот атрибут обычно приме-
няется при объявлении переменной с типом данных, завися-
щим от определения столбца в таблице базы данных. Атрибут
%ROWTYPE обычно применяется, когда объявляется пере-
менная-запись, которая должна иметь такую же структуру,
что и строка в таблице или представлении, или запись, извле-
каемая из курсора. Использование атрибутов %TYPE и
%ROWTYPE предохраняет от возможных ошибок при изме-

179

- '
Раздел 3

нении типов данных столбцов таблиц или структуры самих


таблиц.
С учетом дополнительных объектов и методов PL/SQL
рассмотрим новый вариант программы выборки строк табли-
цы Tab! с использованием курсоров. Обратите внимание на
повторный вывод последней строки. Попытайтесь исправить
организацию цикла для устранения повторного вывода.

SQL> DECLARE
2 TYPE tabl_rec_type IS RECORD — Определение
нового типа данных
3 (Argl Tabl-.Atl%TYPE, — Переменная типа ат-
рибута Atl таблицы Tab!
4 Arg2 Tabl.At2%TYPE) ; — Переменная типа ат-
рибута At2 таблицы Tabl
5 Tabl_rec tabl_rec__type; -- Определение объ- •
екта сконструированного типа
6 Cursor Curl IS SELECT * FROM Tabl; -- Опре-
деление курсора
7 BEGIN
8 OPEN Curl; — Курсор должен быть открыт
9 LOOP
10 EXIT WHEN (Cur1%NOTFOUND);
11 FETCH Curl INTO Tabl_rec;
12 DBMS_OUTPUT.PUT_LINE(Curl%ROWCOUNT||'
'||Tabl_rec.Arg2);
13 END LOOP;
14 END;
/
1 A
2 В
3 С
3 С ,
• s

PL/SQL procedure successfully completed.

Листинг 81. Пример модифицированной программы,


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

180
PL/SQL — процедурное расширение языка SQL

Объявление курсора может содержать параметрический


запрос. Значения параметров задаются при открытии курсора.
Имя параметра должно отличаться от имени столбца в запро-
се курсора. В противном случае будет возвращена каждая
строка! (х = х всегда TRUE). Рассмотрим пример выборки
данных с параметрическим запросом. В листинге 82 приведен
пример с использованием параметрического курсора и изме-
ненной организацией цикла, исключающей повторный вывод
последней строки.

SQL> DECLARE
2 TYPE tabl_rec_type IS .RECORD — Определение
нового типа данных
3 (Argl Tabl.Atl%TYPE, • — Переменная типа ат-
рибута Atl таблицы Tab!
4 Arg2 Tabl.At2%TYPE) ; — Переменная типа ат-
рибута At 2 таблицы Tab!
5 Tabl_rec tabl_rec_type; — Определение объ-
екта сконструированного типа
6 Cursor Cur2 (I NUMBER) IS SELECT * FROM Tabl
WHERE MOD (Atl, I) = 1;
7 BEGIN
8 OPEN Cur2(2); — Курсор открыт с параметром
2
9 FETCH Cur 2 INTO Tabl_rec;
10 WHILE Cur 2% FOUND LOOP
11 DBMS_OUTPUT.PUT_LINE (Cur2%ROWCOUNT| | '
1
| |Tabl_rec.Argl) ;
12 FETCH Cur2 INTO Tabl_rec;
13 END LOOP;
14 END;

1 1
2 3
PL/SQL procedure successfully completed.

Листинг1 82. Пример программы на PL/SQL, осуществ-


ляющей выборку данных с использованием па-
раметрического курсора
181
Раздел 3

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


конструкция REF — ссылка на курсор. Сначала объявляется
ссылка на курсор, а описание курсора производится потом.
Как правило, ссылки на курсор применяются, когда запрос
для курсора формируется динамически. Пример работы REF-
ссылки приведен в листинге 83.

SQL> DECLARE
2 TYPE cursor_type IS REF CURSOR;
3 Curl cursor_type;
4 l_query VARCHAR2(100);
5 . rec Tabl%ROWTYPE;
6 BEGIN
7 l_query:='SELECT * FROM Tabl';
8 l_query:= l_query||' WHERE Atl=l';
9 OPEN Curl FOR l_query;
10 FETCH Curl INTO rec;
11
DBMS_OUTPUT.PUT_LINE(rec.Atl| Г'|Irec.At1);
12 " CLOSE Curl;
13 END;
14 /
11

PL/SQL procedure successfully completed.

Листинг 83. Пример программы на PL/SQL, осуществ-


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

Обработка исключительных
ситуаций
Большинство развитых языков программирования обла-
дают встроенными механизмами обработки исключительных
ситуаций. Соответствующие языковые средства предусмот-
рены и в PL/SQL. При возникновении предопределенной или
объявленной пользователем ситуации происходит автомати-
182
PL/SQL — процедурное расширение языка SQL

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


EXCEPTION программы на PL/SQL, где и происходит преду-
смотренная обработка возникшей исключительной ситуации.
Некоторые предопределенные исключительные ситуации
PL/SQL представлены в таблице 3. Полный перечень исклю-
чительных ситуаций может быть найден в руководстве по
языку PL/SQL.

Таблица 3. Не/которые предопределенные исключи-


тельные ситуации' PL/SQL

Символическое имя Описание


предопределенной предопределенной
исключительной исключительной ситуации
ситуации i
LOGIN_DENIED Неуспешное подключение к сер-
веру (например, введен ошибоч-
ный пароль)
NOT_LOGGED_ON Попытка выполнить действие без
подключения к серверу Oracle
INVALID_CURSOR Ссылка на недопустимый курсор
или недопустимая операция с
курсором .
NO_DATA_FOUND , Не найдены данные, соответству-
ющие оператору SELECT INTO
DUP_VAL_ON_INDEX Попытка вставить в столбец с
ограничением на уникальность
значения значение-дубликат
TOO_MANY_ROWS Оператор SELECT INTO возвра-
щает более одной строки
VALUE_ERROR Арифметическая ошибка, ошиб-
ка преобразования или усечения

Рассмотрим пример программы с обработкой исключи-


тельных ситуаций. В тексте программы пропущен оператор
открытия курсора. Поэтому при обращении к методу
183
Раздел 3
%FOUND неоткрытого курсора возникнет исключительная
ситуация INVALID_CURSOR.

SQL> DECLARE
2 Argl Tabl.AtUTYPE;
3 Arg2 Tabl.At2%TYPE;
4 CURSOR Curl IS SELECT * FROM Tabl;
5 BEGIN
6 WHILE Curl%FOUND LOOP
7 FETCH Curl INTO Argl,Arg2;
8 END LOOP;
9 EXCEPTION
10 WHEN INVALID_CURSOR THEN
11 DBMS_OUTPUT.PUT_LINE('He открыт курсор');
12 END;
/ . :
He открыт курсор

PL/SQL procedure successfully completed.

Листинг 84. Пример обработки исключительной си-


туации в программе на PL/SQL

Для обработки исключительных ситуаций также можно


использовать специальный обработчик PL/SQL OTHERS или
описать пользовательскую исключительную ситуацию и за-
программировать ее обработку. Ключевое слово OTHERS
блока EXCEPTION определяет механизм универсальной об-
работки исключительных ситуаций, не вошедших в список
ситуаций, обрабатываемых явно. Использование специально-
го обработчика исключительных ситуаций OTHERS является
хорошим стилем программирования, при котором в програм-
ме не возникает необработанных исключительных ситуаций.
Дополним пример, представленный в листинге 84. Вве-
дем в текст программы запрещенную операцию деления на
ноль, и обработаем данную исключительную ситуацию в спи-
ске OTHERS. (На самом деле в Oracle предопределена ис-
ключительная ситуация ZERO_DIVIDE, но в данном примере
184
PL/SQL — процедурное расширение языка SQL

это не важно, а важно то, что ее нет в списке блока


EXCEPTION.)

SQL> DECLARE
2 Argl Tabl.Atl%TYPE;
3 Arg2 Tabl.At2%TYPE;
4 CURSOR Curl IS SELECT * FROM Tabl;
5 Arg3 NUMBER := 1;
6 BEGIN
7 Arg3 := Arg3/0;
8 WHILE Curl%FOUND LOOP
9 FETCH Curl INTO Argl>Arg2;
10 END LOOP;
11 EXCEPTION
12 WHEN INVALID_CURSOR THEN
13 DBMSJDUTPUT.PUT_LINE('He открыт курсор');
14 WHEN OTHERS THEN
15 DBMS_OUTPUT.PUT_LINE('Ошибка приложения');
16 END;
/
Ошибка приложения.

PL/SQL procedure successfully completed.

Листинг 85. Пример обработки всех необъявленных


исключительных ситуаций в списке OTHERS

Рассмотрим технику определения и обработки пользова-


тельских исключительных ситуаций. Исключительная ситуа-
ция, определяемая пользователем, должна быть объявлена в
блоке DECLARE программы. В PL/SQL используется сле-
дующий синтаксис объявления исключительной ситуации:

имя_исключительной_ситуации EXCEPTION;

Например, предопределенные исключения PL/SQL объ-


явлены как глобальные в пакете STANDARD в схеме
пользователя SYS.

185
Раздел 3

В программе условие возникновения исключительной си-


туации определяется стандартными средствами PL/SQL, чаще
всего операторами IF.„THEN. После обнаружения условий
возникновения исключительной ситуации она генерируется
оператором RAISE. В PL/SQL используется следующий син-
таксис генерации исключительной ситуации:

RAISE имя_исключительной__ситуации;

Оператор RAISE генерирует определенную пользовате-


лем исключительную ситуацию и передает управление в блок
EXCEPTION.
Рассмотрим пример обработки пользовательской исклю-
чительной ситуации. Достаточно часто в роли пользователь-
ских исключительных ситуаций выступает выход некоторого
хранимого в базе данных значения атрибута за заданные гра-
ницы. В качестве примера в роли исключительной ситуации
рассмотрим превышение значением Argl порога, равного 2.

SQL> DECLARE
2 Argl Tabl.Atl%TYPE;
3 Arg2 Тabl.At2%TYPE;
4 Special_case EXCEPTION;
5 Cursor Curl IS SELECT * FROM Tabl;
6 BEGIN
1 OPEN Curl;
8 FETCH Curl INTO Argl,Arg2;
9 WHILE Curl%FOUND LOOP
10 FETCH Curl INTO Argl,Arg2;
11 IF Argl > 2
12 THEN RAISE Special_case;
13 END IF;
14 END LOOP;
15 EXCEPTION
16 WHEN Special_case THEN
17 DBMS_OUTPUT.PUT_LINE('Пользовательская ис-
ключительная ситуация1);
18 WHEN OTHERS THEN
186
PL/SQL — процедурное расширение яаыка SQL
19 DBMSJDUTPUT.PUT_LINE('Ошибка приложения');
20 END;

Пользовательская исключительная ситуация

PL/SQL procedure successfully completed.

Листинг 86. Пример определения и обработки поль-


зовательской исключительной ситуации в про-
v грамме на PL/SQL

Для обработки исключительных ситуаций, которые от-


сутствуют в таблице 3, следует использовать выражение
PRAGMA EXCEPTIONJNIT (имя_исключения, но-
мер_ошибки\ С помощью исключений, объявленных таким
образом* можно обработать практически любую ошибку сер-
вера, возникающую при работе программы PL/SQL. Для объ-
явления соответствующего исключения достаточно знать но-
мер ошибки. В следующем примере продемонстрируем обра-
ботку ошибки преобразования символьного значения в дату
по заданной маске:

— сначала узнаем номер ошибки


SQL> DECLARE
2 vl DATE;
3 BEGIN
4 vl:=TO_DATE('ABC', 'DDMMYYYY');
5 END;
6 /
DECLARE
*
ERROR at line 1:
ORA-01858: a non-numeric character was found
where a numeric was expected
ORA-06512: at line 4

' SQL> DECLARE


2 vl DATE;
3 to_date_convert_error EXCEPTION;
187

'•
Раздел 3
4 PRAGMA EXCEPTION_INIT
(to_date_convert_error, -01858);
5 BEGIN
6 vl:=TO_DATE('ABC','ddmmyyyy');
7 EXCEPTION
8 WHEN to_date_convert_error THEN
9 DBMS_OUTPUT.PUT_LINE('Произошла ошибка
преобразования даты'};
10 END;
11 /
Произошла ошибка преобразования даты

PL/SQL procedure successfully completed.

Листинг 87. Пример определения исключительной си-


туации с помощью PRAGMA EXCEPTION INIT

Процедуры, функции
и пакеты
Реализация языка программирования высокого уровня
предполагает возможность создания и поддержки процедур и
функций. В PL/SQL процедуры и функции, связанные единым
целевым назначением, объединяются в пакеты. Особенно-
стью является то, что процедуры и функции являются объек-
тами базы данных. Это означает, что их описание хранится в
словаре данных, а собственно код хранится не в файловой
системе, а непосредственно в базе данных. Функции отлича-
ются от процедур тем, что функции возвращают в вызываю-
щую среду одно значение соответствующего типа данных, а
процедура не возвращает ничего. Oracle также поддерживает
специальный тип процедур — триггер, который рассматрива-
ется как самостоятельный объект базы данных. Детально
триггеры будут рассмотрены ниже, а коротко триггер можно
охарактеризовать как процедуру, автоматически запускаемую
сервером при наступлении некоторого события.
Исполняемый код процедур и функций хранится в базе
данных в откомпилированной форме, поэтому выполнение
188
PL/SQL — процедурное расширение языка SQL

типовых операций, Характерных для конкретного приложе-


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

SQL-функции Oracle
Набор встроенных в язык SQL функций позволяет вы-
полнить многие типовые операции обработки данных вызо-
вом соответствующей функции. Ниже приводится описание
функций, сгруппированное по типовым задачам.
Все встроенные функции можно использовать в SQL-
выражениях (как в списке после ключевого слова SELECT,
так и в других конструкциях). Очевидно, что, имея привиле-
гии на выборку данных из любой таблицы, можно вычислить
значение встроенной функции от любого набора параметров
(указав ее в перечне списка SELECT). Однако имеется еще
один способ. Каждая база данных Oracle имеет специальную
общедоступную таблицу с именем dual. Эта таблица находит-
ся в схеме пользователя SYS и содержит один столбец dummy
и одну строку. Дня нее существует общий синоним. Один из
наиболее распространенных вариантов использования табли-
цы dual — вычисление результатов SQL-функций с помощью
запросов к ней.

Функции, устанавливающие
соответствие числовых кодов и символов

Функция СИЩномер_символа) возвращает символ,


имеющий соответствующее значение параметра но-
мер_символа в используемом коде (обычно ASCII). Пример
применения функции представлен в листинге 88.
189
Раздел 3

SQL> SELECT CHR(65)||CHR(66)||CHR(67) "CHR"


2 FROM dual;

CHR

ABC

Листинг 88. Пример применения функции определения


символа по его номеру в кодовой таблице

Функция А8СП(смивол) возвращает числовое значение


(номер) символа, заданного параметром символ. Пример при-
менения функции представлен в листинге 89.

SQL> SELECT ASCII('D') "Функция ASCII" FROM dual;

Функция ASCII

68

Листинг 89. Пример применения функции определения


номера символа . .

Функции преобразования символов подстрок

Функция Ш1ТСАР(сотрока) преобразует каждую первую


букву слов параметра строка в прописную, а все последую-
щие в строчные. Пример применения функции представлен в
листинге 90.

SQL> SELECT INITCAP('бАзА дАнныХ')


2 "Функция INITCAP" FROM dual;

190
PL/SQL — процедурное расширение языка SQL
Функция INITCAP

База Данных

Листинг 90. Пример применения функции преобразо-


вания первой буквы в прописную

Функция LOWER(c/wpo/ca) преобразует каждую букву


параметра строка в строчную. Пример применения функции
представлен в листинге 91.

SQL>SELECT LOWER(' бАзА дАнныХ')


2 "Функция LOWER" FROM dual;

Функция LOWER

база данных

Листинг 91. Пример применения функции преобразо-


вания букв в строчные

Функция ЦРРЕН(с/ирока) преобразует каждую букву па-


раметра строка в прописную. Пример применения функции
представлен в листинге 92.

SQL> SELECT UPPER('бАзА дАнныХ')


2 "Функция UPPER" FROM dual;

Функция UPPER

БАЗА ДАННЫХ

Листинг 92. Пример применения функции преобразо-


вания букв в прописные

191
Раздел 3

Символьные функции усечения


и дополнения строк

Функция 1,РАЗ)(строка_1, число ^символов {&им-


вол_наполнителъ]) возвращает значение параметра строка_1,
дополненное слева до числа символов, которое задано пара-
метром число^имволов, символом-наполнителем, заданным
параметром символ_наполнителъ. По умолчанию символом-
наполнителем является пробел.
Функция RPAD(cmpoKa_l, число_символов {^сим-
вол_наполнителъ]) возвращает значение параметра строка_1,
дополненное справа до числа символов, которое задано пара-
метром число_символов, символом-наполнителем, заданным
параметром символ_наполнителъ. По умолчанию символом-
наполнителем является пробел. Пример применения функции
LPAD и RPAD представлен в листинге 93.

SQL> SELECT LPAD{'база данных', 14, ' + ' )


2 "Функция LPAD" FROM dual;

Функция LPAD

+++база данных
~_
SQL> SELECT RPAD{'база данных 1 , 14, ' + ' )
2 "Функция RPAD" FROM dual;

Функция RPAD

база данных+++
Листинг 93. Пример применения функций дополнения
строк

Функция 1,ТШМ(строка_1, [#трока_шаблон]) возвра-


щает усеченное слева значение параметра строка_1. Из стро-
192
PL/SQL — процедурное расширение языка SQL

ки параметра строка_1 символы удаляются слева до тех пор,


пока удаляемый символ входит во множество символов пара-
метра строка_шаблон. По умолчанию строка_шаблон состо-
ит из символа пробела.
Функция RTKJM(cmpoKa_l', [,строка_шаблон]) возвра-
щает усеченное справа значение параметра строка_1. Из
строки параметра строка_1 символы удаляются справа до тех
пор, пока удаляемый символ входит во множество символов
параметра строка_шаблон. По умолчанию строка_шаблон
состоит из символа пробела. Примеры применения функций
LTRIM и RTRIM представлены в листинге 94.

SQL>SELECT LTRIM(' база данных 1 )


2 "Функция LTRIM" FROM dual;

Функция LTRIM

база данных

SQL>SELECT RTRIM('база данных ')


2 "Функция RTRIM" FROM dual;

Функция RTRIM

база данных

SQL> SELECT LTRIM{' база данных',' абз')


2 "Функция LTRIM" FROM dual;

Функция LTRIM

данных

Листинг 94. Примеры применения функций усечения


строк

193
7. Заказ № 1628.
Раздел 3

Символьные функции
преобразования строк
Функция TRANSLATE(c/wp0KO_7, символы_поиска, сим-
волы_замены) возвращает значение параметра строка_1, для
которой выполнено следующее преобразование. Все вхожде-
ния параметра символ_поиска замещены значением параметра
символ_замены. Если в строке символы_поиска содержится
больше символов, чем в строке символы_замены, то символы,
которым нет соответствия, замещаются на пустой символ (то
есть исключаются из результирующей строки). Функция
TRANSLATE может применяться, в частности, для обработки
текстов, подготовленных с использованием различных рас-
кладок клавиатур. Пример применения функции'
TRANSLATE представлен в листинге 95.

SQL>S.ELECT TRANSLATE с Функция TRANSLATE применя-


етсяё в ч а с т н о с т и ё ' , ' ё ' , ' , ' )
2 "Функция TRANSLATE" FROM dual;

Функция TRANSLATE

Функция TRANSLATE применяется, в частности,

Листинг 95. Пример применения функции преобразо-


' вания символов строк

Функция REPLACE(c/wpOKa_7, строка_поисксг


[,строка_замещения\) возвращает значение параметра стро-
ка^, для которой выполнено следующее преобразование. Все
вхождения параметра строка_поиска замещены значением
параметра строка_замещения. Если параметр строка_заме-
щения не задан, то все вхождения параметра строка_поиска
удаляются. Пример применения функции REPLACE пред-
ставлен в листинге 96.

194
PL/SQL — процедурное расширение языка SQL

SQL>SELECT REPLACE('Фирма Gold Star','Gold Star',


2 'LG') "Функция REPLACE" FROM dual;

Функция REPLACE

Фирма LG

Листинг 96. Пример применения функции замены под-


строк .

Функции, связанные с выделением


подстрок

Функция SUBSTR(cmpoKa_/, позиция [,длина_подстро-


ки]) возвращает подстроку параметра строка_1, начиная с
позиции, заданной параметром позиция, и длиной, заданной
параметром длина_подстроки. Если параметр дли-
на_подстроки не задан, то возвращается подстрока до конца
строки, заданной параметром строка_1. Примеры примене-
ния функции SUBSTR представлены в листинге 97.

SQL> SELECT SUBSTR('ABCDEF',2,4)


2 "Функция SUBSTR" FROM dual;
Функция SUBSTR

BCDE

SQL> SELECT SUBSTR('ABCDEF1,3)


2 "Функция SUBSTR" FROM dual;

Функция SUBSTR

CDEF
Листинг 97. Примеры применения функции SUBSTR для
выделения подстрок

195
Раздел 3

Функция Ш8ТК(с/ир<жа_./, строкаJIOUCKO [,пози-


ция_начала_поиска [,число_вхождений]]) возвращает пози-
цию вхождения строки, задаваемой параметром стро-
каjtoucxa, в строку, задаваемую параметром строка_1. По-
зиция начала поиска задается необязательным числовым па-
раметром позиция_начала_поиска, а необязательный пара-
метр число_вхождений задает требуемое число вхождений
строки поиска в основную строку. Значения по умолчанию
для необязательных параметров — 1. При отсутствии требуе-
мого параметра вхождения строки поиска в основную строку
функция возвращает значение 0. Примеры применения функ-
ции INSTR представлены в листинге 98.

SQL>SELECT INSTR('Барабан' , 'ба',1,2)


2 "Функция INSTR" FROM dual;

Функция INSTR

SQL> SELECT INSTR('барабан','ба', 1, 2)


2 "Функция INSTR" FROM dual;

Функция INSTR

SQL> SELECT INSTR('барабан','ба') "Функция INSTR"


FROM dual;

Функция INSTR

Листинг 98. Примеры применения . функции определе-


ния позиций вхождений подстрок

196
.1 -
PL/SQL — процедурное расширение языка SQL

Функция LENGTH(c/wpoKo) возвращает длину строки,


заданной параметром строка. Пример применения функции
LENGTH представлен в листинге 99.

SQL> SELECT LENGTH('барабан 1 )


2 "Функция LENGTH" FROM dual;
Функция LENGTH

ЛИС-РИНГ 99. Пример применения функции определения


длины строки

Числовые функции, связанные


с возведением в степень
и логарифмированием

Функция ЕХР(числовой_аргумент) возвращает число е


(основание натуральных логарифмов) в степени параметра
числовой аргумент.
Функция \Л^(числовой_аргумент) возвращает натураль-
ный логарифм положительного параметра числовойАргу-
мент. Пример применения функций ЕХР и LN представлен в
листинге 100.

SQL> SELECT ЕХР(LN(10.0)) "Функции LN и ЕХР1


2 FROM dual;
Функции LN и ЕХР
10

Листинг 100. Пример применения функций логарифми-


рования и возведения в степень

197
Раздел 3

Функция POWER(ocH0e<7HMe, числовой_аргумент) воз-


вращает значение параметра основание в степени параметра
числовой_аргумент. Если параметр основание отрицатель-
ный, то параметр числовой^аргумент должен быть целым.
Функция SQRT'(числовой_аргумент) возвращает значе-
ние квадратного корня параметра числовой_аргумент. Если
параметр числовой_аргумент отрицательный, то возвращает-
ся сообщение об ошибке.
Функция IjOG(ocHoeaHue, числовой_аргумент) возвраща-
ет логарифм по основанию, заданному параметром основание,
параметра числовой аргумент. Параметр основание может
быть любым положительным числом, за исключением 1, а
параметр числовой_аргумент должен быть положительным
числом.
Примеры применения функций POWER и LOG представ-
лены в листинге 101.

SQL> SELECT POWER(-3,5) "Функция POWER"


2 FROM dual;

Функция POWER

-243

SQL> SELECT P O W E R ( 6 , L O G ( 6 , 5 . 2 5 ) )
2 "Функции POWER и LOG" FROM dual;

Функции POWER и LOG

5.25

Листинг 101. Примеры применения функций логариф-


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

Тригонометрические функции
Функции &Т№(числовой_аргумент), СО8(числовой_аргу-
мент), ТА^(чг4словой_аргумент) возвращают соответственно
198
PL/SQL — процедурное расширение языка SQL

синус, косинус и тангенс параметра числовой_аргушент. Па-


раметр числовой_аргумёнт предполагается заданным в ра-
дианах.
Функции А8Ш(чмсл0вой_оргул<ен/я) и АСО8(чмсло-
вой_аргумент) возвращают соответственно арксинус и аркко-
синус параметра числовой_аргумент. Параметр число-
вой_аргумент предполагается находящимся в диапазоне от -1
до 1. При вычислении функции с параметром числовой ^аргу-
мент вне указанного диапазона, выдается сообщение об
ошибке. Функция А'ТА^(числовой_аргумент) возвращает
арктангенс параметра числовой_аргумент.
Функции 8Т№Н(чг1Словой_аргумент), - СО8Н(чмсло-
вой_аргумент), ТАНН(числовой_аргумент) возвращают со-
ответственно гиперболический синус, гиперболический коси-
нус и гиперболический тангенс параметра число-
вой_аргумент. Примеры применения тригонометрических
функций представлены в листинге 102.

SQL> SELECT SIN(ASIN(1))


2 "Функции SIN и ASIN" FROM dual;

Функции SIN и ASIN

SQL> SELECT ACOS(2) FROM dual;


SELECT ACOS(2) FROM dual
*
ERROR at line 1:
ORA-01428: argument '2' is out of range

SQL> SELECT TAN(1.5707) FROM dual;

TAN(1.5707)

10381.327

SQL> SELECT TANH(1.5707)"Функция TANH" FROM dual;


199
Раздел 3

Функция TANH

.91713703

Листинг 102. Примеры применения тригонометриче^


ских функций

Числовые функции, связанные


с округлениями

Функция КОиН1)(числовой_аргумент[, позиция]) округ-


ляет значение параметра числовой аргумент с точностью,
определяемой параметром позиция. Параметр позиция опре-
деляет число десятичных знаков после запятой. Если пара-
метр позиция отрицательный, то аргумент округляется до це-
лых чисел соответствующего масштаба (для значения пара-
метра —1 до десятков, от —2 — до сотен и т. д.). Значение па-
раметра позиция по умолчанию — 0.
Функция ТЯХ№С(числовой_аргумент[, позиция}) усекает
значение параметра числовой_аргумент с точностью, опре-
деляемой параметром позиция. Параметр позиция определяет
число десятичных знаков после запятой. Если параметр пози-
ция отрицательный, то аргумент округляется до целых чисел
соответствующего масштаба (для значения параметра -1 до
десятков, от -2 до сотен и т. д.). Значение параметра позиция
по умолчанию — 0.
Примеры применения функций ROUND и TRUNC пред--
ставлены в листинге 103.

SQL> SELECT ROUND{-.65,1) "Функция ROUND1


2 FROM dual;

Функция ROUND

-.7

200
PL/SQL — процедурное расширение языка SQL
SQL> SELECT TRUNC(-.65,1) "Функция TRUNC"
2 FROM dual;
Функция TRUNC
-.6

Листинг 103. Примеры применения функций округле-


ния

Функция ¥1,ООЩчисловой_аргумент) возвращает наи-


большее целое, меньшее или равное значению параметра чи-
словой _аргумент.
Функция С^И,(числовой_аргумент) возвращает наи-
меньшее целое, большее или равное значению параметра чи-
словой ^аргумент.
Примеры применения функций FLOOR и CEIL представ-
лены в листинге 104.

SQL> SELECT (-.65 - FLOOR(-.65)) "Дробная часть"


2 FROM dual;
Дробная часть
.35
SQL> SELECT CEIL(-.65) "Функция CEIL" FROM dual;
Функция CEIL
0
Листинг1 104. Примеры применения функций округле-
ни я

Числовые функции, связанные


со знаком числа
Функция АЯ8(числовой_аргумент) возвращает абсолют-
ное значение числа, заданного параметром числовой_аргу-
мент.
201
Раздел 3
Функция 81О№(числовой_аргумент) возвращает -1, если
параметр числовой_аргумент < 0, возвращает 0, если пара-
метр числовой_аргумент = 0, и возвращает 1, если параметр
числовой аргумент > 0.
Пример применения функций ABS и SIGN представлен в
листинге 105.

SQL> SELECT ABS(1),ABS(-1),SIGN(2),SIGN(-2)


2 FROM dual;
ABS(l) ABS(-l) SIGN(2) SIGN{-2)
1 1 . I --I

Листинг 105. Пример применения функций, связанных


со знаком числа

Числовые функции, связанные


с модулярной арифметикой

Функция МОЩчисловой_аргумент, основание) возвра-


щает остаток от деления параметра числовой_аргумент на
значение, определяемое параметром основание. Использова-
ние отрицательных значений параметра основание не реко-
мендуется, поскольку результат не соответствует принятому
определению модуля числа. Пример применения функции
MOD представлен в листинге 106.

SQL> SELECT MOD(123456789, 13) "Функция MOD"


2 FROM dual;
Функция MOD
1

Листинг 106. Пример применения функций определе-


ния остатка числа
202
PL/SQL — процедурное расширение языка SQL

Функции, оперирующие с датами

Функция SYSDATE возвращает дату и время, опреде-


ляемые средствами операционной системы сервера базы дан-
ных.
Функция ROUND( дата [,формат]) округляет значение
параметра дата по шаблону, определяемому параметром
формат. Если параметр формат опущен, то аргумент дата
округляется до дней (время устанавливается на полночь).
Функция TRUNC( дата [,формат]) усекает значение па-
раметра дата по шаблону, определяемому параметром фор-
мат. Если параметр формат опущен,'то аргумент дата усе-
кается до ближайшего дня (время устанавливается на пол-
ночь).
Некоторые значения параметра формат представлены в
таблице 4.

Таблица 4. Наиболее употребительные значения па-


раметра формат для дат

Параметр Тип округления


YYYY Преобразование до года. Округление в
YEAR большую сторону происходит с 1 июля.
YY
MONTH Преобразование до месяца. Округление в
MON большую сторону происходит с 16 числа.
MM
W Преобразование до того же дня недели, что
первый день месяца.
ODD Преобразование до дня.
DD
J
DAY Преобразование до начального дня недели.
DY
D
HH Преобразование до часа.
203
Раздел 3

НН12
НН24
MI Преобразование до минут.

Функция NEXT_DAY(da/»a, название_дня) возвращает


дату дня, который является первым днем, более поздним, чем
текущая дата с названием, совпадающим с указанным пара-
метром название_дня.
Функции ROUND, TRUNC, NEXT_DAY обычно исполь-
зуются для вычисления календарных интервалов, в частности
для приложений, связанных с учетом трудовой активности.
Примеры применения функций SYSDATE, ROUND,
TRUNC представлены в листинге 107.

SQL>SELECT TO_CHAR(SYSDATE,'DD-MM-YYYY HH24:MI')S


2 FROM dual;

15-04-2002 11:13

SQL> SELECT TO_CHAR(ROUND{SYSDATE,'DD'),


2 'DD-MM-YYYY HH24:MI') "Функция ROUND"_
3 FROM dual;

Функция ROUND

15-04-2002 00:00

SQL> SELECT TO_CHAR(TRUNC{SYSDATE,'DD'),


2 'DD-MM-YYYY HH24:MI') " Функция TRUNC"
3 FROM dual;

Функция TRUNC

15-04-2002 00:00

SQL> SELECT TO_CHAR(TRUNC(SYSDATE,'HH'),


2 'DD-MM-YYYY HH24:MI') " Функция TRUNC"
204
PL/SQL — процедурное расширение языка SQL
3 FROM dual;

Функция TRUNC

15-04-2002 11:00

SQL> SELECT NEXT_DAY(SYSDATE,'SUNDAY')


2 " Функция NEXT_DAY" FROM dual;

Функция NEXT_DAY

21-04-2002 11:17:35

Листинг 107. Примеры применения функций округле-


ния и усечения дат

Функции преобразования
типов данных

Функция ТО_СНАЛ(аргумент [,формат]) возвращает


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

Таблица 5. Наиболее употребительные значения па-


"-. раметра формат для чисел
Формат Вид выводимого результата
9 Выводится цифра. Лидирующий ноль за-
меняется пробелом.
0 Выводится цифра. Лидирующий 0 выво-
дится.
ЕЕЕЕ Результат выводится в экспоненциальной
нотации.
G Выводится символ-разделитель (обычно,
запятая).
205
Раздел 3

Примеры применения функций TO_CHAR представлены


в листинге 108.

SQL> SELECT TO_CHAR(1000000,'9G999G999')


2 "Функция TO_CHAR" FROM dual;
Функция ТО CHAR

1,000,000

SQL> SELECT T O _ C H A R ( 1 0 0 0 0 0 0 , ' 9 9 9 E E E E ' )


2 " Функция TO_CHAR" FROM dual;

Функция TO_CHAR

1E+06

Листинг 108. Примеры применения функции преобра-


зования в символьную строку

Функция ТО_рАТ^(символьный_аргумент [,формат])


возвращает результат преобразования значения параметра
символьный аргумент символьного типа в тип DATE. Если
параметр формат опущен, символьный аргумент должен
соответствовать формату даты, принятому в системе по умол-
чанию. Наиболее употребительные значения параметра фор-
мат представлены выше в таблице 4. Пример применения
функции TO_DATE представлен в листинге 109.

SQL> SELECT TO_DATE('01.04.2002','DD.MM.YYYY')


2 "Функция TO_DATE" FROM dual;

Функция TO_DATE

01-04-2002 00:00:00

Листинг1 109. Пример применения функции преобразо-


• вания символьных строк в даты •
206
• • \i
PL/SQL — процедурное расширение языка SQL
1
Функция ГО_Щ!МВЕЩсимвольный_аргумент) возвра-
щает результат преобразования значения параметра символъ-
ный_аргумент символьного типа в значение типа NUMBER.
Параметр символьный^аргумент может представлять числа в
любой допустимой Oracle нотации.
Пример применения функции TO_NUMBER представлен
в листинге НО.

SQL> SELECT T O _ N U M B E R ( ' 3 . 1 4 ' ) *


2 TO_NUMBER('2.78E+01')
3 "Функция
4
TO_NUMBER" FROM dual;
Функция ТО NUMBER

87.292

Листинг 110. Пример применения функции преобразо-


вания символьных строк в числа

Функция CHARTOROWГО(cгшв0льным_apгy.мeн/я) воз-


вращает результат преобразования значения параметра сим-
вольный аргумент символьного типа в тип ROWID.
г
Символьная функция СО№\ ЕКТ(символъный_аргумент,
символьный_набор1, символьный_набор2) возвращает
результат операции преобразования значения параметра сим-
вольный_аргумент из параметра символьного_набора! в
символьный_набор2.
Функция HEXTORAW(cш<вoлbным_apгyл<eн7и) возвра-
щает результат преобразования значения параметра символь-
ный_аргумент, содержащий шестнадцатеричное значение, в
значение типа RAW.
Функция ТО_8ШСЬЕ_В¥ТЕ(сгшвольный_й!рг>'л<сн/и)
возвращает результат преобразования значения параметра
символьный_аргумент, при котором многобайтные символы,
имеющие однобайтные эквиваленты заменяются на соответ-
ствующие однобайтовые символы.

207

"
Раздел 3

При использовании в выражениях различных типов дан-


ных Oracle выполняет неявное преобразование типов. Для
выполнения преобразования Oracle может преобразовать кон-
станту в тип данных столбца; значение столбца к типу дан-
ных константы; тип данных столбца к типу данных другого
столбца. Например, при выборке значения из столбца типа
DATE в переменную типа CHAR или VARCHAR2 автомати-
чески вызывается функция TO_CHAR для преобразования
даты из внутреннего формата в строку, используя формат да-
ты, установленный по умолчанию. Если требуется получить
строку, содержащую дату в другом формате, то следует явно
вызвать функцию преобразования типа TO_CHAR с подхо-
дящей маской форматирования. Обратно, при записи в стол-
бец типа DATE значения из переменной типа CHAR или
VARCHAR2 автоматически вызывается функция TO_DATE.
При этом предполагается, что строка содержит символьную
запись даты в формате по умолчанию. В противном случае
произойдет ошибка.
Преобразования данных являются контекстно-
зависимыми, поэтому нельзя ожидать, что во всех случаях
будет выполняться тот же вид преобразования. Вместо того
чтобы полагаться на неявные или автоматические преобразо-
вания, необходимо использовать явное преобразование, обес-
печиваемое функциями SQL. Неявное преобразование типов
также может негативно влиять на производительность, осо-
бенно если значения столбца таблицы с большим числом
строк преобразовываются к типу данных константы.

Функции замены аргументов

Функция №УЦаргумент_1, аргумент_2) возвращает


аргумент_2, если аргумент_1 имеет неопределенное значе-
ние (NULL), в противном случае возвращается аргумент^.
Тип данных возвращаемого значения определяется типом
данных параметра аргумент_1.
208
PL/SQL — процедурное расширение языка SQL

Проиллюстрируем применение функции NVL на таблице,


созданной и заполненной предложениями:

CREATE TABLE Tab! (Atl NUMBER, At2 VARCHAR2(1));


INSERT INTO Tabl VALUES (1, NULL);
INSERT INTO Tabl VALUES (NULL, 'A');

Пусть приложение требует замены всех неопределенных


числовых значений на 0, а неопределенных символьных зна-
чений на знак "*".

SQL> SELECT NVL (Atl, 0.) "Функция NVL", NVL (At2, ' * ' )
2 "Функция NVL" FROM Tabl;
Функция NVL Функция NVL

1 *
О А

Листинг 111. Пример применения функции замены не-


определенных значений '

Обратите внимание, если второй аргумент функции NVL


является вычисляемым выражением, . то он вычисляется
всегда, даже в том случае, когда первый аргумент не является
NULL-значением. Проиллюстрируем сказанное следующим
примером:

SQL> SELECT NVL(SYSDATE,


2 TO_DATE{'01-01-2002','DD-MM-YYYY1)) D
3 FROM dual;

14-03-2002 14:17:23
SQL> SELECT NVL(SYSDATE,
209
Раздел 3
2 TO_DATE('ABC', ' D D - M M - Y Y Y Y ' ) ) FROM dual ;
SELECT N V L ( S Y S D A T E , T O _ D A T E ( ' A B C 1 , ' D D - M M - Y Y Y Y ' ) )
*
ERROR at line 1:
ORA-01858: a non-numeric character was found
where a numeric was expected

Листинг 112. 'Пример, иллюстрирующий обязатель-


ность вычисления второго аргумента функции
NVL

Перегружаемая SQL-функция DECODE (выражение,


аргумент_1, результат_1, [ аргумент_2, результат_2, ...]
[значение_по_умолчанию] ) возвращает значение параметра
результату, если параметр выражение совпадает с
параметром аргумент_х, где х принимает значение 1, 2, ... .
Если совпадения ни с одним параметром аргументу не обна-
ружено, то возвращается параметр значение_по_умолчанию.
Если значение_по_умолчанию не задано, то возвращается не-
определенное значение (NULL).

SQL> SELECT DECODE(0,0,'мужской',1,'женский',


2 'пол не определен1) "Функция DECODE"
3 FROM dual;

Функция DECODE

мужскбй

SQL> SELECT DECODE(2,0,'мужской',1, 'женский',


2 'пол не определен1) "Функция DECODE"
3 FROM dual;

Функция DECODE

пол не определен

Листинг 113. Примеры применения функции декодиро-


вания

210
PL/SQL — процедурное расширение языка SQL

Наряду с декодированием функцию DECODE используют


для написания запросов с особенно изощренной логикой,
например, в зависимости от значений полей в записи одной
таблицы можно выбирать, по какому правилу соединять эту
запись с записями другой таблицы. Результат функции
DECODE удобно передавать в качестве параметра
агрегирующей функции. Пример эффективного кодирования
SQL-выражений приведен в разделе "Методы повышения
производительности".
Функция СКЕАТЕ8Т(аргумент_1, аргумент_2, ...)
возвращает наибольшее значение из списка параметров
аргументу. При этом используются обычные правила
сравнения для различных типов.
Функция 1ЖА8Т(аргумент_1, аргумент_2, ...)
возвращает наименьшее значение из списка параметров
аргументах. Примеры применения функций GREATEST и
LEAST представлены в листинге 114.

SQL> SELECT GREATEST(1,2,10) G, LEAST(1,2,10) L


2 FROM dual;
G L

10 1

Листинг 114. Пример применения функций GREATEST и


LEAST

Справочные функции

Функция UID возвращает целое число, которое уникаль-


но идентифицирует текущего пользователя.
Функция USER возвращает имя текущего пользователя
Oracle.

211
Раздел 3

Функция 1]8ЕКЕ^У(символьный_аргумент) возвращает


сведения о текущей сессии. Символьный аргумент помеща-
ется в одиночных кавычках и должен принимать значения из
следующего списка: ENTRYID, SESSIONSID, TERMINAL,
LANG, LANGUAGE, LABEL, INSTANCE, ISDBA.
Примеры применения функций UID, USER и USERENV с
различными параметрами представлены в листинге 115.

SQL> SELECT USER,UID,USERENV('ENTRYID') ENTRYID,


2 U S E R E N V ( ' T E R M I N A L ' ) TERMINAL,
3 U S E R E N V ( ' L A N G ' ) LANG FROM dual;

USER UID ENTRYID TERMINAL LANG

ul 5 0 DATAFORT US

Листинг1 115. Пример применения справочных функций

В качестве хорошего примера работы встроенных SQL-


функций приведем готовую функцию подсчета контрольной
суммы для символьной строки. Естественно, для серьезных
приложений требуется использование специально разрабо-
танных и сертифицированных алгоритмов, поэтому функцию
chksum следует рассматривать лишь как иллюстрацию при-
менения функций SUBSTR, LENGTH, MOD, ASCII и управ-
ляющих конструкций PL/SQL. Создание функции и работа с
ней представлены в листинге 116.

SQL> CREATE OR REPLACE FUNCTION


2 chksum(text IN VARCHAR) RETURN NUMBER IS
3 ic NUMBER(20);
4 s.uml NUMBER (10) := 0;
5 sum2 NUMBER(10) := 0;
6 len NUMBER(10);
7 i NUMBER(10) := 0;
8 с VARCHAR2(1);
212
PL/SQL — процедурное расширение языка SQL
9 BEGIN
10 len := LENGTH(text);
11 WHILE i <'len LOOP
12 с := SUBSTR(text, i+1,1);
13 suml : = suml + ASCII(c);
14 IF suml >= 255 THEN
15 suml := suml-255;
16 END IF;
17 sum2 := sum2+suml;
18 i := i+1;
19 END LOOP;
20 sum2 := MOD(sum2,255);
21 ic : = suml*256 + sum2; • ,.
22 RETURN ic;
23 END;
24 /
Function created.

SQL> SELECT chksum('Текст номер 1') chk FROM dual


2 UNION ALL
3 SELECT chksum('Текст номер 2') FROM dual
4 UNION ALL
5 SELECT chksum('Номер 1 текст') FROM dual;

CHK

39466
39723
39504

Листинг 116. Пример создания и работы функции вы-


числения контрольной суммы _^

Создание пользовательских
процедур и функций
Процедуры и функции — это объекты базы данных и,
следовательно, они создаются командой CREATE и уничто-
жаются командой DROP. При создании процедуры или функ-
ции должны быть определены имя объекта, перечень и тип

213
Раздел 3

параметров и логика работы программы, закодированная на


языке PL/SQL.
Чтобы создать процедуру или функцию, необходимо
иметь системные привилегии CREATE PROCEDURE. Для
создания процедуры, функции или пакета в схеме, отличной
от своей схемы, требуется системная привилегия CREATE
ANY PROCEDURE. Более тонкие вопросы разграничения
доступа будут рассмотрены в соответствующем разделе.
После определения имени новой процедуры или функции
необходимо задать имена, типы и виды параметров. Для каж-
дого параметра обычно указывается вид — IN, OUT или IN
OUT. Вид параметра IN предполагает, что значение парамет-
ра должно быть определено при обращении к программе и не
изменяется программой. Попытка изменить в теле программы
значение параметра вида IN приведет к сообщению об ошиб-
ке. Вид параметра OUT предполагает изменение значения
параметра в процессе работы программы, то есть параметр
вида OUT — это возвращаемый параметр. Параметр IN OUT
— это параметр, которому при вызове должно быть присвое-
но значение, которое может быть изменено в теле программы.
Дополнительно к определениям, необходимым для
процедуры, в определении функции должен быть указан тип
данных возвращаемого функцией значения. Возврат значения
функции выполняется оператором RETURN.
Оператор определения процедуры Oracle использует сле-
дующий синтаксис:
' N

CREATE [OR REPLACE] PROCEDURE


[имя_ схемы.]имя_процедуры
[(имя_параметра [{IN | OUT J IN OUT}] тип_данных
[,имя_параметра [{IN | OUT | IN OUT}] тип_даннык
...])']
{IS I AS} программа_на_PL/SQL

Ключевое слово OR REPLACE указывает на безусловное


замещение старого текста процедуры. Если ключевое слово
OR REPLACE не указано и процедура определена, то заме-
214
PL/SQL — процедурное расширение языка SQL

щения старого значения кода процедуры не происходит и


возвращается сообщение об ошибке.
Обратите внимание, что при описании переменных про-
цедуры не используется ключевое слово DECLARE. Блок оп-
ределения данных начинается сразу после ключевого слова
AS (или IS, по выбору пользователя).
Рассмотрим пример создания процедуры, которая заносит
в таблицу значение определенной функции от числового па-
раметра и текущую дату.
Пусть таблица Tab! создана предложением:

CREATE TABLE Tabl (Atl NUMBER, At2 DATE);

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


117.

SQL> CREATE OR REPLACE PROCEDURE InsRec


2 (Argl IN NUMBER)
3 AS
4 Coeff CONSTANT NUMBER := 0.5;
5 BEGIN
6 INSERT INTO Tabl VALUES(Coeff*Argl,SYSDATE);
7 END;
/
Procedure created.

Листинг 117. Протокол создания процедуры, выпол-


няющей вставку записей в таблицу Tabl
Процедура InsRec может быть отправлена на выполнение
командой EXEC утилиты SQL*Plus, вызовом из анонимного
блока или другой программы. Последующая выборка из таб-
лицы Tabl иллюстрирует изменения в базе данных, осущест-
вленные вызовом процедуры InsRec.

SQL> BEGIN
2 InsRec(240)
215
Раадел 3
3 END;-
4 /

PL/SQL procedure successfully completed.

SQL> SELECT * FROM Tabl;

ARG1 ARC 2
120 04-05-2002

Листинг 118. Протокол изменений в базе данных,


выполняемых созданной процедурой .

В большинстве случаев первая попытка скомпилировать


программу на PL/SQL (процедуру, функцию, пакет или триг-
гер) приводит к получению сообщения о наличии в програм-
ме ошибок. Чтобы уточнить выявленные в процессе синтак-
сического анализа ошибки, можно воспользоваться командой
SQL*Plus SHOW ERRORS. Эта команда показывает ошибки,
обнаруженные в процессе выполнения CREATE PROCE-
DURE, CREATE FUNCTION, CREATE TYPE BODY, CRE-
ATE PACKAGE, CREATE PACKAGE BODY и CREATE
TRIGGER. Если команда SHOW ERRORS используется без
параметров, то возвращаются ошибки последней компилиро-
ванной процедуры, функции, пакета, тела пакета или тригге-
ра.
Рассмотрим пример обнаружения и исправления ошибки.
В процедуре, представленной в листинге 117, добавим оши-
бочный оператор, изменяющий значение параметра вида IN
(напомним, что параметры вида IN не должны изменяться).
Листинг 119 представляет протокол компиляции и вывод ко-
манды SHOW ERRORS.

SQL> CREATE OR REPLACE PROCEDURE InsRec


2 (Argl IN NUMBER)
3 AS
216
PL/SQL — процедурное расширение языка SQL
4 Coeff CONSTANT NUMBER := 0.5;
5 BEGIN
6 Argl := Argl + 234;
7 INSERT INTO Tabl VALUES(Coeff*Argl,SYSDATE);
8 END;
/
Warning: Procedure created with compilation er-
rors.

SQL> SHOW ERRORS


Errors for PROCEDURE INSREC:
LINE/COL ERROR

6/1 PLS-00363: expression 'ARG1 1


cannot be used as an assignment target
6/1 PL/SQL: Statement ignored

Листинг 119. Протокол, иллюстрирующий способ ди-


агностики синтаксических ошибок в тексте
^ процедуры

Конечно, выявление синтаксических ошибок — это пер-


вый, самый простой шаг в процессе отладки процедур и
функций. Для удобства отладки программ на языке PL/SQL
можно использовать специализированные средства, например
интегрированную среду SQL Navigator производства Quest
Software. Обсуждение методов и средств отладки семантики
программ и комплексной отладки выходит за рамки этой кни-
ги.
Напомним, что функции PL/SQL отличаются от процедур
тем, что возвращают в вызывающую среду значение парамет-
ра.
Оператор определения функции Oracle использует сле-
дующий синтаксис:

CREATE [OR REPLACE] FUNCTION


[ишг_схемы. ] имя_ функции
[ (имя_параметра [{IN | OUT | INOUT}] тип_данных
[,имя_параметра [{IN | OUT | INOUT}] тип_данных
....])]
217,
Раздел 3
RETURN тип_данных
{IS | AS} программа_на_РЬ/SQL

Ключевое слово OR REPLACE указывает на безусловное


замещение старого текста функции. Если ключевое слово OR
REPLACE не указано и функция определена, то замещения
старого значения кода функции не происходит и возвращает-
ся сообщение об ошибке.
Описание типа данных для возвращаемого функцией зна-
чения требуется обязательно.
При описании переменных функции так же, как и при
описании переменных процедуры, не используется ключевое
слово DECLARE. Блок определения данных начинается сразу
после ключевого слова IS (или AS, по выбору пользователя).
Рассмотрим пример создания функции, которая вычисля-
ет сумму значений атрибутов, таких, что дата попадает в за-
данный параметрами функции интервал. Пусть таблица Tab!
создана и заполнена предложениями:

CREATE TABLE Tab! (Atl NUMBER, At2 DATE);


INSERT INTO Tabl VALUES(5, SYSDATE);
INSERT INTO Tabl VALUES(6, SYSDATE);
INSERT INTO Tabl VALUES(7, SYSDATE+1);
V
Протокол создания функции представлен в листинге 120.

SQL> CREATE OR REPLACE FUNCTION SumRecInt


2 (Argl FN DATE, Arg2 IN DATE) RETURN NUMBER AS
3 SumVar NUMBER := 0;
4 BEGIN
5 SELECT Sum(Atl) INTO SumVar FROM Tabl
6 WHERE At2 BETWEEN Argl AND Arg2;
7 RETURN SumVar;
8 END;
9 /
Function created.

218
PL/SQL — процедурное расширение языка SQL
SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE(SumRecInt(SYSDATE-
1/2, SYSDATE+1/2));
3 END;
4 /
11

PL/SQL procedure successfully completed.

Листинг 120. Протокол создания функции и обраще-


ния к ней из среды PL/SQL

Если характер использования приложений изменился, то


для освобождения ресурсов базы данных может потребовать-
ся уничтожить процедуру или функцию. В собственной схеме
пользователю не требуются дополнительные привилегии для
уничтожения процедуры или функции. Для уничтожения
процедуры или функции в схеме другого пользователя необ-
ходимо наличие привилегии DROP ANY PROCEDURE.
Для уничтожения процедуры Oracle использует следую-
щий синтаксис:

DROP PROCEDURE [имя_схемы.]имя_процедуры

Для уничтожения функции Oracle использует следующий


синтаксис:

DROP FUNCTION [имя_схемы.]имя_функции


•• \
Рассмотрим пример уничтожения функции Oracle:

SQL > DROP FUNCTION SumRecInt;


Function dropped;

Листинг 121. Протокол уничтожения функции в среде


PL/SQL

219
Раздел 3

Пакеты
Процедуры, функции, переменные и типы, объединенные
общим функциональным замыслом, часто оформляют в виде
единого объекта базы данных — пакета. Прием оформления
родственных программ в пакет хорошо известен из програм-
мистской практики. Особенностью пакетов PL/SQL является
раздельная компиляция и хранение интерфейсной и испол-
няемой частей пакета. Пакет как объект состоит из двух час-
тей: спецификации пакета и тела пакета. В спецификации па-
кета хранится описание процедур, функций, глобальных пе-
ременных, констант, типов и курсоров, которые доступны для
внешних приложений. В теле пакета определяются все про-
цедуры, функции и переменные, включая те, которые не были
определены в спецификации пакета. Процедуры, функции и
переменные, определенные в теле пакета, но не описанные в
его спецификации, являются локальными. Внешние по отно-
шению к пакету приложения не могут обращаться к локаль-
ным объектам пакета. Локальные объекты предназначены ис-
ключительно для использования только процедурами и функ-
циями самого пакета.
Особенностью пакетов PL/SQL является поддержка пере-
гружаемых функций и процедур. Процедуры или функции
могут иметь одинаковое имя, но различный по типу или ко-
личеству набор аргументов. В момент обращения к конкрет-
ной процедуре или функции по числу и типу передаваемых
аргументов автоматически определяется требуемая версия
процедуры или функции, которая и исполняется. Поддержка
перегружаемых процедур, в частности, используется в стан-
дартном пакете DBMS_OUTPUT для единой формы обраще-
ния к процедуре PUT_LINE для вывода данных различных
типов.
Для создания пакета пользователь должен иметь приви-
легию CREATE PROCEDURE. Создание пакета в схеме дру-
220
PL/SQL — процедурное расширение языка SQL
того пользователя требует наличия привилегии CREATE
ANY PROCEDURE. Оператор определения интерфейсной
части (спецификации) пакета Oracle использует следующий
синтаксис:

CREATE [OR REPLACE] PACKAGE имя_схемы.]имя_пакета


(IS I AS} спецификация_пакета_на_Р1>/'SQL

Ключевое слово OR REPLACE указывает на безусловное


замещение старого текста спецификации пакета. Если ключе-
вое слово OR REPLACE не указано и пакет определен в схе-
ме, то замещения старой спецификации пакета не происходит
и возвращается сообщение об ошибке.
Спецификация пакета начинается с описания констант,
типов и переменных. При описании переменных пакета клю-
чевое слово DECLARE не используется.
Рассмотрим пример создания спецификации пакета, ко-
торая состоит из описания константы, функции и процедуры.

SQL> CREATE OR REPLACE PACKAGE PACAA AS


2 PACAA_CONST CONSTANT NUMBER := 1.2;
3 FUNCTION MULCONST(Argl NUMBER) RETURN NUMBER;
4 PROCEDURE AUDITMUL;
5 END;
6 /
Package created.

Листинг 122. Протокол создания спецификации паке-


та •

Оператор определения исполнительной части (тела) паке-


та Oracle использует следующий синтаксис:

CREATE [OR REPLACE] PACKAGE BODY


[имя_схемы. ] имя_пакета
{IS I AS} специфмкация_пакета_на_РЬ/'SQL

221
Раздел 3
Ключевое слово OR REPLACE указывает на безусловное
замещение старого текста тела пакета. Если ключевое слово
OR REPLACE не указано и пакет определен в системе, то за-
мещения старого значения тела пакета не происходит и воз-
вращается сообщение об ошибке.
Определение тела пакета начинается с описания конс-
тант, типов и переменных. Константы, типы и переменные,
описанные в спецификации пакета, являются глобальными и
в теле пакета повторно не описываются. При описании кон-
стант и переменных пакета ключевое слово DECLARE не ис-
пользуется.
Рассмотрим пример создания тела пакета, спецификация
которого приведена в листинге 122. Пусть функция пакета
mulconst выполняет умножение аргумента на константу паке-
та, а процедура auditmul фиксирует факт обращения к функ-
ции mulconst записью в таблицу значения счетчика рбраще-
ний и текущей даты. Предполагается, что таблица TabAUD с
соответствующими типами данных атрибутов к моменту соз-
дания тела пакета создана. Протокол создания тела пакета
приведен ниже.

SQL> CREATE OR REPLACE PACKAGE BODY PACAA AS


2 PACAA_COUNT NUMBER := 0;
3 FUNCTION MULCONST(Argl NUMBER)RETURN NUMBER IS
4 BEGIN
5 AUDITMUL;
6 RETURN Argl*PACAA_CONST;
7 END;
8
9 PROCEDURE AUDITMUL IS
10 BEGIN
11 PACAA_COUNT := PACAA_COUNT + 1;
12 INSERT INTO TabAUD
13 VALUES(PACAA_COUNT, SYSDATE);
14 COMMIT;
15 END;
16 END;
/
222
PL/SQL — процедурное расширение языка SQL
Package body created.

Листинг 123. Протокол создания тела пакета, спе-


цификация которого представлена в листинге
122

Обратите внимание на то, что при описании функций и


процедур пакета в отличие от описаний одиночных функций
и процедур оператор CREATE не используется.
Константы, типы или переменные, объявленные в специ-
фикации пакета, могут быть доступны из других программ.
Чтобы обратиться к глобальной переменной или константе
пакета, нужно указать в качестве префикса имя пакета.
Ниже приведен пример, иллюстрирующий возможность
доступа к глобальной константе пакета и невозможность дос-
тупа к частной переменной пакета. Сравните два примера из
листинга 124:

SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE(PACAA.PACAA_CONST};
3 END;
4 /
1.2

PL/SQL procedure successfully completed.

SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE{PACAA.PACAA_COUNT);
3 END;
4 /
DBMS_OUTPUT.PUT_LINE(PACAA.PACAA_COUNT);
*
ERROR at line 2:
ORA-06550: line 2, column 30:
PLS-00302: component 'PACAA_COUNT' must be de- •
clared

223
Раздел 3
ORA-06550: line 2, column 3:
PL/SQL: Statement ignored

Листинг 124. Пример, иллюстрирующий доступность


глобальных переменных и констант пакета и
недоступность частных переменных и констант

Чтобы вызвать процедуру или функцию пакета, в вызове


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

SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE(PACAA.MULCONST(111));
3 END;
4 /
133.2

PL/SQL procedure successfully completed.


SQL> SELECT * FROM TabAUD;

ATI AT2
1 19-03-2002

Листинг 125. Пример обращения к функции созданно-


го пакета

При использовании переменных пакета обратите внима-


ние на то, как производится инициализация пакетных пере-
менных. В данном случае, после останова и повторного за-
пуска сервера, для новой сессии или после перекомпиляции
пакета счетчик обращений PACAA_COUNT будет установлен
в нулевое состояние. Если по логике приложения требуется
независимое от остановов сервера приращение счетчика,
можно воспользоваться таким объектом, как последователь-
224
PL/SQL — процедурное расширение языка SQL

ность. Проинициализировать пакетные переменные также


можно в блоке инициализации пакета, который выполняется
один раз при первом обращении к пакету.
Как правило, в программах PL/SQL происходит обраще-
ние к объектам базы данных: таблицам, представлениям, по-
следовательностям, другим программам. Если какой-либо
объект, на который ссылается программа, будет удален или
переопределен, то программа станет непригодной к использо-
ванию (недействительной). Просмотреть такие программы
можно в представлении словаря данных ALL_OBJECTS (у
соответствующих записей поле STATUS имеет значение
INVALID).
Oracle автоматически управляет зависимостями между
объектами схемы. После того как объект схемы будет пере-
определен, Oracle автоматически перекомпилирует любую
хранимую программу, зависящую от переопределенного объ-
екта, при ее очередном вызове. Эта перекомпиляция позволя-
ет Oracle проверить, что хранимые программы могут по-
прежнему работать правильно. В том случае, когда програм-
мы создаются в такой последовательности, когда сначала соз-
дается программа, ссылающаяся на еще несуществующий
модуль, может возникнуть ситуация, когда в базе данных бу-
дет большое количество программ, непригодных для исполь-
зования, хотя синтаксически они будут правильными. Для
создания списка таких программ следует выполнить следую-
щий запрос:

SQL> SELECT owner,object_name


2 FROM all_objects WHERE status»'INVALID 1 ;

OWNER OBJECT NAME

Ul VI
U2 PACKAGE1

Листинг 126. Создание списка недействительных


объектов _^
225
8. Заказ № 1628.
Раздел 3

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


программ, представлений, объектных типов и их тел, кото-
рые в настоящий момент являются непригодными для ис-
пользования, и имена их владельцев. Немного изменив запрос
(добавив в него символьные строки вида ALTER
тш^объекта COMPILE), можно получить сценарий, с по-
мощью которого можно будет перекомпилировать объекты.
Также для компиляции объектов схемы можно, использовать
процедуру COMPILE_SCHEMA системного пакета
DBMSJJTILITY.
Если какая-либо PL/SQL программа станет недействи-
тельной, то при обращении к ней будет выдано сообщение об
ошибке и произойдет сброс текущего состояния всех пакетов,
т. е. все пакетные переменные и другие конструкции потеря-
ют свои текущие значения. Иногда может возникнуть необ-
ходимость специально сбросить состояния пакетов для теку-
щей сессии. Например, если пакетные переменные играют
роль "переменных окружения" для приложения, определяя
его поведение в зависимости от их значения. В этом случае
следует использовать процедуру RESET_PACKAGE систем-
ного пакета DBMS_SESSION. Пример ее работы представлен
в листинге 127.
Пусть пакет package 1 имеет пакетную символьную пере-
менную vl.

SQL> BEGIN
2 packagel.vl:='A';
3 DBMSJ3UTPUT.PUT_LINE(packagel. vl) ;
4 END;
5 /
Д
\ ' 1'

PL/SQL procedure successfully completed.

SQL> BEGIN
2 DBMS_SESSION.RESET_PACKAGE;
3 END;
226
PL/SQL — процедурное расширение языка SQL
4 /

PL/SQL procedure s u c c e s s f u l l y completed.

SQL> set serveroutput on


SQL> BEGIN
2 DBMS_OUTPUT.PUT_LI'NE(NVL(packagel.vl, 'vl
имеет значение N U L L ' ) ) ;
3 END;
4 /
vl имеет значение NULL

PL/SQL procedure successfully completed.

Листинг 127. Пример сброса состояний пакетов

Для освобождения ресурсов сервера может потребоваться


уничтожить пакет. В собственной схеме пользователю не
требуются дополнительные привилегии для уничтожения па-
кета. Для уничтожения пакета в схеме другого пользователя
необходима привилегия DROP ANY PROCEDURE.
Для уничтожения спецификации пакета и тела пакета
Oracle использует следующий синтаксис:
DROP PACKAGE [BODY] [имя_схемы.]имя_пакета

Необязательное ключевое слово BODY указывает, что


уничтожается только тело пакета. Если ключевое слово
BODY опущено, то удаляется и спецификация и тело пакета.
Параметр имя_пакета задает имя уничтожаемого пакета.
Пример уничтожения пакета рассматривается в листинге 128.

SQL> DROP PACKAGE PACAA;


Package dropped

Листинг 128. Пример уничтожения''пакета

227
Раздел 3

Триггеры базы данных


Триггер базы данных — это процедура, которая автома-
тически запускается при возникновении определенных собы-
тий, связанных с выполнением операций вставки, удаления
или модификации данных таблицы. Событие, управляющее
запуском триггера, описывается в виде логических условий.
Когда возникает событие, соответствующее условиям тригге-
ра, серверТ)гас!е автоматически запускает триггер.
Триггеры особенно полезны там, где необходимо обеспе-
чить сложный контроль защиты данных или специальный
аудит. Они могут также осуществлять контроль целостности
данных, если требуется более сложная проверка, чем провер-
ка, обеспечиваемая декларативными ограничениями целост-
ности.
Триггер запускается при выполнении одной из трех опе-
раций изменения содержимого таблицы: INSERT, DELETE
или UPDATE. Триггер может запускаться и несколькими опе-
раторами, но хотя бы один оператор из трех должен быть
обязательно указан в условии запуска триггера. Если пере-
чень операторов, запускающих триггер, включает оператор
UPDATE, то для условий срабатывания могут быть указаны
конкретные изменяемые столбцы.
Код триггера может выполняться либо до, либо после тех
операторов, которые инициировали запуск триггера. Напри-
мер, если триггер запускается для проверки полномочий
пользователя на право выполнения операции, то, конечно,
нужно использовать триггер с запуском до выполнения опе-
рации (с ключевым словом BEFORE). Если триггер применя-
ется для формирования данных для аудиторской записи, то
разумно использовать триггер с запуском после выполнения
операции (с ключевым словом AFTER).
Иногда возникает необходимость отключения триггеров,
например, при проведении массовых операций над данными.
Для этого предназначены следующие операторы, которые
228
PL/SQL — процедурное расширение языка SQL

могут переключать режим, разрешая или запрещая запуск


триггера — ALTER TRIGGER (изменяется режим указанного
триггера) с опцией DISABLE или ENABLE и ALTER TABLE
(в этом случае переключается режим у всех триггеров, свя-
занных с таблицей).
Код триггера может быть ассоциирован либо с операцией
над таблицей в целом, либо с каждой строкой, над которой
выполняется операция. В зависимости от этого триггеры под-
разделяют на операторные триггеры и строчные триггеры.
Операторные триггеры обычно используют для проверки пра-
вил, оперирующих таблицей в целом, а строчные триггеры
часто используют для проверки ограничений целостности при
вставке строк. Условие запуска Строчного триггера может
быть уточнено дополнительным логическим условием.
Чтобы создать триггер, необходимо иметь системную
привилегию CREATE TRIGGER. Для создания триггера в
схеме, отличной от текущей схемы пользователя, требуется
системная привилегия CREATE ANY TRIGGER.
Оператор определения триггера Oracle использует сле-
дующий синтаксис:

CREATE [ORREPLACE ]TRIGGER [имя_схемы] имя_триггера


{BEFORE | AFTER}
{INSERT | DELETE | UPDATE [OF имя_столбца
[ , имя_столбца ... ] ] }
[OR { I N S E R T . | DELETE | UPDATE [OF имя_столбца
[ , имя_столбца ... ]] } . . . ]
ON [имя_схемы.]{имя_таблицы \ имя_представления }
[FOR EACH ROW][WHEN условие ]
спецификация_программы_на_ PL/SQL

Ключевое слово OR REPLACE указывает на безусловное


замещение старого текста триггера. Если ключевое слово OR
REPLACE не указано и триггер уже определен, то замещения
старого кода триггера не происходит и возвращается сообще-
ние об ошибке.

229
Раздел 3

Ключевые слова BEFORE или AFTER указывают на вы-


полнение кода триггера либо до, либо после операторов ма-
нипулирования данными, инициировавших запуск триггера.
Ключевые слова INSERT, DELETE или UPDATE опре-
деляют конкретный оператор, запускающий триггер. Не-
обязательное ключевое слово OR присоединяет дополнитель-
ный оператор, запускающий триггер.
Ключевое слово ON задает имя таблицы, ассоциирован-
ной с триггером.
Необязательное ключевое слово FOR EACH ROW опре-
деляет триггер как строчный.
Необязательное ключевое слово WHEN задает дополни-
тельное логическое условие, сужающее область событий, при
наступлении которых триггер запускается.
Прежде чем перейти к примеру построения триггера,
приведем некоторые дополнительные сведения об обработке
исключительных ситуаций в Oracle. Для аварийного заверше-
ния программ PL/SQL применяется процедура
RAISE_APPLICATION_ERROR. С ее помощью можно обра-
ботать до 1000 определяемых пользователем ошибок с номе-
рами в диапазоне от -20000 до -20999. Вызов процедуры
RAISE_APPLICATION_ERROR приводит к генерации ис-
ключительной ситуации и завершению выполнения вызвав-
шей процедуру программы (сравните с рассмотренным выше
оператором PL/SQL RAISE). При этом в среду, вызвавшую
программу, возвращается номер и текстовое сообщение о ти-
пе ошибки.
Рассмотрим пример триггера, который выполняется, если
значение вводимого атрибута "слишком уклоняется" от сред-
него значения для текущего состояния таблицы. В роли меры
"слишком большого уклонения" выберем широко применяе-
мое в инженерной практике правило "трех сигм". Пусть таб-
лица Tab! создана и заполнена предложениями:

CREATE TABLE Tab! (Atl NUMBER);


INSERT INTO T.abl V A L U E S ( 1 ) ;
230
PL/SQL — процедурное расширение языка SQL
INSERT INTO Tabl V A L U E S ( 3 ) ;
INSERT INTO Tabl V A L U E S ( 5 ) ;

Протокол создания триггера представлен в листинге 129.


При срабатывании триггера предусмотрена генерация стан-
дартной обработки ошибки, которой присваивается номер
20002 с соответствующим диагностирующим сообщением.
Обратите внимание на предопределенную переменную
:new.Atl, содержащую (по ее смыслу) вводимое значение ат-
рибута At 1.

SQL> CREATE OR REPLACE TRIGGER TRIG_TB1


2 BEFORE INSERT ON Tabl FOR EACH ROW
3 DECLARE
4 StatAvg NUMBER;
5 StatStd NUMBER;
6 StatN NUMBER;
7 BEGIN
8 SELECT COUNT(Atl),SUM(At!) , STDDEV(Atl}
9 INTO StatN^StatAvg, StatStd FROM Tabl;
10 IF (ABS(StatAvg -
StatN*(:new.Atl))/(SQRT(StatN}*StatStd) > 3) THEN
11 RAISE_APPLICATION_ERROR(-20002, 'Слишком
большое уклонение'); . '
12 END IF; .
13 END;
14 /
Trigger created.

Листинг 129. Пример создания триггера, который


запускается при превышении статистики укло-
нения от среднего значения заданного порога

Работу механизма триггера проиллюстрируем на приме-


ре. При вводе значения, достаточно близкого к среднему (в
данном случае 4), триггер не запускается и "ничего не проис-
ходит". При вводе значения атрибута, равного 7 соответст-
вующая статистика указывает на большое уклонение, проис-

231

*
Раздел 3

ходит срабатывание триггера и новая строка не включается.


Представленная в листинге 130 операция выборки подтвер-
ждает ожидаемое изменение в таблице.

SQL> INSERT INTO Tab! VALUES(4);.


1 row created.

SQL> INSERT INTO Tabl VALUES(7);


INSERT INTO Tabl VALUES(7)
*

ERROR.at line 1:
ORA-20002: Слишком большое уклонение
ORA-06512: at "Ul.TRIGJTBl", line 9
ORA-04088: error during execution of trigger
'U1.TRIG_TB1'

SQL> SELECT * FROM Tabl;

ATI

1
3
5
4

Листинг 130. Пример, иллюстрирующий работу триг-


гера по контролю вводимых данных

Следующий пример иллюстрирует возможность обработ-


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

SQL> CREATE OR REPLACE TRIGGER TRIG_TB2


2 BEFORE INSERT ON Tabl FOR EACH ROW
3 DECLARE
4 StatAvg NUMBER;
232
PL/SQL — процедурное расширение языка SQL
5 StatStd NUMBER;
6 StatN NUMBER;
7 Special_case EXCEPTION;
8 BEGIN
9 SELECT COUNT(Atl),SUM(Atl),STDDEV(Atl)
10 INTO StatN, StatAvg, StatStd FROM Tabl;
. 11 IF (ABS(StatAvg-
StatN*(:new.Atl))/(SQRT(StatN)*StatStd)>3)
12 THEN RAISE Special_case;
13 END IF;
14 EXCEPTION
15 WHEN Special_case THEN .
16 DBMS_OUTPUT.PUT_LINE('Слишком большое
уклонение');
17 WHEN OTHERS THEN
18 DBMS_OUTPUT.PUT_LINE('He диагностируемая
ошибка');
19 END;
20 /
Trigger created.

Листинг 131. Пример создания триггера, который


запускается так же, как триггер TRIG_TB1,
но проводит иную обработку ситуации _^

При вводе значения атрибута равного 7, соответствующая


статистика указывает на большое уклонение, происходит сра-
батывание триггера TRIGJTB2. Выводится диагностическое
сообщение и вводится новая строка. Представленная в лис-
тинге 132 операция выборки подтверждает ожидаемое изме-
нение в таблице.

SQL> INSERT INTO Tabl VALUES(7);


Слишком большое уклонение
1 row created.
SQL> SELECT * FROM Tabl;

ATI

1
233
Раздел 3
3
5
4

Листинг1 132. Пример, иллюстрирующий работу триг-


гера по контролю вводимых данных

На предложения языка SQL, включенные в код триггера


Oracle, наложены некоторые ограничения. Тело триггера не
может включать в себя явное использование управляющих
операторов COMMIT, ROLLBACK и SAVEPOINT, операто-
ров языка определения данных CREATE, ALTER и DROP,
операторов, управляющих разграничением доступа GRANT и
REVOKE, а также неявное выполнение перечисленных опе-
раторов через вызовы процедур и функций.
Наиболее часто при создании и сопровождении триггеров
встречается проблема так называемых мутирующих таблиц.
При попытке в триггере уровня строки обратиться к данным
таблицы, которая изменяется этим же оператором (который
вызвал срабатывание триггера), выдается сообщение об
ошибке. Проиллюстрируем этот факт. Пусть таблица Tab!
создана и заполнена предложениями:

CREATE TABLE Tabl (Atl INTEGER,At2 INTEGER);


INSERT INTO Tabl VALUES(1,1);
INSERT INTO Tabl VALUES(2,1); .

SQL> CREATE OR REPLACE TRIGGER Trl


2 BEFORE DELETE ON Tabl FOR EACH ROW
3 BEGIN
4 IF :OLD.Atl=:OLD.At2 THEN
5 UPDATE Tabl SET At2=NULL
6 " WHERE At 2=:OLD.Atl;
. 7 END IF;
8 END;
9 /
Trigger created.
234
PL/SQL — процедурное расширение языка SQL

SQL> DELETE FROM Tabl WHERE Atl=At2;


DELETE FROM Tabl WHERE Atl=At2
*
ERROR at line 1:
ORA-04091: table U1.TAB1 is mutating, trig-
ger/function may not see it
ORA-06512: at "U1..TR1", line 2
ORA-04088: error during execution o f . t r i g g e r
'U1.TR1'

Листинг 133. Пример мутирующей таблицы

Причина возникновения ошибки состоит в том, что для


операторов SQL, которые работают с множеством строк, не
гарантируется порядок обработки указанных строк. Поэтому
при каждом выполнении одинаковых операторов могут быть
получены различные результаты. И различных источниках
предложены многочисленные способы решения проблемы
мутирующей таблицы. Рассмотрим следующий алгоритм: в
триггере уровня строки сохранить записи, которые подлежат
изменениям в таблице PL/SQL (для объявления PL/SQL таб-
лицы понадобится пакет), а необходимые действия по изме-
нению таблицы выполнить в триггере AFTER. Реализация
этой идеи представлена в листинге 134.

SQL> CREATE OR REPLACE PACKAGE packagel AS


2 PROCEDURE clear_count;
3 PROCEDURE add_At2(p_At2 IN INTEGER);
4 PROCEDURE null_tab;
5 END;
6 /
Package created.

SQL> CREATE OR REPLACE PACKAGE BODY packagel AS


2
3 TYPE Tabl_At2_type IS TABLE OF INTEGER
4 INDEX BY BINARY_INTEGER;
5 At2_table Tabl_At2_type;
235
Раздел 3
6 At2_ind BINARY_INTEGER;
7
8 PROCEDURE clear_count IS
9 BEGIN
10 At2_ind:=0;
11 END;
12
13 PROCEDURE add_At2(p_At2 IN INTEGER) IS
14 BEGIN
15. At2__ind:=At2_irid+l;
16 At2_table(At2_ind) :=p_at2;
17 END;
18
19 PROCEDURE null_tab IS
20 l_At2 INTEGER;
21 BEGIN
22 FOR i IN l..At2_ind LOOP
23 l_At2:=At2_table(I);
24 UPDATE Tabl SET At2pNULL
25 WHERE At2=l_At2;
26 END LOOP;
27 END;
28
29 END;
30 /
Package body created.

SQL> CREATE OR REPLACE TRIGGER Trl


2 BEFORE DELETE ON Tabl
3 BEGIN
4 packagel.clear_count;
5 END;
6
7 /
Trigger created.

SQL> CREATE OR REPLACE TRIGGER Tr2


2 BEFORE DELETE ON Tabl FOR EACH ROW
3 BEGIN
4 packagel.add_At2(:OLD.At2);
:
5 END;
6 /
Trigger created.

236
PL/SQL — процедурное расширение языка SQL
SQL> CREATE OR REPLACE TRIGGER Tr3
2 AFTER DELETE ON Tabl
3 BEGIN
4 packagel.null_tab;-
5 END;
6 /
Trigger created.

SQL> DELETE FROM Tabl WHERE Atl=At2;


1 row deleted.

SQL> SELECT .* FROM Tabl;

ATI AT2

Листинг1 134. Решение проблемы мутирующей таблицы

Несмотря на то, что листинг кажется громоздким и непо-


нятным, пример имеет прозрачную логику. В пакете packagel
объявлена PL/SQL таблица At2_table. Для каждой удаляемой
записи триггер Тг2 с помощью пакетной функции add_At2
заносит в нее значение поля At2 удаляемой записи и увеличи-
вает значение "индекса" для этой таблицы. Значение "индек-
са" (пакетной переменной At2_ind) перед каждым примене-
нием оператора DELETE к таблице Tabl обнуляет триггер
Trl, вызывая пакетную процедуру clear_count. А после фор-
мирования PL/SQL таблицы и внесения изменений в таблицу
Tabl, выполняется триггер ТгЗ, который имеет тип AFTER и
вносит изменения, которые ранее выполнялись непосредст-
венно в теле первой версии триггера Trl. Схематично после-
довательность срабатывания триггеров можно представить
так: Trl (BEFORE -- обнуляем "индекс"), Tr2(BEFORE FOR
EACH ROW — для каждой записи запоминаем значение At2),
Tr3(AFTER — реализуем изменения, запомненные в PL/SQL
таблице).
Некоторым недостатком такого способа является боль-
шой объем памяти, требуемый для промежуточного хранения
237
Раздел 3

изменяемых данных. Отчасти его можно устранить — при


завершении работы приложения присвоить PL/SQL таблице
значение пустой таблицы или применить системную пакет-
ную функцию для освобождения памяти.

Стандартные пакеты Oracle


Промышленная разработка серверной логики на языке
PL/SQL требует от программиста знаний возможностей, пре-
доставляемых стандартными средствами сервера Oracle' В
комплект поставки сервера входит большое количество паке-
тов, предназначенных для облегчения и унификации процесса
разработки пользовательских процедур и функций. Поэтому
для экономии времени и повышения производительности
труда следует максимально широко использовать стандарт-
ные пакеты Oracle.
Всего стандартных пакетов поставляется около сотни.
Наличие тех или иных пакетов зависит от версии сервера и
комплекта поставки. Если какие — либо пакеты отсутствуют,
но из документации известно, что для данной версии они су-
ществуют, то администратор базы данных должен выполнить
соответствующий сценарий, создающий необходимые про-
граммы, таблицы, представления, синонимы, предоставляю-
щий привилегии и т. п. Как правило, стандартные пакеты на-
ходятся в схеме пользователя SYS и имеют имена с префик-
сом DBMS. Далее рассмотрим работу с основными стандарт-
ными пакетами: DBMS_SQL (динамический - SQL),
DBMS_JOB (управление заданиями), UTL_FILE (файловый
ввод-вывод), DBMS_LOB (работа с большими объектами).

Динамический SQL

Основное отличие динамически формируемых SQL-


предложений от обычных (статических) состоит в том, что
первые динамически формируются и выполняются во время
238
PL/SQL — процедурное расширение языка SQL

выполнения PL/SQL программы, а вторые — непосредствен-


но кодируются при написании самой программы.
При использовании статического SQL программист соз-
дает PL/SQL программу посредством включения в код соот-
ветствующих SQL-предложений. В этом случае в тексте про-
граммы должны содержаться в явном виде все SQL-
предложения, которые могут быть необходимы в процессе ее
работы. Но, например, если в базе данных имеется большое
число таблиц с примерно одинаковой структурой и необхо-
димо выполнять над ними примерно одну и ту же операцию,
то хотелось бы создать одну небольшую PL/SQL программу,
которая будет формировать SQL-предложение для требуемой
таблицы и тут же выполнять его.
Большинство PL/SQL программ кодируется для конкрет-
ной базы данных, конкретной структуры таблиц. Благодаря
этому, практически любую программу PL/SQL можно напи-
сать с использованием только статических предложений, осо-
бенно если не учитывать сложность и размер программы. Но
даже если не требуется создать программу, обладающую гиб-
костью при управлении непредусмотренными при кодирова-
нии выражениями, существует, по крайней мере, две причи-
ны, по которым необходимо использование динамически
формируемых SQL-предложений:
В хранимые процедуры нельзя передавать в качестве па-
раметра имя объекта базы данных. При компиляции про-
граммы PL/SQL Oracle кроме синтаксической проверки про-
водит также проверку полномочий и зависимостей объектов
базы данных, чтобы удостоверится в правильности написания
программы. Если же имя объекта базы данных неизвестно,
такая проверка невозможна. Поэтому выражение вида
SELECT ... FROM :tl, где tl передается как параметр, будет
отвергнуто еще при проверке кода.
В PL/SQL нельзя использовать выражения языка DDL.
Например, нельзя создать последовательность или таблицу.
Если бы в PL/SQL непосредственно поддерживались DDL-
предложения, то программа могла бы создавать таблицы и
239
Раздел 3

зависела бы от этих таблиц, еще не существующих при ком-


пиляции, что также является недопустимым.
.В комплект поставки сервера Oracle входит пакет
DBMS_SQL, обеспечивающий выполнение динамически
формируемых SQL-предложений в программах на PL/SQL.
Динамические SQL-предложения конструируются непосред-
ственно во время выполнения программы в виде символьной
строки, & затем передаются соответствующим программам
пакета DBMS_SQL для разбора и исполнения. Ответствен-
ность за возможное нарушение объектных зависимостей и
прав доступа, которые Oracle в данном случае во время ком-
пиляции не проверяет, теперь ложится на программиста.
Если некоторое SQL-предложение является динамически
формируемым, то приложение должно обеспечить построе-
ние правильного SQL-предложения, его разбор и выполнение,
определение столбцов для строк возвращаемого набора (в
случае запроса) и выборку строк. Число шагов, требуемое для
выполнения динамического SQL-предложения, изменяется в
зависимости от типа предложения. Для выполнения операто-
ра DDL и, скажем, запроса, они будут разными.
Для динамически сформированных операторов SQL, ко-
торые возвращают данные (т. е. для операторов SELECT) ис-
пользуется следующая последовательность обработки: от-
крытие курсора, разбор запроса, связывание переменных, оп-
ределение столбцов, выполнение запроса, выборка строк, по-
лучение значений столбцов, закрытие курсора.
Приведем пример использования динамического SQL для
выполнения запроса. Пусть таблицы Tab! и ТаЬ2 созданы и
заполнены с помощью следующих предложений:

CREATE TABLE Tab!(At1 INTEGER, At2 DATE);


CREATE TABLE Tab2(Atl INTEGER, At2 DATE);
INSERT INTO Tabl VALUES(1,SYSDATE);
INSERT INTO Tabl VALUES(2,SYSDATE-10) ;

240
PL/SQL — процедурное расширение языка SQL

Создадим процедуру, которая копирует данные из таб-


лицы, указанной параметром p_table_namel в таблицу ука-
занную параметром p_table_name2.

SQL> CREATE OR REPLACE PROCEDURE copy


2 (p_table._namel IN VARCHAR2, P_TABLE_NAME2 IN
VARCHAR2) IS
3 l_Atl NUMBER;
4 . l_At2 DATE;
.5 c_cursor INTEGER;
6 d_cursor INTEGER;
7 ignore INTEGER;
8 BEGIN
9 c_cursor := DBMS_SQL.OPEN_CURSOR;
10 DBMS_SQL. PARSE (c_cursor, 'SELECT Atl, At2
FROM ' | |
11 p_table_namel,
DBMS_SQL. NATIVE) ;
12 " DBMS_SQL.DEFINE_COLUMN (c_cursor, ~l,
_
13 DBMS_SQL.DEFINE_COLUMN (c_cursor, 2,
l_At2);
14 ignore :- DBMS_SQL. EXECUTE (c_cursor) ;
15 d_cursor := DBMS_SQL.OPEN_CURSOR;
16 DBMS_SQL. PARSE (d_cursor, 'INSERT INTO • ' I I
p_table_name2
17 M 1 VALUES (:Atl, ':At2)',
DBMS_SQL. NATIVE) ;
18 " LOOP
19 IF DBMS_SQL.FETCH_ROWS(c_cursor)>0 THEN
20 DBMS_SQL.COLUMN_VALUE(c_cursor, 1,
_
21 DBMS_SQL.COLUMN_VALUE(c_cursor, 2,
-l_At2);
22 DBMS_SQL. BIND_VARIABLE (d_cursor,
'Atl', l_Atl) ;
23 . DBMS_SQL.BIND_VARIABLE(d_cursor,
'At2', l_At2);
24 ignore := DBMS_SQL. EXECUTE (d_cursor) ;
25 ELSE
26 EXIT;

241
Раздел 3
' 21 END IF;
28 END LOOP;
29 COMMIT;
30 DBMS_SQL.CLOSE_CURSOR(c_cursor);
31 DBMSjSQL.CLOSE_CURSOR(d_cursor);
32 END;
33 I
Procedure created.

SQL> BEGIN
2 copy (' Tabl', ' Tab2'') ;
3 END;
4 J
PL/SQL procedure successfully completed.

SQL> SELECT * FROM Tab2;

ATI AT2

1 15-03-2002
2 05-03-2002

Листинг 135. Пример выборки данных с использова-


нием динамического SQL

В данном примере предполагалось, что структура таблиц


одинакова и они имеют заранее известные названия столбцов.
В более сложном примере можно, используя соответствую-
щие представления системного словаря данных, например
USER_TAB_COLUMNS, это ограничение обойти.
Вернемся к логике процедуры сору. В полном соответст-
вии с изложенной последовательностью действий, функция
DBMS_SQL.OPEN_CURSOR открывает курсор и возвращает
в переменную c_cursor его идентификатор. Затем для курсора
процедура DBMS_SQL.PARSE производит синтаксический
разбор запроса, который выбирает данные из таблицы-
источника. Обратите внимание на последний параметр про-
цедуры PARSE — пакет DBMS_SQL содержит три глобаль-
ные константы типа INTEGER: V6, V7 и NATIVE. Константы
242
PL/SQL — процедурное расширение языка SQL

указывают на использование определенных правил. V6 и V7


определяют поведение SQL-предложения по правилам Oracle
6 или Oracle 7 соответственно, NATIVE определяет поведе-
ние согласно той версии базы данных, с которой работает
приложение. Процедура DEFINE_COLUMN определяет
столбцы для записей, возвращаемых запросом. В запросе два
столбца и процедура вызывается дважды. После выполнения
этих операций запрос выполняется функцией EXECUTE. Для
каждой записи, извлеченной из этого курсора, по аналогич-
ной схеме формируется предложение вставки данных во вто-
рую таблицу. В предложении INSERT требуется подстановка
копируемых значений данных (связывание объявленных пе-
ременных с их значениями). Для этого служит процедура
BIND_VARIABLE. Каждая запись вставляется в таблицу с
помощью другого курсора.
Обратите внимание — для предложения INSERT, опре-
деляющего второй курсор, функция PARSE вызывается толь-
ко один раз. Действительно, для всех записей копируемой
таблицы оно будет отличаться только значениями данных.
Поэтому, чтобы не производить каждый раз синтаксический
разбор, необходимо определить связанные переменные и
только указывать их значения для каждой вставки данных. В
конце процедуры оба курсора закрываются. *
Для остальных видов динамически сформированных
предложений SQL, которые различаются наличием или от-
сутствием возвращаемых данных, параметрами и т. п., ис-
пользуются другие схемы вызова процедур и функций пакета
DBMS_SQL.

Таблица 6. Описание процедур и функций пакета


DBMS SQL

Имя процедуры Описание


или функции
BINDJVARIABLE Связывает значение с переменной в
курсоре. Если переменная является
243
Раздел 3

вида IN или IN OUT, то связываемое


значение должно быть того же типа.
CLOSE_CURSOR Закрывает открытый курсор, освобо-
ждая выделенную под него память.
COLUMNJVALUE Получает значение атрибута записи
курсора для текущей записи данного
курсора.
DEFINE_COLUMN Определяет поле записи, которая
должна быть выбрана из курсора.
PARSE Разбор SQL-предложения для курсо-
ра. Если разбираемое предложение
является DDL-предложением, то про-
цедура выполняет это предложение.
EXECUTE Выполняет предложение, разобран-
ное в курсоре, и возвращает число
обработанных в процессе выполнения
строк (для операторов INSERT,
UPDATE и DELETE ).
FETCH_ROWS Извлекает строку из курсора в ло-
кальный буфер. Чтобы затем прочи-
тать значения в извлеченной строке,
надо использовать процедуру
column value.
EXECUTE AND Выполняет предложение, разобран-
FETCH ное в курсоре, и извлекает первую
строку^ из курсора.
ISJ3PEN Проверяет, открыт ли курсор.
LAST ERROR Если имеет место ошибка во время
POSITION выполнения операции, разобранной в
курсоре, то функция возвращает от-
носительную позицию в курсорном
предложении, которая послужила
причиной ошибки.
LAST_ROW Возвращает число строк, извлечен-
COUNT ных до момента ее вызова из курсора.
244
PL/SQL — процедурное расширение языка SQL

LAST_SQL Возвращает код функции.


FUNCTION CODE
OPEN_CURSOR Открывает новый курсор.

Файловый ввод-вывод
Иногда возникает необходимость организовать работу
программ PL/SQL с текстовыми файлами, например, для ор-
ганизации обмена данными с внешними системами. Конечно,
с этой целью можно использовать клиентское приложение,
например SQL*Loader, или с помощью Oracle Report Builder
создать текстовый отчет. Но есть ситуации, когда обработку
файлов требуется встроить именно в хранимые программы на
стороне сервера, например, для ведения собственного журна-
ла аудита или протокола, характеризующего действия прило-
жений. При неудачном завершении операции изменения, сде-
ланные в таблицах аудита, будут отменены наряду с измене-
ниями собственно данных. Если же производить запись изме-
нений в текстовый файл на стороне сервера, то они сохраня-
ются и после отката транзакций. С помощью механизмов
PL/SQL для работы с файлами также можно загружать в базу
данных Java-программы.
Пакет UTL_FILE предоставляет программам PL/SQL
возможность открывать текстовый файл, находящийся в не-
котором каталоге на сервере и работать с ним. В пакет
UTL_FILE входят процедуры, описанные в таблице 7.
Все каталоги, которые использует в своей работе пакет
UTLJFILE, должны быть перечислены в параметре utl_file_dir
в файле параметров базы данных. Для просмотра допустимых
названий каталогов можно использовать соответствующее
представление словаря данных:

SQL> SELECT value dir FROM v$parameter


2 WHERE name='utl file d i r ' ;

245
Раздел 3

DIR

C:\Dirl
:
Листинг 136. Просмотр доступных каталогов .

Используется следующая последовательность действий с


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

Таблица 7. Описание процедур и функций пакета


UTL FILE

Имя процедуры Описание


или функции
FOPEN Открывает указанный файл для чте-
ния/записи.
IS_OPEN Проверяет, открыт ли файл.
FCLOSE Закрывает файл.
FCLOSE_ALL Закрывает все открытые файлы.
GETJLINE Считывает строку из файла.
PUT Записывает строку в файл. Символ
конца строки не добавляется.
PUTXINE Записывает строку в файл. Символ
конца строки добавляется .

В качестве примера работы с пакетом UTL_FILE приве-


дем процедуру, которая построчно переносит результат за-
проса к таблице Tab! в файл. У процедуры имеется параметр
p_mode, определяющий режим открытия файла.

246
PL/SQL — процедурное расширение языка SQL

SQL> CREATE OR REPLACE PROCEDURE ta-


ble_copy(p_mode IN VARCHAR2) IS
2 fid UTL_FILE.FILE_TYPE;
3 BEGIN
4 fid := UTL_FILE.FOPEN ( ' C : \ D i r l ' ,
' f n a m e . t x t ' , p_mode);
5 FOR rec IN (SELECT At 1',At2 FROM Tabl) LOOP
6 UTL_FILE.PUT_LINE ( f i d , r e c . A t l M 1
1
||rec.At2);
7 END LOOP;
8 UTL_FILE.FCLOSE (.fid) ;
9 EXCEPTION
10 WHEN UTL_FILE.INVALID_PATH
11 THEN DBMS_OUTPUT.PUT_LINE('Неверный ка-
талог ' ) ;
12 WHEN UTL_FILE.INVALID_MODE
13 THEN DBMSJ3UTPUT.PUT_LINE('Неверный ре-
жим работы с файлом');
14 WHEN UTL_FILE.INVALID_FILEHANDLE
15 ^HEN DBMS_OUTPUT.PUT_LINE('Неправильный
дескриптор файла '•) ;
16 WHEN UTL_FILE.INVALID_OPERATION
17 THEN DBMS_OUTPUT.PUT_LINE('Фaйл не был
открыт для записи/добавления');
18 WHEN UTL_FILE.READ_ERROR
19 THEN DBMS_OUTPUT.PUT_LINE('Ошибка. ОС при
чтении файла');
20 WHEN UTL_FILE.WRITE_ERROR
21 THEN DBMS_OUTPUT.PUT_LINE('Ошибка ОС при
записи в файл');
22 WHEN UTL_FILE.INTERNAL_ERROR
23 THEN DBMSJDUTPUT.PUT_LINE('Произошла
внутренняя ошибка');
24 WHEN OTHERS
25 THEN DBMS_OUTPUT.PUT_LINE(SQLERRM) ;
26 END;
27 /

Procedure created.

247
Раздел 3

SQL> BEGIN
2 table_copy('A');
3 END;
4 /

PL/SQL procedure successfully completed.

Листинг 137. Пример работы с текстовыми файлами


из PL/SQL

В ходе выполнения процедуры с параметром p_mode,


равным 'A' (append), в файл fhame.txt, находящийся в катало-
ге C:\Dirl, будут вставлены записи из таблицы ТаЫ. Обрати-
те внимание — если вызвать процедуру с параметром
p_mode, равным 'W (write), то существующее содержимое
файла будет заменено на содержимое таблицы. После откры-
тия файла в цикле с помощью процедуры
UTL_FILE.PUT_LINE выполняется запись строк в него. Ис-
ключительные ситуации, которые могут возникнуть при ра-
боте пакета UTLJFILE, объявлены в самом пакете и обраба-
тываются в процедуре table_copy.
Для более сложных действий с файлами можно использо-
вать готовые библиотеки, программы которых могут осуще-
ствлять поиск строк в файлах, записывать строки в заданное
место в файле, форматировать их и т. п.
Управление заданиями

Управление заданиями является мощным средством реа-


лизации бизнес-логики для баз данных. Для систем, осущест-
вляющих пакетную обработку данных, обязательно наличие
механизма, который позволяет в заданные моменты времени
выполнять задания. Например, для систем, автоматизирую-
щих финансовые расчеты за оказание каких-либо услуг, целе-
сообразно в некоторые установленные моменты времени ав-
томатически собирать сведения о задолженности клиентов за
оказанные услуги. Во время, когда сервер баз данных загру-
248
PL/SQL — процедурное расширение языка SQL

жен в меньшей степени, например ночью или в выходные


дни, в пакетном режиме автоматически могут запускаться
процедуры, выполняющие эти действия. Для сервера Oracle
планировщиком заданий являются процедуры и функции па-
кета DBMS_JOB.
При использовании пакета DBMS_JOB можно поставить
в очередь заданий программы, которые будут выполнены в
различные сроки в соответствии с указанными параметрами
запуска. На выполнение можно отправить любую программу,
написанную на языке PL/SQL. Эти программы могут выпол-
няться либо фоновым процессом сервера БД с привилегиями
поставившего их в очередь пользователя, либо собственно
пользовательским процессом. В приведенных примерах при-
меняется процедура DBMS_JbB.SUBMIT. Данная процедура
посылает серверу БД запрос на выполнение указанной поль-
зователем хранимой программы для запуска ее отдельным
фоновым процессом.
Процесс, который управляет заданиями, называется SNP-
процессом. Для того чтобы задания, находящиеся в очереди,
могли выполняться по заданному расписанию, должен суще-
ствовать хотя бы один SNP-процесс. Всего в системе могут
находиться до тридцати шести SNP-процессов, имеющих
идентификаторы от SNPO до SNP9 и от SNPA до SNPZ. Если
при работе SNP-процесса происходит ошибка, сервер авто-
матически запускает его снова. Для определения интервалов
между попытками запуска служат параметры в файле ини-
циализации базы данных.
Задание ставится в очередь и определяются моменты
времени, в которые оно будет запускаться. Допускается изме-
нение времени следующего запуска, интервала между после-
дующими запусками, удаление заданий, которые уже нахо-
дятся в очереди, а также их принудительный запуск.

249
Раздел 3
Таблица 8. Описание процедур и функций пакета
DBMS JOB

Имя процедуры Описание


или функции
SUBMIT Устанавливает задание в очередь.
CHANGE Изменяет параметры задания в
очереди.
WHAT Изменяет описание для задания.
NEXT_DATE Изменяет следующее время вы-
полнения для задания.
REMOVE Удаляет задание из очереди.
BROKEN Помечает задание как ненужное.
RUN Указывает немедленно выпол-
нить задание.
INTERVAL Изменяет интервал между после-
дующими запусками задания.

Будем рассматривать в качестве задания процедуру pi,


которая за один вызов выполняет вставку одной записи в таб-
лицу ТаЫ. Поставим ее в очередь со следующими парамет-
рами:

SQL> DECLARE
2 l_job_num NUMBER;
3 BEGIN
4 DBMS_JOB.SUBMIT(l_job_nura,'pi;',sysdate,
5 . 'sysdate+1/8640');
6 COMMIT;
7 DBMS_OUTPUT.PUT_LINE{l_j ob_num);
8 END;
9 /
23

PL/SQL procedure successfully completed.

Листинг 138. Пример создания задания с помощью


процедуры SUBMIT

250
PL/SQL — процедурное расширение языка SQL

В очередь помещается процедура р! с немедленным вы-


полнением сразу после помещения и последующим выполне-
нием каждые 10 секунд. На терминал выводится уникальный
номер задания, присвоенный р! (23).
Данные о заданиях пользователя, которые в данный мо-
мент находятся в очереди, хранятся в представлении словаря
данных USER_JOBS. Пример просмотра информации о зада-
ниях представлен в листинге 139.

SQL> SELECT job, log_user,last_sec,next_sec,


2 broken,interval,what FROM user_jobs;
JOB LAST_SEC NEXT_SEC BROKEN INTERVAL WHAT

23 11:26:51 11:27:01 N. sysdate+1/8640 pi;

Листинг 139. Пример просмотра сведений о заданиях


в очереди из представления USER JOBS

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


ределяет процедура SUBMIT при постановке задания в оче-
редь. Эти номера генерируются специальной последователь-
ностью SYS.JOBSEQ. Знать номер, присвоенный заданию,
необходимо, например, для его удаления из очереди. Для это-
го используется процедура REMOVE, параметром которой
является только номер, а не имя задания. В следующих
столбцах указаны сведения о времени последнего и следую-
щего выполнения задания, интервала выполнения и какая
именно программа составляет задание. Меткой BROKEN по-
мечаются те задания, при шестнадцати попытках выполнения
которых произошли ошибки. Также задание можно пометить
специально, используя процедуру DBMS_JOB.BROKEN.
Иногда может возникнуть необходимость удалить не-
нужное больше задание. Пример удаления задания из очереди
приведен в листинге 140. ,

251
Раздел 3

SQL> BEGIN
2 DBMS_ JOB. REMOVE ( 2 3 ) " ;
3 END;
4 /

PL/SQL procedure successfully completed.

Листинг 140. Пример удаления задания из очереди

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


задания зависит от успешности предыдущего выполнения. То
есть если, например, установить в понедельник при постанов-
ке задания в очередь в процедуре SUBMIT параметр
'SYSBATE+7', чтобы она выполнялась каждый понедельник,
то необязательно так будет происходить на самом деле. Если
в понедельник произошел сбой в работе и задание выполнить
не удалось, а удалось только, скажем, в среду, то время ново-
го выполнения будет вычислено начиная со среды, и выпол-
няться оно будет, соответственно, каждую среду. Точно так
же, если послать задание на выполнение'командой RUN, то
время следующего выполнения будет рассчитано с этого мо-
мента.

Управление LOB-объектами

Oracle в настоящее время поддерживает следующие типы


данных для работы с большими неструктурированными объ-
ектами (LOB-объектами), максимальный размер которых не
превышает 4 гигабайта:
— BLOB — тип для хранения неструктурированных
двоичных данных;
— CLOB и NCLOB — типы для хранения символьных
данных.
Эти типы данных могут использоваться при описании
столбца таблицы, атрибута объекта или в PL/SQL. Различие
252
PL/SQL — процедурное расширение языка SQL

между типами CLOB и NCLOB состоит в использовании раз-


личных кодовых таблиц.
Тип BFILE предназначен для описания файлов, находя-
щихся вне базы данных Oracle. По этой причине при работе с
объектами типа BFILE не поддерживается транзакционный
механизм Oracle (для остальных типов поддерживается). Та-
ким образом, можно выделить внешние (BFILE) и внутренние
(BLOB, CLOB) объекты.
Структура всякого LOB-объекта включает две компонен-
ты:
— указатель на объект (внутренняя ссылка на фактиче-
ское LOB-значение), который и находится в таблице;
— LOB-значение, которое хранится в специально отве-
денном месте (например, для хранимых в столбцах LOB-
объектов можно указать отдельное табличное пространство).

Значение LOB-поля может храниться либо вместе со


строкой таблицы, либо отдельно. Содержание поля с LOB-
объектом может характеризоваться одним из трех состояний:
пусто, NULL и наличие значения. Для того чтобы установить
указатель на LOB-объект, используется функция
EMPTY_BLOB (EMPTY_CLOB). LOB-переменные реально
играют роль всего только места хранения указателя на факти-
ческий объект, расположенный в БД. При всякой работе с
LOB-объектом доступ к нему производится через соответст-
вующий указатель. Когда в LOB-переменную выбирается ко-
мандой SELECT указатель, он становится согласованным по
чтению. Это значит, что данные, выбранные в свою очередь
по этому указателю, будут все время соответствовать момен-
ту выборки этого указателя. Если потом то же самое поле бу-
дет выбрано в другую LOB-переменную, и далее изменено, то
значение, выбираемое по первой LOB-переменной, не изме-
нится.
Для работы с типом BFILE также можно использовать
указатели. Объекты этого типа рассчитаны только на чтение

253
Раздел 3

данных и ни удаление имеющегося BFILE-значения, ни копи-


рование его, ни занесение в базу нового никак не влияют на
сам файл. Все эти операции выполняются над указателями.
Для обращения к файлам используется специальный объ-
ект базы данных — каталог, который представляет собой ука-
зание на место нахождения файлов в файловой системе. Ка-
талог создается оператором CREATE DIRECTORY
имя_катшюга AS путь ОС.

SQL> CREATE DIRECTORY Dirl AS 'C:\WORK';


Directory created.

Листинг1 141. Пример создания каталога

Проиллюстрируем вышесказанное на примере таблицы


ТаЫ.

SQL> CREATE TAB.LE ТаЫ (Atl NUMBER,At2 BLOB,


2 At3 BFILE);
Table created.

SQL> INSERT INTO Tab! VALUES(1,NULL,NULL);


1 row created.

SQL> INSERT INTO Tabl VAL-


UES (2,EMPTY_BLOB(},NULL);
1 row created.

SQL> INSERT INTO Tabl VALUES


2 (3,NULL,BFILENAME('Dirl','filel' ));
1 row created.

Листинг 142. Пример вставки в таблицу LOB-


объектов

Как и для объектов BLOB (CLOB), столбцам типа BFILE


можно присвоить значения NULL или значения-указатели на
254
PL/SQL — процедурное расширение языка SQL

файлы. Для этого служит специальная функция BFILENAME.


Пример ее работы представлен в листинге 142.
При удалении этой записи из таблицы Tab! с файлом
filel никаких действий не производится.
Для работы с LOB-объектами предназначен стандартный
пакет DBMS_LOB. Процедуры и функции из этого пакета по-
зволяют производить различные операции (чтение, запись)
над LOB-объектами как целиком, так и по частям.

Таблица 9. Описание процедур и функций пакета


DBMS LOB

Имя процедуры Описание


или функции
APPEND Приписывает к одному LOB-объекту
другой:
WRITE Записывает данные в LOB-объект.
COMPARE Сравнивает два LOB-объекта одного
типа
GETLENGTH Возвращает длину LOB-объекта.
INSTR Возвращает позицию n-ого вхожде-
ния строки в LOB-объект.
READ Считывает часть LOB-объекта.
SUBSTR Возвращает часть LOB-объекта начи-
ная с заданного смещения.
FILECLOSE Закрывает файл по указателю BFILE.
FILECLOSEALL Закрывает все файлы по имеющимся
указателям BFILE.
FILEEXISTS Проверяет фактическое наличие фай-
ла по указателю.
FILEGETNAME Выдает имя директории и имя файла
для заданного указателя BFILE.
FILEISOPEN Проверяет, открыт ли файл по BFILE-
указателю.
FILEOPEN Открывает файл для заданного
255
Раздел 3

BFILE-y казателя .
COPY Копирует LOB-объекты.
ERASE Удаляет объект полностью или час-
тично.
TRIM Обрезает LOB-объект до заданной
длины.

В качестве примера работы с BFILE-объектами с исполь-


зованием пакета DBMS_LOB приведем процедуру f_compare,
которая сравнивает файлы в каталоге Dirl. Имена файлов
передаются как параметры.

SQL> CREATE OR REPLACE PROCEDURE f_compare


2 (fnamel IN VARCHAR2, fname2 IN VARCHAR2) IS
3 fil_l BFILE;
4 fil_2 BFILE;
5 result INTEGER;
6 BEGIN
7 fil_l := BFILENAMECDIR1', fnamel);
8 fil_2 := BFILENAME('DIR1', fname2);
9 DBMS_LOB.FILEOPEN(f il_l);
10 DBMS_LOB.FILEOPEN(fil_2);
11 result:=DBMS_LOB.COMPARE(fil_l,fil_2,
12 4294967295,1,1);
13 IF (result != 0) THEN
14 DBMS_OUTPUT.PUT_LINE{'Файлы различные');
15 ELSE
16 DBMS_OUTPUT.PUT_LINE('Файлы одинаковые ');
17 END IF;
18 DBMS_LOB.FILECLOSEi
19 DBMS_LOB.FILECLOSEi
20 END;
21 /
Procedure created.

SQL> BEGIN
2 f_compare('fname.txt','fname.txt');
3 END;
4 /
256
PL/SQL — процедурное расширение языка SQL
Файлы одинаковые

SQL> BEGIN
2 f_compare('fname.txt','fname2.txt'};
3 END;
, 4 /
Файлы различные

SQL> BEGIN
2 f_compare('fname.txt','fnameS.txt');
3 END;
4. /
BEGIN
-*
ERROR at line 1:
ORA-22288: f i l e or LOB operation FILEOPEN failed
He удается найти указанный файл
ORA-06512: at "SYS.DBMS_LOB", line 475
ORA-06512: at "SYSTEM.F_COMPARE", line 9
ORA-06512: at line 2

Листинг 143. Пример работы с BFILE-объектами

При последнем вызове процедуры не удалось открыть


указанный файл. Обратите внимание, ошибка произошла при
попытке открыть файл. Установка же указателя на объект
BFILE произошла нормально.
Для загрузки файлов в таблицы как LOB-объекты предна-
значена специальная функция LOADFROMFILE пакета
DBMSJLOB. Функции в качестве параметров передается пе-
ременная типа BFILE, связанная с загружаемым файлом, ко-
личество байт, считываемое из файла и указатель на объект-
приемник. Пример загрузки файла в таблицу Tab! представ-
лен в листинге 144.

SQL> DECLARE
2 1_BLOB BLOB;
3 fil_l BFILE;
4 BEGIN
257
9. Заказ № 1628.

-
Раздел 3
.5 SELECT At2 INTO 1_BLOB FROM Tabl
6 WHERE At1=2 FOR UPDATE;
7 fil_l == BFILENAME( ' DIR1',. 'fname.txt') ;
8 DBMS_LOB.FILEOPEN(fil_l);
10 DBMS_LOB.LOADFROMFILE(1_BLOB,fil_l,
11 DBMS_LOB.GETLENGTH(fil_l));
12 COMMIT;
13 END;
14 /

PL/SQL procedure- successfully completed.

Листинг 144. Пример загрузки файлов в таблицу как


BLOB-значений

Обратите внимание, сначала объект, в который загружа-


ются данные из файла, блокируется с помощью SQL-
выражения SELECT FOR UPDATE, а затем функция
LOADFROMFILE осуществляет в него загрузку. В этом при-
мере блокировалось значение, предварительно проинициали-
зированное функцией EMPTY_CLOB() (строка с At 1=2). В
том случае, если блокировать строку, в которой значение
BLOB столбца равно NULL (строка с Atl=l) и попытаться
выполнить загрузку в него, то произойдет ошибка.
Остальные функции пакета DBMS_LOB предназначены
для чтения элементов, записи объектов, их сравнения и т. п.

Управление
многопользовательским доступом

, Сервер Oracle производит обработку данных в условиях


многопользовательского доступа. Транзакционная модель
Oracle, уровни изоляции, блокировка таблиц и строк обсуж-
даются в разделе "Методы обеспечения целостности данных.
Использование возможностей сервера по обеспечению совме-
стной работы с одними данными в программах на PL/SQL
имеет свои особенности. Как правило, программа должна за-
блокировать данные, над которыми она собирается произво-
258
PL/SQL — процедурное расширение языка SQL

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


блокировку не удается, то приложение либо выдает сообще-
ние пользователю о том, что необходимые для выполнения
операции данные заблокированы, либо выполняет преду-
смотренные в таком случае действия, например, через неко-
торый интервал времени пытается выполнить блокировку еще
раз. В некоторых средствах разработки клиентских приложе-
ний, например, в Oracle Form Builder, блокирование записей
производится автоматически.
Рассмотрим примеры реализации обработки данных в ус-
ловиях многопользовательского доступа в программе на язы-
ке PL/SQL. Для проведения массовых операций, связанных с,
модификацией данных, целесообразно заблокировать всю
таблицу с использованием оператора LOCK TABLE. В при-
мере в листинге 145 процедура lockjable пытается залокиро-
вать таблицу, сделав несколько попыток. Параметры проце-
дуры: количество попыток и время ожидания между ними в
секундах. Логика работы процедуры довольно прозрачна —
после очередной неудачной попытки заблокировать таблицу
оператором LOCK TABLE с опцией NOWAIT счетчик попы-
ток увеличивается и выдерживается пауза в заданное число
секунд (ожидание реализуется функцией SLEEP стандартного
пакета DBMS_LOCK). В случае превышения отведенного
числа попыток процедура завершает работу с выдачей соот-
ветствующего сообщения. Для унификации операции блоки-
рования таблиц данный пример можно доработать — переда-
вать в качестве параметра имя таблицы и выполнять оператор
LOCK TABLE с помощью динамического SQL.

SQL> CREATE OR REPLACE PROCEDURE


2 locktable (p__count NUMBER, p_time NUMBER) IS
3 a NUMBER := 0;
4 l_err NUMBER := 1;
5 BEGIN
6 WHILE l_err>0 AND a<=p_count LOOP
7 BEGIN
259
Раздел 3
8 а:=а+1;
9 LOCK TABLE Tab!
10 IN SHARE ROW EXCLUSIVE MODE NOWAIT;
11 l_err:=0;
12 EXCEPTION WHEN OTHERS THEN
13 IF SQLCODE IN (-54,-51) THEN
14 DBMS_LOCK,SLEEP(p_time);
15 ELSE
16 RAISE_APPLICATION_ERROR-(-
20001,'Блокировка неудачна');
17 END IF;
18 END;
19 END LOOP;
20
21 IF l_err>0 THEN
22 ~ RAISE_APPLICATION_ERROR(- '
20000,'Блокировка неудачна '};
23 END IF;
24
25 EXCEPTION WHEN OTHERS THEN
' 26 DBMS_OUTPUT.PUT_LINE('Произошла ошибка');
27 DBMS_OUTPUT.PUT_LINE(SQLERRM);
28 END;
29 /

Procedure created.

— пусть таблица Tab!


-- заблокирована другим приложением
SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE(SYSDATE);
3 locktable(5,5) ;
4 DBMS_OUTPUT.PUT_LINE(SYSDATE);
• 5 END;
6 /
12:09:01
Произошла ошибка
ORA-20000: Блокировка неудачна
12:09:31

PL/SQL procedure successfully completed.

Листинг 145. Пример функции, осуществляющей бло-


кировку таблицы
260
PL/SQL — процедурное расширение языка SQL

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


системах обработки данных, для которых требуется блоки-
ровка всей таблицы. Если же необходимо изменить отдель-
ную запись, следует использовать процедуру, подобную пред-
ставленной в листинге 146 процедуре p_update. Логика
работы процедуры p_update тоже довольно прозрачна — по-
сле блокирования строки (считаем, что возвращается всегда
ровно одна строка) происходит ее изменение. Если попытка
блокирования завершилась неудачно, выдается соответст-
вующее сообщение.

SQL> CREATE OR REPLACE PHOCEDURE


2 p_update(p_atl IN INTEGER,p_at2 IN' VARCHAR2)IS
ч3 " l_rowid ROWID;
4 locked EXCEPTION;
5 -PRAGMA EXCEPTION_INIT(locked,-54);
6 Locked2 EXCEPTION;
7 PRAGMA EXCEPTION_INIT(locked2,-51);
8 BEGIN
9 SELECT ROWID INTO l_rowid
10 FROM Tabl WHERE Atl=p_atl FOR UPDATE NOWAIT;
12 UPDATE Tabl SET At2=p_at2
13 WHERE ROWID = l_rowid;
14 EXCEPTION
Is WHEN locked THEN
16 DBMS_OUT PUT.PUT_LINE('Необходимые данные
заблокированы');
17 WHEN Iocked2 THEN
18 DBMSJDUTPUT.PUT_LINE('Необходимые данные
заблокированы ');
19 WHEN OTHERS THEN
20 DBMSJDUTPUT.PUT_LINE{'Произошла недиаг-
ност . ошибка ');
21 END;
22 /
Procedure created.

Листинг 146.-Пример функции, изменяющей запись с


предварительной ее блокировкой

261
Раздел 3

Использование функций PL/SQL


в SQL-выражениях

Начиная с версии Oracle 7.1, появилась возможность ис-


пользования пользовательских хранимых программ, отве-
чающих определенным требованиям, в SQL-выражениях. Вы-
зов этих программ внутри SQL-выражений ничем не отлича-
ется от вызова встроенных функций SQL. Как правило, эти
функции используются там, где требуется реализация слож-
ной логики с использованием управляющих структур (прове-
рок условий, циклов).
Наряду со стандартными требованиями к программам
PL/SQL, эти функции должны соответствовать еще ряду ог-
раничений. Ограничения на их реализацию указываются с
помощью так называемых спецификаций доступа или "уров-
ней чистоты", соответствие которым проверяется на этапе
компиляции или вызова. Кроме того, вызываемые функции
должны иметь параметры только типа IN. Спецификации дос-
тупа представлены в таблице 10.

Таблица 10. Спецификации доступа

Директива Ограничения
WNDS Функции запрещена модификация
данных в таблицах (представлениях)
базы данных.
WNPS Функции запрещена модификация
\
переменных, хранимых в пакетах.
RNDS Функции запрещено чтение данных
из таблиц и представлений базы дан-
ных.
RNPS Функции запрещено чтение значений
переменных, хранимых в пакетах.

262
PL/SQL — процедурное расширение языка SQL

Для автономных функций соответствие ограничениям


проверяется при их вызове в SQL-выражении. В том случае,
если функция не соответствует ограничениям, возникает
ошибка.
Для пакетных функций указание спецификаций доступа
производится с помощью конструкции PRAGMA
RESTRICT_REFERENCES. Она помещается в заголовке па-
кета совместно с объявлением функции. В качестве примера
можно привести функцию, которая осуществляет вывод сум-
мы прописью. Полностью привести ее исходный код не пред-
ставляется возможным в связи с его размером, представим
только результаты работы. При формировании результирую-
щей строки функция обращается к таблицам, в которых нахо-
дятся справочные данные, поэтому соответствует только
уровню WNDS.

SQL> CREATE OR REPLACE PACKAGE p_sum_as_string AS


2 FUNCTION str(p_sum IN NUMBER) RETURN VARCHAR2;
3 PRAGMA RESTRICT_REFERENCES (str,WNDS);
4 END;
5 /
Package created.

SQL> SELECT Atl, p_sum_as_string.str(Atl) str


2 FROM tabl;

ATI STR

10.34 Десять рублей 34 коп.


745.23 Семьсот сорок пять рублей 23 коп.

Листинг 147. Пример работы пользовательской функ-


ции в SQL-выражении

263
Раздел 4

Средства разграничения
доступа в Oracle

Современный уровень развития распределенной обработ-


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

264
Средства разграничения доступа в Oracle

личные средства разграничения доступа, реализованные в


Oracle.
Задача распознавания пользователей и разграничения
доступа между различиями пользователями системы решает-
ся как на уровне средств операционной системы, так и на
уровне средств СУБД. Стандартным подходом, характерным
для обоих уровней, является деятельность администраторов,
которые создают (регистрируют) пользователей в системе и
управляют назначением привилегий. С другой стороны всякая
система должна поддерживать естественный порядок, при
котором пользователь, создающий некоторый объект, имеет
право на управление доступом к этому объекту. Обычное ре-
шение состоит в реализации концепции привилегии или права
доступа. Привилегия — это некоторый поддерживаемый сис-
темой признак, который определяет, может ли конкретный
пользователь выполнить конкретную операцию. Имеется не-
сколько типов привилегий, соответствующих нескольким ти-
пам операций. В языке SQL — базовом языке промышленных
СУБД — привилегии определяются и отменяются двумя ко-
мандами: GRANT (предоставить привилегию) и REVOKE
(отменить привилегию).
Чтобы предоставить кому-либо доступ к базе данных
Oracle, администратор должен обеспечить глобальную дос-
тупность базы данных, создать в базе данных соответствую-
щего пользователя (определив его учетную запись) и предос-
тавить пользователю определенные полномочия по доступу к
объектам базы. Обеспечение правомерности доступа пользо-
вателя реализуется средствами аутентификации, простейшим
из которых является использование пароля, подтверждающе-
го подлинность пользователя. Для подключения к базе дан-
ных пользователь должен ввести свое имя и пароль. Обычно
администратор выбирает осмысленные имена пользователей
(например, объединяя имя и фамилию) и не несущие никако-
го смысла пароли.
В Oracle реализована поддержка принципа "безопасности
по умолчанию" или принципа "наименьших привилегий".
265.
Раздел 4

Суть принципа состоит в том, что пользователь может полу-


чить доступ к объекту базы данных (например, таблице или
представлению) или выполнить определенные действия в сис-
теме (например, создать нового пользователя), только если
ему это явно разрешено.
В разделе рассмотрены следующие основные программ-
ные решения по обеспечению безопасности информации, ко-
торые реализованы в СУБД Oracle:
— анализ включающей инфраструктуры;
— технологии аутентификации;
— статические средства разграничения доступа;
— динамические средства разграничения доступа;
— средства аудита;
— средства управления нагрузкой.

Анализ включающей
инфраструктуры
Любой сервер баз данных работает под управлением не-
которой операционной системы, поэтому первым шагом ана-
лиза защищенности информации в базах данных должен быть
анализ защищенности ресурсов сервера баз данных как объ-
ектов операционной системы. Система безопасности сервера
баз данных включает как внешние по отношению к серверу
средства (в первую очередь средства операционной системы),
так и собственные механизмы сервера. Верхний уровень за-
щиты информации базы данных состоит в контроле принци-
пиальной возможности доступа к данным. Прежде чем нач-
нется работа с базой данных, администратор должен выпол-
нить некоторые действия по инициализации сервера. Никакой
пользователь не может использовать данные, пока обладаю-
щий соответствующими правами администратор не запустит
сервер и не сделает базу данных доступной. В терминологии
Oracle администратор должен запустить экземпляр (instance)

266
Средства разграничения доступа в Oracle

сервера базы данных. В ходе запуска экземпляра базы данных


Oracle открывает определенные файлы операционной систе-
мы, необходимые для того, чтобы сделать базу данных дос-
тупной.
Для операционных систем Windows NT или Windows
2000 запуск экземпляра может быть выполнен утилитой
svrmgrSO. Пример запуска экземпляра представлен в листинге
148.

С: \orant>svrmgr30
Oracle Server Manager Release 3.0»5.0.0 - Produc-
tion
(c) Copyright 1997, Oracle Corporation. All
Rights Reserved.
OracleS Enterprise Edition Release 8.0.5.0.0 -.
Production
PL/SQL Release 8.0.5.0.0 - Production
SVRMGR> connect internal
Password:
Connected.
SVRMGR>startup
ORACLE instance started.
Total System Global Area 15077376 bytes
Fixed Size - 49152 bytes
Variable Size 12906496 bytes
Database Buffers 2.048000 bytes
Redo Buffers 73728 bytes
Database mounted.
Database opened.
SVRMGR>exit
Server Manager complete.

Листинг 148. Протокол запуска экземпляра Oracle


на Windows 2000

После запуска администратором экземпляра базы данных


и ее открытия пользователи могут присоединяться к базе дан-
ных. Завершая работу с базой данных, администратор раз-
монтирует ее, отсоединяя от экземпляра, а затем останавлива-
267
Раздел 4

ет экземпляр. В процессе останова сервера базы данных


Oracle завершает запущенные процессы и закрывает файлы
операционной системы, в которых хранится информация базы
данных. Для систем Windows NT и Windows 2000 останов
экземпляра осуществляется утилитой svrmgrSO. Пример оста-
нова экземпляра представлен в листинге 149.

С:\orant>svrmgr30
Oracle Server Manager Release 3 . 0 . 5 . 0 . 0 - Produc-
tion
( c ) Copyright 1997, Oracle Corporation. All
Rights Reserved.
OracleB Enterprise Edition Release 8 . 0 . 5 . 0 . 0 -
Production
PL/SQL Release 8 . 0 . 5 . 0 . 0 - Production
SVRMGR> connect internal
Password:
Connected.
SVRMGR>shutdown
Database closed.
Database dismounted.
ORACLE instance shut down.
SVRMGR>exit
Server Manager complete.

Листинг 149. Протокол останова экземпляра Oracle


на Windows 2000

Естественно, что перечень администраторов Oracle,


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

нистратор делает невозможным использование данных из


табличной области для всех пользователей.
Перевод табличной области в автономное (то есть недо-
ступное для пользователей) выполняется командой ALTER
TABLESPACE. Той же командой, естественно, с другими па-
раметрами выполняется обратная операция, переводящая таб-
личную область в состояние, когда пользователи могут обра-
щаться к данным, размещенным в ней.
Обычно перевод табличной области в автономное со-
стояние используется для резервного копирования данных. В
то же время с позиций обеспечения безопасности данных
управление доступностью табличных областей Oracle может
оказаться полезным для решения задач разграничения досту-
па. Например, если таблицы некоторого приложения находят-
ся в конкретной табличной области, то администратор может
эффективно запретить работу приложения, переведя соответ-
ствующую табличную область в автономное состояние. Более
конкретно, пусть табличная область содержит данные, доступ
к которым требуется достаточно редко, но данные важные
(архивные данные). Администратор может эффективно за-
прещать доступ к этим данным, поддерживая соответствую-
щую табличную область в автономном состоянии. При полу-
чении распоряжения о проведении обработки данных адми-
нистратор переводит табличную область в оперативное со-
стояние, и пользователи могут выполнять доступные им при-
ложения по обработке данных из этой табличной области.
Пример, приведенный в листинге 150, иллюстрирует пе-
ревод в автономное и оперативное состояние табличной об-
ласти APP_DATA. Предполагается, что команды управления
табличной областью выполняются пользователем, обладаю-
щим необходимыми привилегиями. Попытка выполнить вы-
борку данных из таблицы ТаЬ2, размещенной в табличной
области APP_DATA, приводит к сообщению о невозможнос-
ти выполнить операцию. После перевода табличной области в
оперативный режим операция выборки выполняется.

269
Раздел 4

ALTER TABLESPACE USER_DATA OFFLINE NORMAL;


Tablespace altered.

SQL> SELECT * FROM TAB2;

SELECT * FROM TAB2 *


ERROR at line I:
ORA-00376: file 5 cannot be read at this time
ORA-01110: data file 5:
1
с:\orant\database\appdata:dbf'
,

SQL> ALTER TABLESPACE USER_DATA ONLINE;


Tablespace altered.

SQL> SELECT * FROM TAB2;

ATI

12

Листинг 150. Пример управления доступностью таб-


личной области Oracle

Похожим средством защиты данных от преднамеренного


или случайного изменения является возможность перевода
табличной области в состояние только для чтения (read only).

Идентификация пользователей
Каждый пользователь Oracle должен иметь специальный
идентификатор: имя или точку входа. Создание нового иден-
тификатора осуществляется уполномоченным пользователем
или администратором выполнением предложения CREATE
USER (подробно описанного выше).
С позиций системы источники, предъявившие иденти-
фикатор, неразличимы. То есть, хотя пользователем может
быть как реальный человек, сидящий за терминалом, так и
прикладной процесс, для системы оба объекта тождественны.
270
Средства разграничения доступа в Oracle

Вновь созданный пользователь не имеет никаких прав на вы-


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

GRANT CREATE SESSION TO имя_пользователя;

Протокол взаимодействия с системой Oracle представлен


в листинге 151.

SQL> CONNECT SYSTEM/MANAGERSEDUC;


Connected.

SQL> CREATE USER Ul IDENTIFIED BY U1PSW;


User created.

SQL> CONNECT U1/U1PSW0EDUC;


ERROR: ORA-01017: invalid username/password;
logon denied
Warning: You are no longer connected to ORACLE.

SQL> CONNECT SYSTEM/MANAGERSEDUC;


Connected.

SQL> GRANT CREATE SESSION TO Ul;


Grant succeeded.

SQL> CONNECT U1/U1PSW0EDUC;


Connected.

Листинг 151. Регистрация пользователя в Oracle и


предоставление ему минимальных прав доступа

271
Раздел 4

Когда пользователь пытается подключиться к базе дан-


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

Базовое понятие системы


разграничения доступа —-
привилегии
Привилегия (privilege) — это разрешение на выполнение
в системе определенного действия. Не имея соответствующей
привилегии, пользователь не может получить доступ к дан-
ным или выполнить какое-либо действие.
Сервер базы данных поддерживает для каждого пользо-
вателя набор привилегий. Привилегии этого набора могут из-
меняться: назначаться новые или отменяться старые. Множе-
ство базовых привилегий определено в стандарте ANSI SQL.
Помимо этого в Oracle реализованы некоторые дополнитель-
ные привилегии (всего поддерживается более 70 типов).
Основой системы разграничения доступа в Oracle являет-
ся реализация принципа минимальных привилегий. Суть дан-
ного принципа, состоит в том, что пользователю должно быть
явно разрешено выполнение каждого действия в системе.
Все привилегии могут быть разделены на два класса: сис-
темные привилегии (system privelege) и привилегии доступа к
объектам (object privelege).
Системная привилегия — это привилегия, которая дает
пользователю право на выполнение какой-либо операции в
272 -
Средства разграничения доступа в Oracle

масштабе базы данных. Например, пользователь с системной


привилегией ALTER TABLESPACE может изменять любую
табличную область (за исключением некоторых ограничений
на табличную область SYSTEM). Пользователь с системной
привилегией SELECT ANY TABLE может выполнять выбор-
ку из любой таблицы базы данных. Поскольку системные
привилегии связаны с возможностью выполнения глобальных
изменений в базе данных, их предоставление должно тща-
тельно планироваться.
Привилегия доступа к объекту — это разрешение поль-
зователю на выполнение определенной операции над опреде-
ленным объектом, например выполнение выборки из не-
которой таблицы. При этом пользователь может формировать
любые запросы к данной таблице, но не имеет права модифи-
цировать данные этой таблицы или формировать какой-либо
запрос к другой таблице.
Привилегия доступа к объекту базы управляют работой
пользователя базы данных с конкретным объектом. Напри-
мер, администратор может управлять списком пользователей,
которые имеют право выполнять выборку из конкретной таб-
лицы. Для этого он предоставляет привилегии SELECT на эту
таблицу конкретным пользователям или ролям. Аналогично
можно предоставить на таблицу полномочия INSERT,
UPDATE, DELETE. Механизм привилегий доступа к объекту
дает администратору возможность детально управлять досту-
пом к информации базы данных.
В завершение темы необходимо отметить важный прин-
цип: в своей схеме (с объектами, владельцем которых являет-
ся пользователями) разрешены любые операции, т.е. со свои-
ми таблицами, представлениями, хранимыми программами и
т. п. пользователь волен делать что угодно. Если привилегий
оказалось достаточно, чтобы создать объекты, то даже после
отмены привилегий пользователь по-прежнему сможет про-
изводить любые действия с уже существующими объектами.
По этой причине отсутствуют системные привилегии
DROP TABLE, DROP VIEW и т. п. (существуют DROP ANY
273

'
Раздел 4

TABLE, DROP ANY VIEW). Различие между привилегиями, в


названиях которых присутствует/отсутствует ключевое слово
ANY, как правило, заключается в том, что в первом случае
при наличии привилегии можно производить действия с объ-
ектами и в других схемах, а во втором — только в своей.
Этот принцип можно использовать для построения защи-
ты, например, создав все объекты приложения в одной схеме
и отменив пользователю-владельцу привилегию CREATE
SESSION (остальным пользователям и ролям явно предоста-
вив необходимые привилегии). В этом случае гарантируется
отсутствие доступа ко всем данным приложения сразу (есте-
ственно, при ограниченном использовании системных приви-
легий вроде SELECT ANY TABLE и системных учетных за-
писей).

Предоставление системных
привилегий
Системные привилегии могут быть предоставлены серве-
ром Oracle двум объектам системы: пользователям (USER) и
ролям (ROLE). Роль представляет собой поименованный на-
бор привилегий. Назначение и языковые средства определе-
ния ролей будут рассмотрены ниже.
Для предоставления системных привилегий пользовате-
лю в соответствии с требованиями стандарта используется
команда GRANT. Пользователь, выдавший команду GRANT,
должен обладать системной привилегией GRANT ANY
PRIVILEGE. Оператор определения системных привилегий
Oracle использует следующий синтаксис:

GRANT системная_привилегия
[{,системная_привилегия }. . .]
ТО {пользователь \ PUBLIC} [{, пользователь }...]
[WITH ADMIN OPTION]

274
Средства разграничения доступа в Oracle

Список значений, которые может принимать параметр


системная_привилегия, приведен в представленных ниже
таблицах. Системные привилегии сгруппированы по объ-
ектам Oracle. Список не является исчерпывающим, полный
список может быть взят из документа "Oracle Server SQL
Reference".

Системные привилегии, определяющие права


по работе с таблицами и представлениями

Для работы с таблицами и представлениями в Oracle пре-


дусмотрены следующие системные привилегии:

Таблица 11. Обозначение и сущность системных при-


вилегий Oracle, связанных с работой с таб-
лицами и представлениями

Системная Разрешаемые системной


привилегия привилегией действия
CREATE Разрешает пользователю создавать таблицу
ANY TABLE в любой схеме базы данных. Для создания
таблицы необходима привилегия на квоту
пространства в табличной области, где соз-
дается таблица.
CREATE Разрешает пользователю создавать таблицу
TABLE в собственной схеме базы данных. Для- соз-
дания таблицы необходима привилегия на
квоту пространства в табличной области,
где она создается.
DROP ANY Разрешает пользователю уничтожать лю-
TABLE бую таблицу в любой схеме базы данных.
ALTER ANY Разрешает пользователю изменять таблицу
TABLE в любой схеме базы данных.
INSERT ANY Разрешает пользователю вставку строк в
TABLE любую таблицу или представление любой

275
Раздел 4

схемы базы данных.


UPDATE Разрешает пользователю модифицировать
ANY любые строки в любой таблице или пред-
TABLE ставлении любой схемы базы данных.
DELETE Разрешает пользователю удалять любые
ANY строки в любой таблице или представлении
TABLE любой схемы базы данных.
SELECT Разрешает пользователю выполнять произ-
ANY вольную выборку из любой таблицы, пред-
TABLE ставления или снимка любой схемы базы
данных.
LOCK ANY Разрешает пользователю выполнять бло-
TABLE кировку любой таблицы любой схемы базы
данных.
BACKUP Разрешает пользователю применять утили-
ANY ту Export в инкрементальном режиме для
TABLE таблиц из любой схемы базы данных.
COMMENT Разрешает пользователю вносить коммен-
ANY тарии в словарь данных для любого столб-
TABLE ца любой таблицы в любой схеме базы дан-
ных.

Рассмотрим пример. Пусть пользователю U1 предостав-


лена системная привилегия CREATE TABLE. Команда со-
здания таблицы Tab! проходит успешно. Попытка создать
таблицу Tab! в схеме пользователя U2 отвергается системой.
После предоставления привилегий CREATE ANY TABLE
предыдущая операция выполняется успешно.
Протокол взаимодействия с системой Oracle, иллюстри-
рующий пример, приведен в листинге 152:

SQL> CONNECT U1/U1PSW@EDUC;


Connected.

276
Средства разграничения доступа в Oracle
SQL> CREATE TABLE T a b l ( A t 1 NUMBER);
Table created.

SQL> CREATE TABLE U 2 . T a b l ( A t l NUMBER);


CREATE TABLE U 2 . T a b l ( A t l NUMBER)
*
ERROR at line 1: ORA-01031: i n s u f f i c i e n t privi-
leges

SQL> CONNECT SYSTEM/MANAGER@EDUC;


Connected.

SQL> GRANT CREATE ANY TABLE TO Ul;


Grant succeeded.

SQL> CONNECT U1/U1PSW8EDUC;


Connected. 1
-
SQL> CREATE TABLE U 2 . T a b l ( A t l NUMBER);
Table created.

Листинг 152. Пример использования привилегий на


создание таблицы

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


стоящий в том, что пользователь U1, создавший таблицу Tab!
в схеме U2, не имеет никаких прав на операции с данной таб-
лицей. Пользователь U2 может выполнять выборку из табли-
цы Tabl, а пользователь U1 — нет. Разрешение на выполне-
ние конкретной операции должно быть предоставлено явно.
После того как администратор предоставил глобальное раз-
решение на выборку пользователю U1, первоначально запре-
щаемая операция выборки проходит успешно. Листинг 153
содержит протокол для данного примера, иллюстрирующего
принцип минимальных привилегий, реализованный в Oracle:

SQL> CONNECT U1/U1PSW@EDUC;


Connected.

277
Раздел 4

•SQL> SELECT * FROM U2.Tabl;


SELECT * FROM U2.Tabl
*
ERROR at line 1: ORA-01031: insufficient privi-
leges
SQL> CONNECT U2/U2PSW0EDUC;
Connected.

SQL> SELECT * FROM Tabl;


no rows selected

SQL> CONNECT SYSTEM/MANAGERSEDUC;


Connected.
SQL> GRANT SELECT ANY TABLE TO Ul;
Grant succeeded.

SQL> SELECT * FROM U2.Tabl;


no rows selected

Листинг 153. Пример использования привилегий для


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

Дополнительно только для представлений в Oracle преду-


смотрены следующие системные привилегии:

Таблица 12. Обозначение и сущность дополнительных


системных привилегий Oracle, связанных
исключительно с работой с представлениями
Системная Разрешаемые системной
привилегия привилегией действия
CREATE Разрешает пользователю создавать пред-
ANY VIEW ставление в любой схеме базы данных.
CREATE Разрешает пользователю создавать пред-
VIEW ставление в собственной схеме базы дан-
ных.
DROP ANY Разрешает пользователю уничтожать любое
VIEW представление в любой схеме базы данных.

278
Средства разграничения доступа в Oracle

Системные привилегии,
определяющие права по работе
с процедурами и триггерами

Для работы с процедурами в Oracle предусмотрены сле-


дующие системные привилегии:

Таблица 13. Обозначение и сущность системных при-


вилегий Oracle, связанных с работой с про-
цедурами

Системная Разрешаемые системной


привилегия привилегией действия
CREATE ANY Разрешает пользователю создавать хра-~
PROCEDURE нимую процедуру, функцию или пакет в
любой схеме базы данных.
DROP ANY Разрешает пользователю уничтожать хра-
PROCEDURE нимую процедуру, функцию или пакет в
любой схеме базы данных.
EXECUTE Разрешает пользователю выполнять лю-
ANY бую хранимую процедуру или функцию,
PROCEDURE как входящую в состав пакета, так и оди-
ночную, и ссылаться на любой элемент
спецификации пакета из любой схемы ба-
зы данных.
ALTER ANY Разрешает пользователю изменять любую
PROCEDURE хранимую процедуру, функцию или пакет
из любой схемы базы данных.

Рассмотрим пример. Пусть пользователь U1 создал про-


цедуру InsRec, выполняющую вставку записи в таблицу Tab!
и представленную в листинге 154. Попытка выполнить эту
процедуру пользователем U2 отвергается системой. После
предоставления администратором привилегии EXECUTE
ANY PROCEDURE пользователю U2 запуск процедуры про-
279
Раздел 4

ходит успешно. Обратите внимание на то, что явная вставка


(не через процедуру) строк в таблицу ТаЬ2 пользователю U2
не разрешена.

SQL> CONNECT U2/U2PSW0EDUC;


Connected.
SQL> BEGIN
2 Ul.InsRec(lll);
3 END;
4 /
BEGIN Ul.InsRec(l-ll) ; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'Ul.INSREC' must be de-
clared '
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

SQL> CONNECT SYSTEM/MANAGER@EDUC;


Connected.

.SQL> GRANT EXECUTE ANY PROCEDURE TO U2;


Grant succeeded.

SQL> CONNECT U2/U2PSW0EDUC;


Connected.

SQL> BEGIN
2 Ul.InsRec(lll);
3 END;
4 / •

PL/SQL procedure successfully completed.

SQL> INSERT INTO Ul.Tabl VALUES(100);


INSERT INTO Ul.Tabl VALUES(100)
*
ERROR at line 1:
ORA-00942: table or view does not exist

280
Средства разграничения доступа в Oracle
SQL> CONNECT U1/U1PSW8EDUC;
Connected.

SQL> SELECT * FROM Tabl;

ATI . AT2

5.5 05-04-2002

Листинг 154. Пример, иллюстрирующий предоставле-


ние системных привилегий по выполнению про-
цедур

Симметричные системные привилегии предусмотрены


для работы с триггерами базы данных.

Таблица 14. Обозначение и сущность системных при-


вилегий Oracle, связанных с работой с триг-
герами баз данных

Системная Разрешаемые системной


привилегия привилегией действия
CREATE ANY Разрешает пользователю создавать триг-
TRIGGER гер базы данных в любой схеме базы дан-
ных, ассоциированный с таблицей любой
схемы.
CREATE Разрешает пользователю создавать триг-
TRIGGER гер базы данных в собственной схеме ба-
зы данных.
DROP ANY Разрешает пользователю уничтожать про-
TRIGGER извольный триггер в любой схеме базы
данных.
ALTER ANY Разрешает пользователю изменять любой
TRIGGER триггер из любой схемы базы данных.

281
Раздел 4

Системные привилегии,
определяющие права по работе
с пользователями

Для работы с пользователями в Oracle предусмотрены


следующие системные привилегии:

Таблица 15. Обозначение и сущность системных при-


вилегий Oracle, определяющих права по рабо-
те с пользователями

Системная Разрешаемые системной


привилегия привилегией действия
CREATE USER Разрешает создавать нового пользователя.
Данная привилегия позволяет определять
квоту в табличном пространстве, опреде-
лять табличное пространство по умолча-
нию и временное табличное пространство,
а также определять профиль пользовате-
ля.
DROP USER Разрешает пользователю уничтожать лю-
бых пользователей базы данных.
ALTER USER Разрешает пользователю изменять харак-
теристики пользователя, в частности, из-
менять пароль или метод аутентификации,
переопределять любую квоту в табличном
пространстве, переопределять табличное
пространство по умолчанию и временное
табличное пространство, а также переоп-
ределять профиль пользователя.
BECOME Разрешает пользователю регистрировать-
USER ся в системе как другой пользователь.

Наличие привилегии создания пользователя никак не свя-


зано с возможностью предоставления созданному пользова-

282
Средства разграничения доступа в Oracle
телю каких-либо прав. Приведенный ниже пример показыва-
ет, что пользователь Ш, обладая соответствующей привиле-
гией, успешно создал пользователя U2, но предоставить ему
минимальное право создания сессии не может.

SQL> CONNECT SYSTEM/MANAGEReEDUC .


Connected.
SQL> GRANT CREATE USER TO Ul;
Grant succeeded.

SQL> CONNECT U1/U1PSW@EDUC;


Connected.
SQL> CREATE USER U2 IDENTIFIED BY U2PSW;
User created.
SQL> GRANT CREATE SESSION TO U2;
GRANT CREATE SESSION TO U2
*
ERROR at line 1:
ORA-01031: i n s u f f i c i e n t privileges

Листинг* 155. Пример, иллюстрирующий предоставле-


ние .системных привилегий по созданию поль-
зователя

Системные привилегии,
определяющие права по работе
с табличными областями
Особенность привилегии MANAGE TABLESPACE со-
стрит в ее ориентации на управление состоянием табличной
области. Спецификой табличной области является возмож-
ность ее перевода в автономное или оперативное состояние.
Пользователю может быть предоставлена привилегия по
управлению табличной рбластью, но не более сильные при-
вилегии, связанные с изменением табличной области, напри-
мер привилегия добавления файла для хранения данных.
283
Раздел 4

Для работы с табличными областями в Oracle предусмот-


рены следующие системные привилегии.

Таблица 16. Обозначение и сущность системных при-


вилегий Oracle, связанных с работой с таб-
личными областями
Системная Разрешаемые системной
привилегия привилегией действия
CREATE Разрешает пользователю создавать таб-
TABLESPACE личную область.
DROP Разрешает пользователю уничтожать
TABLESPACE любую табличную область, кроме таб-
личной области SYSTEM.
ALTER Разрешает пользователю изменять лю-
TABLESPACE бую табличную область.
MANAGE Разрешает пользователю переводить таб-
TABLESPACE личные области в оперативное (online) и
автономное (offline) состояние и вы-
полнять резервное копирование таблич-
ной области.
UNLIMITED Разрешает пользователю задействовать
TABLESPACE произвольную часть табличного про-
странства. Данная привилегия перекры-
вает любые ограничения на допустимые
квоты пространства табличной области.
Привилегия не применима к ролям.

SQL> CONNECT SYSTEM/MANAGER@EDUC


Connected.

SQL> GRANT MANAGE TABLESPACE TO Ul;


Grant succeeded.

SQL> CONNECT U1/U1PSWSEDUC ;


Connected.

284
Средства разграничения доступа в Oracle
SQL> ALTER TABLESPACE APP_DATA OFFLINE NORMAL;
Tablespace altered.

SQL> ALTER TABLESPACE APP_DATA


2 ADD DATAFILE ' appdata.2 . d b f ' ;
ALTER TABLESPACE APP_DATA ADD DATAFILE
'appdata2.dbf~'
*
ERROR at line 1:
ORA-01031: i n s u f f i c i e n t privileges

SQL> ALTER TABLESPACE APP_DATA ONLINE; :


Tablespace altered.

Листинг 156. Пример, иллюстрирующий предоставле-


ние системных привилегий по управлению таб-
личной областью

Системные привилегии,
определяющие права по работе с
последовательностями

Дня работы с последовательностями в Oracle предусмот-


рены следующие системные привилегии.

Таблица 17. Обозначение и сущность системных при-


вилегий Oracle, связанных с работой с по-
следовательностями
Системная Разрешаемые системной
привилегия привилегией действия
CREATE ANY Разрешает пользователю создавать произ-
SEQUENCE вольную последовательность в любой
схеме.
CREATE Разрешает пользователю создавать после-
SEQUENCE довательность в собственной схеме базы
данных.
DROP ANY Разрешает пользователю уничтожать про-
SEQUENCE извольную последовательность в любой
схеме.
285

- -
'
Раздел 4

ALTER ANY Разрешает пользователю изменять пара-


SEQUENCE метры произвольной последовательности
в любой схеме.
SELECT ANY Разрешает пользователю вычислять зна-
SEQUENCE чения последовательности из любой схе-
мы базы данных.

Системные привилегии,
определяющие права по работе
с синонимами

Для работы с синонимами в Oracle предусмотрены сле-


дующие системные привилегии:

Таблица 18, Обозначение и сущность системных при-


вилегий Oracle, связанных с работой с сино-
нимами

Системная Разрешаемые системной


привилегия привилегией действия
CREATE ANY Разрешает пользователю создавать си-
SYNONYM ноним в любой схеме базы данных.
CREATE Разрешает пользователю создавать об-
PUBLIC щие синонимы базы данных.
SYNONYM
CREATE Разрешает пользователю создавать си-
SYNONYM ноним в собственной схеме базы дан-
ных.
DROP ANY Разрешает пользователю уничтожать
SYNONYM синоним базы данных.
DROP PUBLIC Разрешает пользователю уничтожать
SYNONYM общие синонимы базы данных.

Реализация синонимов в Oracle корректно поддерживает


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

286
Средства разграничения доступа в Oracle

право создания синонима, не может выполнить действие с


объектом, скрытым за этим синонимом, если явно ему не пре-
доставлены соответствующие привилегии. Пользователь U1,
создав общий синоним таблицы Tab! из схемы U2, делает
попытку выполнять выборку из таблицы ТаЫ, скрытой под
общим синонимом Tabx. Система отвергает попытку, отмечая
недостаток привилегий у пользователя U1. Листинг 157 со-
держит протокол для данного примера:

SQL> Connect SYSTEM/MANAGERSEDUC;


Connected.

SQL> GRANT CREATE PUBLIC SYNONYM TO Ul;


Grant succeeded.

SQL> CONNECT U1/U1PSWQEDUC;


Connected.

SQL> SELECT * FROM U2.Tabl,"


SELECT * FROM U2.Tabl
*
ERROR in line 1:
ORA-01031: insufficient privileges

SQL> CREATE'PUBLIC SYNONYM Tabx FOR U2.Tabl;


Synonym created.

SQL> SELECT * FROM Tabx;


SELECT * FROM Tabx
*
ERROR in line 1:
ORA-01031: insufficient privileges

Листинг1 157. Протокол примера использования сино-


нима для выборки из таблицы

287
Раздел 4

Системные привилегии,
определяющие права по выполнению
глобальных действий в системе

Для управления глобальными операциями в системе в


Oracle предусмотрены следующие системные привилегии:

Таблица 19. Обозначение и сущность системных при-


вилегий Oracle, связанных с управлением
глобальными операциями

Системная Разрешаемые системной


привилегия привилегией действия
GRANT ANY Предоставляет пользователю все системные
PRIVILEGE привилегии. Использование такой команды
(как и ее наличие) представляется неоправ-
данным в системе с серьезными требова-
ниями по безопасности данных.
CREATE Разрешает пользователю создавать сессию.
SESSION Минимальная привилегия для выполнения
какой-либо работы с базой данных.
AUDIT ANY Разрешает пользователю проведение аудита
любого объекта системы в любой схеме.
AUDIT Разрешает пользователю выполнение ко-
SYSTEM манды AUDIT для проведения аудита сис-
темных событий.

Системные привилегии, определяющие права


по выполнению действий
с остальными объектами базы данных

Для управления действиями с остальными объектами ба-


зы данных в системе в Oracle предусмотрены следующие сис-
темные привилегии:

288
Средства разграничения доступа в Oracle
Таблица 20. Обозначение и сущность системных при-
вилегий Oracle, связанных- с управлением
действиями с остальными объектами базы дан-
ных

Системная Разрешаемые системной


привилегия привилегией действия
CREATE Разрешает пользователю создавать кла-
ANY CLUSTER стеры в любой схеме базы данных.
CREATE Разрешает пользователю создавать кла-
CLUSTER стеры в своей схеме базы данных.
ALTER Разрешает пользователю изменять кла-
ANY CLUSTER стеры в любой схеме базы данных.
DROP ANY Разрешает пользователю уничтожать
CLUSTER кластеры в любой схеме базы данных.
CREATE INDEX Разрешает пользователю создавать ин-
дексы в собственной схеме базы данных.
CREATE Разрешает пользователю создавать ин-
ANY INDEX дексы в любой схеме базы данных.
ALTER Разрешает пользователю изменять лю-
ANY INDEX бой индекс в любой схеме базы данных.
DROP Разрешает пользователю уничтожать
ANY INDEX индексы в любой схеме базы данных.
CREATE Разрешает пользователю создавать биб-
LIBRARY лиотеки внешних процедур в собствен-
ной схеме базы данных.
CREATE Разрешает пользователю создавать биб-
ANY LIBRARY лиотеки внешних процедур в любой
схеме базы данных.
DROP Разрешает пользователю уничтожать
ANY LIBRARY библиотеки внешних процедур в любой
схеме базы данных.
CREATE Разрешает пользователю создавать
ANY снимки в любой схеме базы данных.
SNAPSHOT

289
10. Заказ № 1628.
Раздел 4

CREATE Разрешает пользователю создавать


SNAPSHOT снимки в ообственной схеме.
ALTER Разрешает пользователю изменять сним-
ANY ки в любой схеме базы данных.
SNAPSHOT
DROP Разрешает пользователю уничтожать
ANY снимки в любой схеме базы данных.
SNAPSHOT
CREATE Разрешает пользователю создавать объ-
ANY TYPE ектные типы в любой схеме.
CREATE TYPE Разрешает пользователю создавать объ-
ектные типы в собственной схеме.
ALTER Разрешает пользователю изменять объ-
ANY TYPE ектные типы в любой схеме.
DROP ANY Разрешает пользователю уничтожать
TYPE объектные типы в любой схеме.
EXECUTE Разрешает пользователю ссылаться на
ANY TYPE любой объектный тип и его методы.
CREATE Разрешает пользователю создавать про-
PROFILE фили.
ALTER Разрешает пользователю изменять про-
PROFILE фили.
DROP PROFILE Разрешает пользователю уничтожать
профили.
CREATE Разрешает пользователю создавать сег-
ROLLBACK менты отката,
SEGMENT
ALTER Разрешает пользователю _ изменять сег-
ROLLBACK менты отката.
SEGMENT
DROP Разрешает пользователю уничтожать
ROLLBACK сегменты отката.
SEGMENT
CREATE ANY Разрешает пользователю создавать ката-
DIRECTORY логи в собственной схеме.

290
Средства разграничения доступа в Oracle

DROP ANY Разрешает пользователю создавать ката-


DIRECTORY логи в любой схеме.
CREATE Разрешает пользователю создавать связи
DATABASE с удаленными базами данных.
LINK
CREATE Разрешает пользователю создавать об-
PUBLIC щедоступные связи с удаленными база-
DATABASE ми данных.
LINK
DROP PUBLIC Разрешает пользователю уничтожать
DATABASE общедоступные связи с удаленными ба-
LINK зами данных.
ALTER Разрешает пользователю изменять стои-
RESOURCE мость использования ресурсов системы.
COST
ALTER Разрешает пользователю изменять со-
DATABASE стояние базы данных с помощью опера-
тора ALTER DATABASE.
ALTER Разрешает пользователю изменять со-
SESSION стояние сессии с помощью оператора
ALTER SESSION.
ALTER SYSTEM Разрешает пользователю изменять со-
стояние системы с помощью оператора
ALTER SYSTEM.
ANALYZE ANY Разрешает пользователю производить
сбор статистики для таблиц, кластеров и
индексов в любой схеме.
FORCE ANY Разрешает пользователю производить
TRANSACTION принудительную фиксацию или откат
любой сомнительной распределенной
транзакции.
FORCE Разрешает пользователю производить
TRANSACTION принудительную фиксацию или откат
сомнительной распределенной транзак-
ции.

291
10*
Раздел 4

Использование конструкции PUBLIC и


параметра WITH ADMIN OPTION

Конструкция PUBLIC используется для предоставления


конкретной системной привилегии всем пользователям сис-
темы. Заметим, что передача системных привилегий всем
пользователям в системе с серьезными требованиями по за-
щите информации обычно не используется.
Рассмотрим пример, в котором пользователь U1, создав
последовательность Seql, предоставляет привилегию выпол-
нения операции выборки всем пользователям системы. Обра-
тите внимание, что привилегия автоматически предоставляет-
ся пользователю U3, который создается позже, чем определе-
на привилегия по доступу к последовательности Seql.
Листинг 158 содержит протокол для данного примера,
иллюстрирующего особенности предоставления глобальных
привилегий объектам Oracle:

SQL> CONNECT U1/U1PSW0EDUC;


Connected.

SQL> CREATE SEQUENCE Seql;


Sequence created.

SQL> GRANT SELECT ON Seql TO PUBLIC;


Grant succeeded.

SQL> CONNECT U2/U2PSW0EDUC;


Connected.

SQL> SELECT Ul.Seql.NEXTVAL FROM DUAL;

NEXTVAL

1
SQL> CONNECT SYSTEM/MANAGER0EDUC;
Connected'.

292
Средства разграничения доступа в Oracle
SQL> CREATE USER U3 IDENTIFIED BY U3PSW;
User created.

SQL> GRANT CONNECT TO U3;


Grant succeeded.

SQL> CONNECT U3/U3PSW;


Connected.

SQL> SELECT Ul.Seql.NEXTVAL FROM DUAL;

NEXTVAL

Листинг 158. Протокол примера предоставления гло-


бальной привилегии по выборке из- последова-
тельности

Для передачи некоторой системной привилегии с правом


наследования используется параметр WITH ADMIN OPTION.
Если системная привилегия передана с этим параметром, по-
лучивший ее пользователь имеет право передавать данную
привилегию другим пользователям.
Рассмотрим пример. Пусть пользователю U1 предостав-
лена системная привилегия SELECT ANY TABLE WITH
ADMIN OPTION. Пользователь Ul может передать соответ-
ствующую привилегию пользователю U2. Попытка пользова-
теля U2 выполнить выборку из таблицы Tab! в схеме пользо-
вателя U1 отвергается системой. После предоставления при-
вилегий SELECT ANY TABLE предыдущая операция выпол-
няется успешно. Отметим тот факт, что при попытке выпол-
нить выборку данных из таблицы Ul.Tabl, доступ к которой
пользователю U2 не предоставлен, система выдает сообщение
об отсутствии таблицы с данным именем, а не о недостатке
привилегий. Такой подход обеспечивает защиту от выявления
имен таблиц, содержащих важную информацию, путем уга-
дывания за счет многократного апробирования вариантов.

293
Раздел 4

Протокол взаимодействия с Oracle, иллюстрирующий


пример, приведен в листинге 159:

SQL> CONNECT SYSTEM/MANAGERSEDUC;


Connected.

SQL> GRANT SELECT ANY TABLE TO Ul


2 WITH ADMIN OPTION;
Grant succeeded.

SQL> CONNECT U2/U2PSW0EDUC;


Connected.

SQL> SELECT * FROM Ul.Tabl;


SELECT * FROM Ul.Tabl
*
ERROR in line 1:
ORA-00942: table or view does not exist.

SQL> CONNECT'U1/U1PSW@EDUC;
Connected.

SQLX INSERT INTO Tabl VALUES (123); '


1 row created.

SQL> GRANT SELECT ANY TABLE TO U2;


Grant succeeded.

SQL> CONNECT U2/U2PSW0EDUC;


Connected.

SQL> SELECT * FROM Ul.Tabl;

ATI

123

Листинг 159. Протокол примера предоствления при-


вилегий с параметром WITH ADMIN OPTION

294
Средства разграничения доступа в Oracle

Предоставление привилегий
доступа к объекту
Привилегии доступа к объекту могут быть предоставлены
сервером Oracle двум объектам системы: пользователям
(USER) и ролям (ROLE). Роль представляет собой поимено-
ванный набор привилегий. Назначение и языковые средства
определения ролей будут рассмотрены ниже.
Для предоставления привилегий пользователю в Oracle, в
соответствии с требованиями стандарта, используется коман-
да GRANT. Пользователь, выдавший команду GRANT, либо
должен быть владельцем объекта (то есть пользователем, в
схеме которого создан данный объект), либо наследовать со-
ответствующую привилегию, то есть привилегия была пере-
дана ему с параметром WITH GRANT OPTION, либо обла-
дать привилегией GRANT ANY PRIVILEGE.
Операторы определения привилегий доступа к объектам
управляют разграничением доступа к объектам Oracle: табли-
цам, представлениям, последовательностям, процедурам,
функциям и пакетам, снимкам и синонимам. Оператор опре-
деления привилегий доступа к объектам Oracle использует
следующий синтаксис:

GRANT{привилегия_доступа_к_объекту\ ALL
PRIVILEGES}
[имя_столбца [ { , имя_столбца}...] ]
[ {, привилегия_доступа_к_объекту }...]
ON [имя_схемы.}имя_объекта
ТО {пользователь \ PUBLIC}
[WITH GRANT OPTION]

Список значений, которые может принимать параметр


прившегия_достпупа_к_объекту, состоит из ключевых слов,
значение которых пояснено в приведенной таблице.

295
Раздел 4
Таблица 21. Обозначение сущность .привилегии
доступа к объекту

Привилегия Разрешаемые
привилегией действия
SELECT Пользователь с этой привилегией
может выполнять выборку данных из
соответствующего объекта.
INSERT Пользователь с этой привилегией
может выполнять вставку данных в
соответствующий объект. Данная
привилегия допускает уточнение для
определенных элементов объекта.
UPDATE Пользователь с этой привилегией
может выполнять модификацию дан-
ных соответствующего объекта. Дан-
ная привилегия допускает уточнение
для определенных элементов объекта.
REFERENCES Пользователь с этой привилегией
может определить ссылку, по которой
производится контроль целостности
объекта. Данная привилегия допуска-
ет уточнение для определенных эле-
ментов объекта.
DELETE Пользователь с этой привилегией
может выполнять удаление данных в
соответствующем объекте.
EXECUTE Пользователь с этой привилегией
может выполнять действие с соответ-
ствующим объектом (например, вы-
полнить процедуру из пакета).
INDEX Пользователь с этой привилегией
может выполнять операцию индекси-
рования для соответствующего объ-
екта.

296
Средства разграничения доступа в Oracle

Следующий пример иллюстрирует возможность предос-


тавления набора привилегий одной командой. Владелец таб-
лицы, пользователь U2, предоставляет пользователю U1 при-
вилегии по выборке, вставке и модификации для таблицы
Tab!. Пусть таблица ТаЫ создана предложением:

CREATE TABLE ТаЫ (Atl Number);.

Выполнение операций, привилегии на выполнение кото-


рых предоставлены, проходит успешно, а попытка пользова-
теля U1 выполнить удаление строк отвергается системой.
Листинг 160 содержит протокол для данного примера.

SQL> CONNECT U2/U2PSW@EDUC;


Connected.

SQL> GRANT SELECT, INSERT, UPDATE ON Tabl TO Ul;


Grant succeeded.

SQL> CONNECT U1/U1PSW@EDUC,-


Connected.

SQL> INSERT INTO U2.Tabl VALUES (123);


1 row created.
s

SQL> SELECT * FROM U2.Tabl;

ATI

123

SQL> UPDATE U2.Tabl SET Atl - 345;


1 row updated.

SQL> SELECT * FROM U2.Tabl;

ATI

345

297
Раздел 4 ,

SQL> DELETE FROM U2.Tabl;


DELETE FROM U2.Tabl
*.

ERROR at line 1:
ORA-01031: insufficient privileges

Листинг 160. Протокол примера предоставления не-


скольких привилегий доступа к объекту
Oracle одной командой

Рассмотрим пример, иллюстрирующий возможность из-


бирательного, по столбцам, предоставления набора привиле-
гий для команд вставки и модификации данных в таблице
ТаЫ.
Владелец таблицы, пользователь U2, предоставляет поль-
зователю U1 привилегии по вставке и модификации столбца
Atl таблицы ТаЫ. Выполнение перечисленных операций
проходит успешно, а попытка пользователя U1 выполнить
модификацию столбца At2 таблицы ТаЫ отвергается систе-
мой. Обратите внимание, что перечень столбцов относится к
каждой операции, то есть отсутствие перечня после операции
INSERT указывает на возможность вставки всех столбцов
таблицы ТаЫ. Протокол выполнения примера представлен в
листинге 161:

SQL> CONNECT U2/U2PSW0EDUC;


Connected.

SQL> CREATE TABLE Tabl(Atl NUMBER, At2 NUMBER);


Table created.

SQL> GRANT SELECT ON Tabl TO Ul;


Grant succeeded.

SQL> GRANT INSERT, UPDATE (Atl) ON Tabl TO Ul;


Grant succeeded.

SQL> CONNECT U1/U1PSW0EDUC;


Connected.
298
Средства разграничения доступа в Oracle
SQL> INSERT INTO U2.Tab! VALUES (123,123);
1 row created.

SQL> UPDATE U2.Tabl SET Atl = '345;


1 row updated.

SQL> SELECT * FROM U2.Tabl;

ATI AT2

345 123

SQL> UPDATE U2.Tabl SET At2 = 345;


UPDATE U2.Tabl SET At2 = 345
*
ERROR at line 1:
ORA-01031: i n s u f f i c i e n t privileges

Листинг 161. Протокол примера избирательного, по


столбцам, предоставления привилегий для
операций вставки и модификации объекта
Oracle

Ключевое слово REFERENCES указывает на предостав-


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

299
Раздел 4

Применимость значения параметра привилегия_досту-


па_к_объекту к объектам Oracle представлена в приведенной
ниже таблице.

Таблица 22. Таблица применимости привилегий к


объектам базы данных Oracle

Объект Oracle Применимые к объекту


привилегии
Таблица SELECT, INSERT, UPDATE,
DELETE, ALTER, INDEX,
REFERENCES
Представление SELECT, INSERT, UPDATE, DELETE
Последовательность SELECT, ALTER
Процедуры, функ- EXECUTE
ции, пакеты
Снимки SELECT, INSERT, UPDATE, DELETE
Директории READ
Библиотеки EXECUTE

Управление привилегиями
с помощью ролей
Большое число пользователей, статус которых требует
различных привилегий для доступа к ресурсам базы данных,
создает значительный объем рутинной работы администрато-
ру. Oracle предлагает языковое средство для автоматизации
работы администратора по разграничению доступа. Данное
средство поддерживается как объект базы данных, называе-
мый ролью (ROLE). Роль — это поименованный набор при-
вилегий, который может быть предоставлен пользователю
или другой роли. Роль не является объектом какой-либо схе-
мы.

'300
Средства разграничения доступа в Oracle

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


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

Системные привилегии,
определяющие права по работе с ролями

Для работы с ролями в Oracle предусмотрены следующие


системные привилегии.

Таблица 23. Обозначение и сущность системных при-


вилегий Oracle, определяющие права по рабо-
те с ролями

Системная Разрешаемые системной


привилегия привилегией действия
CREATE Разрешает пользователю создавать роли в
ROLE базе данных.
GRANT ANY Разрешает пользователю предоставлять
ROLE произвольную роль произвольному пользо-
вателю в базе данных.
DROP ANY Разрешает пользователю уничтожать про-
ROLE извольную роль в базе данных.
ALTER ANY Разрешает пользователю изменять произ-
ROLE вольную роль в базе данных.

Изменим пример, приведенный в листинге 155 так, чтобы


предоставление привилегий пользователю U2 было выполне-
301
Раздел 4

но успешно. Администратор дополнительно к привилегии


создания пользователей предоставляет пользователю U1 при-
вилегию GRANT ANY ROLE. Теперь пользователь U1 может
предоставить пользователю U2 роль CONNECT, предусмат-
ривающую, в частности, привилегию на образование сессий.

SQL> CONNECT SYSTEM/MANAGERSEDUC


Connected.

SQL> GRANT GRANT ANY ROLE TO Ul;


Grant succeeded.

SQL> CONNECT U1/U1PSW@EDUC;


Connected.

SQL> CREATE USER U2 IDENTIFIED BY U2PSW;


User created.

SQL> GRANT CONNECT TO U2;


Grant succeeded.

SQL> CONNECT U2/U2PSW0EDUC;


Connected. \
Листинг 162. Пример предоставления пользователю
системной привилегии на разрешение ролей

Отметим, что данный пример носит учебный характер.


Предоставление пользователю привилегии GRANT ANY
ROLE в системе с повышенными требованиями по защищен-
ности вряд ли целесообразно.

Предопределенные роли в Oracle

Несколько ролей автоматически определяются Oracle при


создании базы данных. Сценарий определения ролей
CONNECT, RESOURCE и DBA определен в файле sql.bsq. В

302
Средства разграничения доступа в Oracle

данном сценарии определяются привилегии данных ролей, и


роль DBA с параметром WITH ADMIN OPTION предоставля-
ется пользователям SYS и SYSTEM. Квалифицированный
разработчик, создавая систему с повышенными требованиями
по безопасности данных, может изменить сценарий создания
базы данных, определив иные привилегии и иные роли для
сценария создания базы данных.
Роли EXP_FULL_DATABASE и IMP_FULL_DATABASE
созданы для упрощения логической разгрузки и загрузки баз
данных с использованием утилит Export и Import. Данные ро-
ли создаются во время исполнения файла сценария catexp.sql.
Системные привилегии, предоставляемые перечислен-
ным выше ролям, перечисленные в таблице.

Таблица 24. Имена и системные привилегии


предопределенных ролей Oracle

Роль Разрешенные роли


системные привилегии
CONNECT ALTER SESSION
CREATE CLASTER
CREATE DATABASE LINK
CREATE SEQUENCE
CREATE SESSION
CREATE SYNONYM
CREATE TABLE
CREATE VIEW
RESOURCE CREATE CLASTER
CREATE PROCEDURE
CREATE SEQUENCE
CREATE TABLE
CREATE TRIGGER
DBA Все системные привилегии с
параметром WITH ADMIN
OPTION
EXP_FULL_DATABASE
IMP FULL DATABASE
303
Раздел 4

EXP_FULL_DATABASE SELECT ANY TABLE


BACKUP ANY TABLE
INSERT,UPDATE,DELETE доя
системных таблиц
sys.lncexp
sys.incvid
sys.incfil.
IMP FULL DATABASE BECOME USER

Создание ролей и предоставление


им привилегий .

Создание роли может быть выполнено пользователем,


имеющим системную привилегию CREATE ROLE. Для того
чтобы предоставить пользователю некоторую роль, необхо-
димо создать эту роль и разрешить ее в текущем сеансе. Об-
ратите внимание на аналогию с пользователем: его нужно
создать и предоставить ему минимальные привилегии. Ко-
манда создания роли в Oracle использует следующий синтак-
сис:

CREATE ROLE имя_роли


[{NOT IDENTIFIED|IDENTIFIED
{BY пароль^роли \ EXTERNALLY }}]

Параметр NOT IDENTIFIED указывает на то, что при ис-


пользовании роли аутентификация при помощи пароля не
производится. Параметр IDENTIFIED BY пароль_роли указы-
вает на то, что при использовании роли производится аутен-
тификация при помощи пароля, а значение параметра
IDENTIFIED EXTERNALLY указывает на то, что при исполь-
зовании роли аутентификация производится средствами опе-
рационной системы. По умолчанию аутентификация при ус-
тановке разрешения на использование роли не производится.
Рассмотрим пример создания роли Sat, которой предос-
тавлена системная привилегия осуществления выборки из
любой таблицы, и роли SUDat, которой предоставлены сис-
304
Средства разграничения доступа в Oracle

темные привилегии выполнения выборки, модификации и


удаления строк из любой таблицы. Для роли SUDat преду-
смотрена защита паролем sudat_psw. Протокол создания роли
и предоставления ей системных привилегий приведен в лис-
тинге 163.

SQL> CONNECT SYSTEM/MANAGERSEDUC;


Connected.

SQL> CREATE ROLE Sat;


Role created.

SQL> CREATE ROLE SUDat IDENTIFIED BY sat_psw;


Role created.

SQL> GRANT SELECT ANY TABLE TO Sat;


Grant succeeded.

SQL> GRANT SELECT ANY TABLE, UPDATE ANY TABLE,


2 DELETE ANY TABLE TO SUDat;
Grant succeeded.

SQL> GRANT Sat TO Ul;


Grant succeeded.
- • ч •
SQL> GRANT SUDat TO Ul;
Grant succeeded.

Листинг 163. Протокол создания роли и предостав-


ления ей системных привилегий

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

Управление разрешением или запрещением ролей для те-


кущей сессии выполняется командой SET ROLE. До тех пор
пока явно не будет разрешено использование роли для сессии,
привилегии, определенные для пользователя ролью, не пре-
доставляются. Обычно команда SET ROLE подобно опера-
305
Раздел 4

торным скобкам устанавливает корректный домен полномо-


чий пользователя для проведения логически единого с точки
зрения разграничения доступа действия. Команда разрешения
или запрещения использования ролей Oracle использует сле-
дующий синтаксис: -

SET ROLE {роль [IDENTIFIED BY пароль_роли]


[{,роль [IDENTIFIED BY пароль_роли] } . . . ] ] !
{ALL [EXCEPT роль [ , роль ]...] }| NONE}

Параметр ALL с необязательным параметром EXCEPT


используется для разрешения всех ролей, кроме ролей, пере-
численных после параметра EXCEPT. В списке ролей, пере-
численных после параметра EXCEPT, могут присутствовать
только роли, явно назначенные пользователю, то есть недо-
пустимо использование параметра для исключения из списка
ролей, назначение которых выполняется через другие роли.
Данный параметр применим только для ролей, не защищен-
ных паролем. Защищенные паролем роли должны быть раз-
решены явным указанием. Если роль была защищена паро-
лем, то для разрешения роли требуется в предложении
IDENTIFIED BY указать пароль.
Использование параметра NONE предназначено для за-
прещения всех ролей.
Для ролей, протокол создания которых приведен в лис-
тинге 163, рассмотрим механизмы разрешения их использо-
вания. Пусть в системе определены роли Sat и SUDat. Перво-
начально все роли запрещены, и пользователь U1 не имеет
права выполнить выборку из таблицы Tab! схемы U2. После
разрешения ему роли Sat выборка проходит успешно, но опе-
рация по модификации данных отвергается. После предос-
тавления роли SUDat, защищенной паролем, операция моди-
фикации таблицы Tab! из схемы U2 также выполняется. Про-
токол разрешения ролей пользователю и предоставления ему
системных привилегий приведен в листинге 164.

306
Средства разграничения доступа в Oracle

SQL> CONNECT U1/U1PSW@EDUC;


Connected.

SQL> SET ROLE NONE;


Role set.

SQL> SELECT * FROM U2.Tab.l;


SELECT.* FROM U 2 . T a b l
*
ERROR at line 1:
ORA-00942: table or view does not exist

SQL> SET ROLE Sat;


Role set.

SQL> SELECT * FROM U 2 . T a b l ;

ATI

123

SQL> UPDATE U2.Tabl SET Atl = 678;


UPDATE U2.Tabl SET Atl = 678
*
ERROR at line 1:
ORA-01031: insufficient privileges

SQL> SET ROLE SUDat IDENTIFIED BY sudat_psw;


Role set.

SQL> UPDATE U2.Tabl SET Atl = 678;


1 row updated.

Листинг1 164. Пример управления разрешением и за-


прещением использования роли

В том случае, если среда выполнения программы не под-


держивает инструкцию SET ROLE, можно использовать
стандартный пакет DBMS_SESSION. Входящая в него проце-
дура SET_ROLE позволяет обращаться к инструкции SET
• . /
307
Раздел 4

ROLE через процедурный интерфейс. Пример использования


DBMS_SESSION.SET_ROLE представлен в листинге 165.

SQL> BEGIN
2 DBMS_SESSION.SET_ROLE('NONE');
3 END;
4 /

PL/SQL procedure successfully completed.

Листинг 165. Пример управления разрешением роли с


помощью стандартного пакета DBMS_SESSION

Отмена привилегий
Чтобы отменить системные привилегии или привилегии
доступа к объекту, предоставленные пользователям или ро-
лям, используется команда REVOKE. Стандарты ANSI/ISO
SQL не определяют синтаксис команды отмены привилегий.
В Oracle для отмены системных привилегий и привилегий
доступа к объекту используются различные синтаксические
конструкции.

Отмена системных привилегий


и ролей

Для отмены системных привилегий и ролей в Oracle


используется команда:

.REVOKE {системная_привилегия \ роль}


[, (системная_привилегия \ роль]...]
FROM {пользователь!роль\ PUBLIC}
[{, пользователь] роль}...]

Использование ключевого слова PUBLIC приводит к от-


мене системной привилегии или роли для всех пользователей.
308
Средства разграничения доступа в Oracle

Обратите внимание, что при отмене системной привилегии


или роли с параметром PUBLIC привилегии, предостав-
ленные пользователю явно или через роль, не отменяются.
Отмена привилегий для пользователя или роли наступает
немедленно. Если отменяется роль для конкретного пользова-
теля, то отмена проявляется только после окончания сессии
пользователя.
Отмена привилегий доступа
к объекту
Для отмены привилегий доступа к объекту в Oracle ис-
пользуется команда:

REVOKE {привилегия_доступа_к__объекту \ ALL


[PRIVILEGES ]'}[/: {привиле-
гия_доступа_к_объекту}...]
ON [схема.]объект
FROM{пользователь] роль| PUBLIC}
[{, пользователь] роль}...] [CASCADE CONSTRAINTS]

Параметр привилегш_доступа_к_объекту может прини-


мать значения: SELECT, INSERT, UPDATE, DELETE, REF-
ERENCES, ALTER, EXECUTE, INDEX. Применимость пара-
метра привилегия_доступа_к_объекту к конкретным объ-
ектам Oracle представлена в таблице 22. Если необязательный
параметр схема не указан, то предполагается, что объект при-
надлежит схеме пользователя, выполняющего команду.
Использование ключевого слова PUBLIC приводит к от-
мене привилегии доступа к объекту для всех пользователей.
Обратите внимание, что при отмене системной привилегии
или роли с параметром PUBLIC привилегии, предостав-
ленные пользователю явно или через роль, не отменяются.
Конструкция CASCADE CONSTRAINTS отменяет ссы-
лочные ограничения целостности, предоставленные с помо-
щью ключевого слова REFERENCES.

309
Раздел 4

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


немедленно.
Команда REVOKE не может быть использована для от-
мены привилегий доступа к объекту, явно предоставленных
другим пользователем.
Вопрос о передаче привилегий на право выполнения опе-
раций по отмене привилегий не проработан до академической
ясности. Общий подход состоит в том, что привилегии отме-
няются пользователем, который их предоставил, и отмена
каскадируется, то есть автоматически распространяется на
всех пользователей, получивших эту привилегию. При разра-
ботке политики безопасности конкретной системы необходи-
ма дополнительная проработка вопроса и, возможно, прове-
дение реального тестирования на используемой версии
Oracle.

Использование представлений
для разграничения доступа
Широко используемым, простым и эффективным спосо-
бом разграничения доступа является использование представ-
лений (view). Представление — это динамически поддержи-
ваемая сервером выборка из одной или нескольких таблиц.
Оператор SELECT, определяющий выборку, ограничивает
видимые пользователем данные. Кроме того, представление
позволяет эффективно ограничить данные, которые поль-
зователь может модифицировать. Сервер гарантирует акту-
альность представления, то есть формирование представле-
ния (подстановка соответствующего запроса) производится
каждый раз при обращении к нему. Используя представления,
администратор безопасности ограничивает доступную поль-
зователю часть базы данных только теми данными, которые
реально необходимы для выполнения его работы.
Наличие такого объекта, как представление, позволяет
администратору делать действие привилегий более избира-
310
Средства разграничения доступа в Oracle

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


или нескольких таблиц базы данных формирует набор строк и
столбцов, реально необходимых пользователю для работы,
администратор безопасности определяет необходимые при-
вилегии на представление. Наличие механизма представлений
делает возможности команды GRANT для разграничения дос-
тупа практически неограниченными.
Чтобы конструктивно работать с представлением, поль-
зователь должен как минимум^ иметь привилегию SELECT
для всех таблиц, которые участвуют в запросе, формирующем
данные представления. Поэтому данная привилегия наследу-
ется представлением для пользователя, который его создает.
Если пользователь обладает любой комбинацией привилегий
INSERT, UPDATE, DELETE для базовых таблиц, они также
будут автоматически наследоваться представлением. В то же
время пользователь, не имеющий привилегий на модифика-
цию строк базовых таблиц, не может получить соответст-
вующие привилегии в представлении. Так как внешние клю-
чи не используются в представлениях, наличие/отсутствие
привилегии REFERENCES для базовых таблиц никогда не
создает ограничений при создании представлений.
С позиций разграничения доступа часто целесообразно
предоставлять пользователю не первичную, а производную
информацию, строящуюся на основе информации из базовых
таблиц. .Для реализации такого подхода обычно используют
представления.
Рассмотрим пример. Пусть базовая таблица создана и за-
полнена с использованием следующих предложений:

CREATE TABLE Tab!(Atl NUMBER, At2 VARCHAR2(3));


INSERT INTO TAB1 VALUES(1,'A');
INSERT INTO TAB1 VALUES(1,'В');
INSERT INTO TAB1 VALUES(2,'A');
INSERT INTO TAB1 VALUES(1,'A');

Пользователь Ul создает представление VI, в котором


для таблицы Tab! вычисляется сумма в столбцах Atl, сгруп-
311
Раздел 4

пированная по значениям столбца At2. Пользователю U2 пре-


доставляется право выборки из представления, но не из базо-
вой таблицы. Протокол иллюстрирующего примера приведен
в листинге 166.

SQL> CREATE OR REPLACE VIEW VI (VAT1) AS


2 SELECT SUM(ATI)
3 FROM Tabl GROUP BY ATI;
View created.

SQL> GRANT SELECT ON VI TO U2;


Grant succeeded.

SQL> CONNECT U2/U2PSW;


Connected.

SQL> SELECT * FROM U1.V1;

VAT1

3
2

SQL> 'SELECT * FROM Ul.Tabl;


SELECT '* FROM Ul.Tabl
*
ERROR at line 1:
ORA-00942: table or view does not exist
/
Листинг 166. Протокол создания представления для
доступа к агрегированным данным

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


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

Хранимая процедура или функция — это множество объ-


единенных общим замыслом предложений языка PL/SQL,
которые хранятся на сервере в откомпилированной форме и
исполняются по запросу клиентского предложения. Процеду-
ры или функции создаются для выполнения некоторой кон-
кретной работы пользователем. При этом пользователю дос-
таточно предоставить привилегию на исполнение процедуры,
созданной для поддержки его деятельности. Важным фактом
является то, что пользователю не требуется предоставления
прав доступа к данным, обрабатываемым данной процедурой.
Наличие такого механизма позволяет исключить обработку
данных пользователем, не предусмотренную разработчиком
системы или администратором безопасности.
Рассмотрим конкретный пример. Пользователь U1 созда-
ет процедуру выборки данных из таблицы ТаЬ2 и предостав-
ляет право на ее исполнение пользователю Ш. Пользователь
U2, выполняя процедуру, может получить результат выборки
из U1 .ТаЬ2, но попытка явного выполнения выборки отверга-
ется системой. Ясно, что в процедуре при определении кур-
сора могло быть задано любое ограничение, характеризую-
щее данные, необходимые для работы приложения. В листин-
ге 167 приведен протокол исполнения предложенного приме-
ра.

SQL> CONNECT U1/U1PSW0EDUC;


Connected.

SQL> CREATE OR REPLACE PROCEDURE getdata AS


2 CURSOR cursel IS
3 SELECT * FROM Tab2;.
4 currec Tab2%ROWTYPE;
5 BEGIN
6 FOR currec IN cursel LOOP
1 DBMS_OUTPUT.PUT_LINE(TO_CHAR(currec.Atl)| Г
'} |TO_CHAR(currec.At2));
8 END LOOP;
9 END getdata;
313
Раздел 4
10 /
Procedure created.
SQL> -GRANT EXECUTE ON getdata TO U2;
Grant succeeded.

SQL> CONNECT . U2/U2PSW@EDUC;


Connected.
SQL> SELECT * FROM Ul.Tab2;
SELECT * FROM Ul.Tab2
*
ERROR at line 1:
ORA-01031: insufficient privileges

SQL> BEGIN
2 Ul.getdata;
3 END;
4 /

1 2
3 4

PL/SQL procedure successfully completed.

Листинг 167. Протокол примера разграничения дос-


тупа средствами хранимой процедуры

Использование триггеров
для повышения защиты системы
Триггер — это совокупность предложений языка PL/SQL,
автоматически запускаемая при регистрации сервером опре-
деленных событий в системе. Триггеры выполняются систе-
мой автоматически до или после возникновения предопреде-
ленных событий, таких, как выполнения операций INSERT,
UPDATE, DELETE в некоторой таблице. Способы использо-
вание триггеров для повышения защищенности системы по-
добны использованию хранимых процедур. Особенностью
триггеров является реализуемая возможность выполнить не-
314
Средства разграничения доступа в Oracle

обходимые проверки полномочий перед выполнением опера-


ции над таблицами. Дополнительно отметим, что на одном
множестве таблиц может быть определено несколько тригге-
ров. Комбинации триггеров, выполняемых до и после опера-
ций, позволяют создавать изощренные механизмы проверки
допустимости тех или иных действий в базе данных.
Рассмотрим пример применения триггеров для выполне-
ния функций разграничения доступа и фискальных действий.
Пусть пользователь SYSTEM является владельцем таблицы
Tab! с одним столбцом Ail, в который предполагается запись
данных уполномоченными пользователями. Список уполно-
моченных пользователей размещается в таблице AuthTab.
Процесс ввода данных в таблицу Tab! контролируется триг-
гером TRIG_BFR, который автоматически выполняется до
выполнения операции вставки строк в таблицу Tab! (конст-
рукция BEFORE INSERT). Наличие полномочий у пользова-
теля на выполнение операции вставки проверяется вызовом
функции FuncAuth. Для регистрации действий уполномочен-
ных пользователей создана таблица TabAud. В данном при-
мере в таблице TabAud регистрируется вводимое в таблицу
Tab! значение атрибута и дата вставки записи. Регистрация
действий осуществляется после выполнения вставки строки в
таблицу ТаЫ. В листинге 168 представлены протоколы соз-
дания таблиц AuthTab и TabAud, функции FuncAuth, выпол-
няющей проверку полномочий и синонима для таблицы
TabAud:

CONNECT SYSTEM/MANAGER8EDOC
Connected.

SQL> CREATE TABLE AuthTab (Atl V A R C H A R ( 3 0 ) ) ;


Table created.

SQL> INSERT INTO AuthTab VALUES ('SYSTEM');


1 row created.

315
Раздел 4
SQL> INSERT INTO AuthTab VALUES ('Ul');
1 row created.
SQL> CREATE OR REPLACE FUNCTION FuncAuth
2 RETURN NUMBER
.3 AS
4 varl NUMBER;
.5 BEGIN
6 SELECT COUNT(*) INTO varl FROM AUTHTAB
7 WHERE Atl IN (USER);
8 RETURN varl-;
9 END;
10 /
Function created.

SQL> CREATE PUBLIC SYN.ONYM FUNCAUTH


2 FOR SYSTEM.FuncAuth;
Synonym created.

SQL> GRANT EXECUTE ON'FuncAuth TO PUBLIC;


Grant succeeded.

SQL> CREATE TABLE TabAud (Atl NUMBER, At2 DATE);


Table created.

SQL> CREATE PUBLIC 'SYNONYM TabAud


2 FOR SYSTEM.TabAud;
Synonym created.

SQL> GRANT INSERT ON TabAud TO -PUBLIC;


Grant succeeded.

Листинг 168. Протокол создания таблиц, функции и


синонима примера

Протоколы создания триггеров представлены в листинге


169. Триггер TRIG_BFR автоматически запускается до вы-
полнения операции вставки строк в таблицу ТаЫ, а триггер
TRIG AFT — после.

SQL> CREATE OR REPLACE TRIGGER TRIG_BFR


2 BEFORE INSERT ON Tabl
316
Средства разграничения доступа в Oracle
3 FOR EACH ROW
4 BEGIN
5 IF FuncAuth = 0
6 THEN
7 RAISE_APPLICATION_ERROR(-20011, 'Неавторизова-
нная операция');
8 END IF;
9 END;
10 /
'Trigger created.

SQL> CREATE OR REPLACE TRIGGER TRIG_AFT


2 AFTER INSERT OR UPDATE ON Tabl
3 FOR EACH ROW
4 BEGIN
5 INSERT INTO TabAud VALUES(:new.At1, SYSDATE);
6 END;
7 /
Trigger created.

Листинг1 169. Протокол создания триггеров примера

Протокол создания пользователей U1 и U2 приведен в


листинге 170. Пользователь U1 уполномочен выполнять
вставку строк в таблицу Tabl (см. строки таблицы AuthTab в
листинге 168), а пользователь U2 — нет. С позиций системы
пользователи наделяются одинаковыми привилегиями.

SQL> CREATE USER Ul IDENTIFIED BY U1PSW;


User created.

SQL> GRANT CONNECT TO Ul;


Grant succeeded.

SQL> GRANT INSERT ANY TABLE TO Ul;


Grant succeeded.

SQL> CREATE USER U2 IDENTIFIED BY U2PSW;


User created.

317
Раздел '4
SQL> GRANT CONNECT TO U2;
Grant succeeded.

SQL> GRANT INSERT ANY TABLE TO U2;


Grant succeeded.

Листинг 170. Протокол создания пользователей при-


мера

В листинге 171 приведен протокол демонстрации работы


модельной системы разграничения доступа, построенной е
использованием триггеров. Для пользователя U1 операция
вставки строк выполняется успешно. Для пользователя U2 —
автоматически запускается триггер, который генерирует ис-
ключительную ситуацию по нарушению условий авторизации
доступа.

SQL> CONNECT U1/U1PSW0EDUC;


Connected

SQL> INSERT INTO SYSTEM.Tabl VALUES(111);


1 row created.

SQL> CONNECT U2/U2PSW0EDUC;


Connected.

SQL> INSERT INTO SYSTEM.Tabl VALUES(222);


INSERT INTO SYSTEM.TAB1 VALUES(222)
*
ERROR at line 1:
ORA-20011: Неавторизованная операция
'ORA-06512: at "SYSTEM.TRIG_BFR", line 4
ORA-04088: error during execution of trigger
1
SYSTEM.TRIG_BFR'

SQL> CONNECT SYSTEM/MANAGER0EDUC;.


Connected.

318
Средства разграничения доступа в Oracle

SQL> SELECT * FROM Tabl; '

ATI

111

SQL> SELECT * FROM TabAud;

ATI AT2

111 10-04-2002

Листинг1 171. Пример, демонстрирующий использова-


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

Средства аудита
Полноценная система обеспечения безопасности должна
обладать развитыми средствами аудита, то есть автоматиче-
ского ведения протоколов действий пользователей системы.
Таблицы для записей аудита обычно являются частью слова-
ря данных. В Oracle основной таблицей для записей аудита
является таблица SYS.AUD$. В данной таблице 28 столбцов,
что позволяет вести достаточно детальный аудит событий в
системе.
Для каждой контролируемой операции фиксируется ин-
формация о пользователе, выдавшем запрос на операцию, ти-
пе операции, об объектах базы данных, на которые воздейст-
вовала операция, дате и времени выполнения операции. На
базе таблицы SYS.AUD$ построено несколько представле-
ний, информация из которых обычно и обрабатывается адми-
нистраторами системы и возможно пользователями. Наиболее
часто используются представления: DBA_AUDIT_TRAIL,
USER_AUDIT_TRAIL, USER_AUDIT_OBJECT, а также
USER_AUDIT_SESSION,USER_AUDIT_STATEMENT.
Для того чтобы началась автоматическая фиксация собы-
тий в системе при помощи включения соответствующих за-
319
Раздел 4
писей в таблицу аудита, необходимо активизировать службу
аудита и определить перечень фиксируемых событий. Для
активизации службы аудита необходимо включить в файл
параметров базы данных параметр audit_trail = true (при ис-
пользовании стандартного файла инициализации данный па-
раметр присутствует, но закомментирован) и перезапустить
сервер для того, чтобы измененное значение параметра при-
вело к включению службы аудита.
Определение перечня фиксируемых событий может быть
модифицировано в любое время пользователем, имеющим
привилегию AUDIT SYSTEM (для аудита системных собы-
тий) или AUDIT ANY (для аудита событий, связанных с до-
ступом к объекту системы). Заметим, что модификация пе-
речня фиксируемых событий может быть выполнена и в пе-
риод, когда служба аудита не активизирована. Естественно,
что записи о событиях перечня начнут появляться только по-
сле активизации службы.

Аудит системных событий

Оператор определения перечня фиксируемых системных


событий Oracle использует следующий синтаксис:

AUDIT {имя_группы_событии \ системная_привилегия}


[ { , имя_группы_событий\системная_привилегия } . . . ]
[BY пользователь { [ , пользователь] . . . } ]
[BY { SESSION I ACCESS }]
[WHENEVER [NOT] SUCCESSFUL]

Список значений, которые может принимать параметр


имя_группы_событш, приведен в представленных ниже таб-
лицах. Системные привилегии сгруппированы по объектам.
Список не является исчерпывающим, полный список может
быть взят из документа Oracle Server SQL Reference. Список
значений, которые может принимать параметр систем-

320
Средства разграничения доступа в Oracle

ноя_привилегия, приведен в разделе, посвященном предостав-


лению системных привилегий.
Конструкция BY пользователь указывает на то, что фик-
сируются только определенные данным предложением дейст-
вия конкретного пользователя или перечисленных в списке
пользователей. Если конструкция BY пользователь не указа-
на, фиксируются действия всех пользователей.
Конструкция BY SESSION указывает на то, что в таблицу
аудита заносится единственная запись о фиксируемом дейст-
вии для каждого сеанса пользователя. Значение используется
по умолчанию.
Конструкция BY ACCESS указывает на то, что для каж-
дого выполнения действия пользователем в таблицу аудита
заносится запись о фиксируемом действии. Заметим, что в
случае, если в предложении определена фиксация действий с
системными привилегиями, или выполнение предложений
подъязыка определения данных, то независимо от указанного
значения параметра BY { SESSION | ACCESS} принудитель-
но выполняются действия, опеределяемые конструкцией BY
ACCESS.
Конструкция WHENEVER SUCCESSFUL указывает на
то, что в таблицу аудита заносится запись о фиксируемом
действии только в случае успешного выполнения операции.
Конструкция WHENEVER NOT SUCCESSFUL указывает
на то, что в таблицу аудита заносится запись о фиксируемом
действии только в случае неуспешного выполнения операции.
Если конструкция WHENEVER ... не указана, то ауди-
торская запись вносится независимо от успешности выполне-
ния операции. Значения, которые может принимать параметр
имя_группы_событий, приведены в таблицах 25 и 26.

321
-И. Заказ Мо 1628.
Раздел 4
Таблица 25. Обозначение и сущность основных сис-
темных событий Oracle, фиксирование которых
определяется параметром имя_группы_событий
команды AUDIT

Имя группы ' Фиксируемые действия


событий
SESSION Фиксирует вхождения пользователей
в систему.
USER CREATE USER
DROP USER
ALTER USER
SYSTEM AUDIT AUDIT
NOAUDIT
SYSTEM GRANT GRANT (системные привилегии и
привилегии доступа к объекту)
REVOKE (системные привилегии и
привилегии доступа к объекту)
NOT EXIST Фиксирует неуспешную попытку вы-
полнить любое SQL-предложение,
если причина невозможности выпол-
нить операцию в том, что объект базы
данных не существует.
PROCEDURE CREATE FUNCTION
CREATE PACKAGE
CREATE PACKAGE BODY
.
CREATE PROCEDURE
DROP FUNCTION
DROP PACKAGE
DROP PROCEDURE
TABLE CREATE TABLE
DROP TABLE
TRUNCATE TABLE
VIEW CREATE VIEW
DROP VIEW
PUBLIC SYNONYM CREATE PUBLIC SYNONYM
DROP PUBLIC SYNONYM

322
Средства разграничения доступа в Oracle

SYNONYM CREATE SYNONYM


DROP SYNONYM
ROLE CREATE ROLE
N. ALTER ROLE
DROP ROLE
SET ROLE
SEQUENCE CREATE SEQUENCE
DROP SEQUENCE
TABLESPACE CREATE TABLESPACE
DROP TABLESPACE
ALTER TABLESPACE

Рассмотрим пример использования автоматического ау-


дита процесса регистрации пользователей в системе. Пред-
ставленный в листинге 172 протокол демонстрирует включе-
ние и выключение службы автоматической регистрации со-
единений пользователей с сервером Oracle.
В данном случае запуск аудита выполняется пользовате-
лем SYSTEM, который обладает необходимыми привилегия-
ми.

SQL> AUDIT CONNECT;


Audit succeeded.

SQL> CONNECT U1/U1PSW


Connected.

SQL> CONNECT U2/U2PSW


Connected.

SQL> CONNECT UNKNOWN/ABC


ERROR: ORA-01017: invalid username/password;
logon denied
Warning: You are no longer connected to ORACLE.

SQL> CONNECT SYSTEM/MANAGER


Connected.

323
11*
Раздел 4
SQL> NOAUDIT CONNECT.;
Noaudit succeeded.

Листинг 172. Пример активизации и завершения про-


цесса автоматической регистрации подключе-
ния пользователей к серверу Oracle

Результаты автоматической регистрации процессов под-


ключения пользователей к серверу Oracle просматриваются с
использованием представления DBA_AUDIT_TRAIL, создан-
ного на базе системной таблицы SYS.AUD$. В листинге 173
представлена выборка данных с результатами аудита систе-
мы, инициированного действиями, описанными в листинге
172.

SQL> SELECT USERNAME, TIMESTAMP,


2 RETURNCODE FROM DBA_AUDIT_TRAIL;

USERNAME TIMESTAMP RETURNCODE

Ul 11-04-2002 0
U2 11-04-2002 0
UNKNOWN 11-04-2002 1017
SYSTEM 11-04-2002 0

Листинг 173. Результат выборки данных, собранных


согласно листингу 172

Дополнительные значения, которые может принимать


параметр имя_группы_событий, приведены в таблице 26.

324
Средства разграничения доступа в Oracle
Таблица 26. Обозначение дополнительных системных
событий, фиксирование которых определяет
имя_грулпы_ событий

Имя группы_ Фиксируемые действия


событий
GRANT TABLE Передача привилегий с использо-
ванием, предложения GRANT на
объекты: таблица, представление,
снимок. Отзыв привилегий с ис-
пользованием REVOKE на объек-
ты: таблица, представление, сни-
мок.
INSERT TABLE Операции вставки строк в таблицы
и представления.
DELETE TABLE Операции удаления строк из таб-
лиц и представлений.
UPDATE TABLE Операции изменения строк в таб-
лицах и представлениях.
SELECT TABLE Операции выборки из таблиц,
представлений и снимков.
ALTER TABLE Операции модификации определе-
ний таблиц ALTER TABLE.
EXECUTE Выполнение любой процедуры
PROCEDURE или функции или доступ к элемен-
ту спецификации произвольного
пакета.
GRANT PROCEDURE Передача привилегий с использо-
ванием предложения GRANT на
объекты: процедура, функция или
пакет. Отзыв привилегий с исполь-
зованием предложения REVOKE
на объекты: процедура, функция
или пакет.
GRANT SEQUENCE Передача привилегий с использо-
ванием предложения GRANT на
325
Раздел 4

последовательность. Отзыв приви-


легий с использованием предло-
жения REVOKE на последова-
тельность.
SELECT SEQUENCE Выполнение выборки элементов
произвольной последовательности
использованием CURRVAL или
NEXTVAL

В Oracle предусмотрено использование обобщенных


имен групп событий для фиксации более широких множеств
событий, чем те, что приведены в таблицах 25 и 26. Отметим,
что поддержка обобщенных имен групп событий в будущих
версиях Oracle не гарантируется.

Таблица 27. Таблица обобщенных имен групп событий


Oracle

Имя группы Фиксируемые действия


событий
CONNECT CREATE SESSION
RESOURCE CREATE TABLE
CREATE VIEW
CREATE PROCEDURE
CREATE SEQUENCE
CREATE SYNONYM
ALTER SYSTEM
CREATE DATABASE LINK
CREATE TABLESPACE
DBA Все привилегии, задаваемые
предложением SYSTEM GRANT, a
также CREATE USER
CREATE ROLE
AUDIT SYSTEM
CREATE PUBLIC DATABASE LINK
CREATE PUBLIC SYNONYM
326
Средства разграничения доступа в Oracle

ALL Все привилегии, перечисленные в


таблице 25 (но не в таблице 26).
ALL PRIVILEGES Все системные привилегии.

Аудит событий, связанных


с доступом к объекту

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


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

AUDIT {имя^регистрируемого_действия]
[ {, {имя_регистрируемого_действия } . . . ]
ON { [ с х е м а . ] о б ъ е к т \ DEFAULT}
[BY { SESSION | ACCESS }]
[WHENEVER [NOT] SUCCESSFUL]

Параметр шля регистрируемого Действия может прини-


мать значения, приведенные в таблице 28 и зависящие от типа
объекта.
Конструкция BY SESSION указывает на то, что в таблицу
аудита заносится единственная запись о регистрируемом дей-
ствии для каждого сеанса пользователя. Значение использует-
ся по умолчанию.
Конструкция BY ACCESS указывает на то, что для каж-
дого выполнения действия пользователем в таблицу аудита
заносится запись о фиксируемом действии. Заметим, что в
случае, если в предложении определена фиксация выполне-
ния предложений подъязыка определения данных, то незави-
327
Раздел 4

симо от указанного значения параметра BY {SESSION |


ACCESS} принудительно выполняются действия, определяе-
мые конструкцией BY ACCESS.
Конструкция WHENEVER SUCCESSFUL указывает на
то,'что в таблицу аудита заносится запись о фиксируемом
действии только в случае успешного выполнения операции.
Конструкция WHENEVER NOT SUCCESSFUL указывает
на то, что в таблицу аудита заносится запись о фиксируемом
действии только в случае неуспешного выполнения операции.
Если конструкция WHENEVER ... не указана, то ауди-
торская запись вносится независимо от успешности выполне-
ния операции. Действие команды аудита доступа к объекту
начинается немедленно после ее выполнения, то есть в теку-
щей сессии.

Таблица 28. Таблица значений параметра имя_регис-


трируемого_действия, применимого к объектам
Oracle

Имя действия Допустимые объекты Oracle


SELECT Таблица, представление, снимок, по-
следовательность.
INSERT Таблица, представление, снимок.
UPDATE Таблица, представление, снимок.
DELETE Таблица, представление, снимок.
EXECUTE Процедура, функция, пакет.
GRANT Таблица, представление, снимок, по-
следовательность, процедура, пакет,
функция.
AUDIT Таблица, представление, снимок, по-
следовательность, процедура, функция,
пакет.
ALTER Таблица, снимок, последовательность.
RENAME Таблица, представление, снимок, про-
цедура, функция, пакет.

328
Средства разграничения доступа в Oracle

Рассмотрим пример аудита неуспешных попыток записи


в таблицу Tabl, владельцем которой является пользователь
SYSTEM. Заметим, что в листингах 168—171 представлен
метод, который не допускает выполнения такой операции. В
листинге 174 представлен метод, в котором запрещение опе-
рации обеспечивается системными средствами, а попытка
выполнить запрещенную операцию регистрируется средства-
ми системного аудита.

SQL> CONNECT SYSTEM/MANAGER@EDUC


Connected.

SQL> AUDIT INSERT ON TAB1


2 WHENEVER NOT SUCCESSFUL;
Audit succeeded.

SQL> CONNECT U1/U1PSW@EDUC


Connected.

SQL> INSERT INTO SYSTEM.TAB1 VALUES(111);


INSERT INTO SYSTEM.TAB! VALUES(111)
*
ERROR at line 1:
ORA-00942:. table or view does not exist

SQL> CONNECT SYSTEM/MANAGER@EDUC


Connected.

SQL> NOAUDIT INSERT ON TAB1;


Noaudit succeeded.

SQL> SELECT USERNAME, ACTION,


2 TIMESTAMP FROM USER_AUDIT_TRAIL;

USERNAME- ACTION TIMESTAMP

Ul 103 12-04-2002

SQL> SELECT USERNAME, SES_ACTIONS


2 FROM USER_AUDIT_TRAIL;
329
Раздел 4

USERNAME SES_ACTIONS

Ul . F

Листинг1 174. Протокол регистрации неуспешных по-


пыток вставки строк в таблицу ТаЫ

Прекращение регистрации событий

Прекращение регистрации системных событий может


быть выполнено в любое время пользователем, имеющим
привилегию AUDIT SYSTEM.
Оператор прекращения регистрации определенных сис-
темных событий Oracle использует следующий синтаксис:

NOAUDIT.
{имя_группы_событий \ системная_привилегия]
[{,имя_группы_событий |системная_привилегия }...]
[BY пользователь {[, пользователь} ...}]
[WHENEVER [NOT] SUCCESSFUL]

Список значений, которые может принимать параметр


имя_группы_событий, приведен в таблицах 25 и 26. Список
не является исчерпывающим, полный дписок можно получить
из документа Oracle Server SQL Reference.
Список значений, которые может принимать параметр
системная_привилегия, приведен в разделе, посвященном
предоставлению системных привилегий.
Конструкция BY пользователь указывает на то, что пре-
кращается регистрация только действий конкретного пользо-
вателя, определенных данным предложением. Если она не
указана, прекращается регистрация действий всех пользова-
телей.
Конструкция WHENEVER SUCCESSFUL указывает на
то, что в таблицу аудита заносится запись о фиксируемом
действии только в случае успешного выполнения операции.
330
Средства разграничения доступа в Oracle

Конструкция WHENEVER NOT SUCCESSFUL указывает


на то, что в таблицу аудита заносится запись о фиксируемом
действии только в случае неуспешного выполнения операции.
Если конструкция WHENEVER ... не указана, то ауди-
торская запись вносится независимо от успешное.™ выполне-
ния операции.
Отметим, что команда отмены системного аудита избира-
тельна, то есть отменяет соответствующую команду начала
регистрации событий. Поясним замечание примером. Пусть
сначала выполнено предложение начала аудита по выборке
пользователем U1, а потом выполнено предложение по то-
тальному аудиту по выборке. Если администратор отменяет
тотальный аудит по выборке, то действия пользователя U2
перестают фиксироваться, а регистрация действий пользова-
теля U1 продолжается.
Прекращение регистрации событий, связанных с досту-
пом к объекту Oracle, может быть выполнено пользователем,
имеющим привилегию AUDIT ANY.
Оператор прекращения регистрации определенных собы-
тий, связанных с доступом к объекту Oracle, использует сле-
дующий синтаксис:

NOAUDIT имя_регистрируемого_действия
[, имя_регистрируемого_действия ...]
ON [схема].объект
[WHENEVER [NOT] SUCCESSFUL]

Параметр имя регистрируемого Действия может прини-


мать значения, приведенные в таблице 28 и зависящие от типа
объекта.
Конструкция WHENEVER SUCCESSFUL указывает на
то, что в таблице аудита прекращается регистрация только
успешно завершенных действий с объектами.
Конструкция WHENEVER NOT SUCCESSFUL указывает
на то, что прекращается фиксация действий, приведших к
возникновению ошибки.
331
Раздел 4

Если конструкция WHENEVER ... не указана, то пре-


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

Обработка данных аудита

Для обработки данных, накопленных в ходе аудита,


обычно используются представления USER_AUDIT_TRAIL,
USER_AUDIT_OBJECT, USER_AUDIT_SESSION, а также
USER_AUDIT_STATEMENT.
Наиболее полную информацию об аудите содержит пред-
ставление USER_AUDIT_TRAIL. В таблице 29 перечислены
имена атрибутов и их содержательные описания.

Таблица 29. Имена атрибутов и их содержательное


описание для представления USER_AUDIT_TRAIL

Имя атрибута Тип данных Описание


атрибута
OSJJSERNAME VARCHAR2(255) Имя пользова-
теля, под кото-
рым он зареги-
стрировался в
операционной
системе.
USERNAME VARCHAR2(30) Имя пользова-
теля, под тсото-
рым он зареги-
стрировался в
СУБД.
USERHOST V ARCH AR2( 128) Идентификатор
экземпляра ба-
зы данных, с
332
Средства разграничения доступа в Oracle

которым рабо-
тает поль-
зователь.
TERMINAL VARCHAR2(255) Идентификатор
.
клиентского
- терминала
пользователя.
TIMESTAMP DATE Дата и время
создания реги-
страционной
записи.
OWNER VARCHAR2(30) Владелец объ-
екта, с ко-
торым взаимо-
>-'..'""* действует
пользователь
(для аудита
объектов
Oracle).
OBJ_NAME VARCHAR2(128) Имя объекта, с
которым взаи-
-, модействует
пользователь
(для аудита
объектов
Oracle).
ACTION NUMBER Числовой код
регистрируемо-
го действия
пользователя.
ACTION_NAME VARCHAR2(27) Название реги-
стрируемого
действия поль-
зователя.
NEW OWNER VARCHAR2(30) Владелец пере-
333
Раздел 4

именованного
объекта.
NEW_NAME VARCHAR2(128) Новое имя пе-
реименованно-
го объекта.
OBJ_PRIVILEGE VARCHAR2(16) Привилегии
доступа к объ-
екту, которые
были предо-
ставлены или
отозваны.
SYS_PRIVILEGE VARCHAR2(40) Системные
привилегии,
которые были
предоставлены
или отозваны.
ADMINJDPTION VARCHAR2(1) Индикатор
предоставле-
ния привиле-
гий с парамет-
ром WITH
. e
ADMIN
s

OPTION (при-
нимает значе-
ния Y и N)
GRANTEE VARCHAR2(30) Имя пользова-
теля, у которо-
го изменены
привилегии ко-
мандами
GRANT или
REVOKE.
AUDIT_OPTION VARCHAR2(40) Параметры ко-
манды AUDIT.

334
Средства разграничения доступа в Oracle

SES_ACTIONS VARCHAR2(19) Строка симво-


лов, описы-
вающая ус-
пешное или
неуспешное
выполнение
команды.
LOGOFF_TIME DATE Дата и время
завершения
сессии пользо-
вателем.
LOGOFF_LREAD NUMBER Число опера-
ций логическо-
го чтения, вы-
полненных за
сессию.
LOGOFF_PREAD NUMBER Число опера-
ций физиче-
ского чтения,
выполненных
за сессию.
LOGOFF LWRITE NUMBER Число опера-
ций логической
записи, выпол-
ненных за сес-
сию.
LOGOFF DLOCK VARCHAR2(40) Число тупико-
вых ситуаций,
зафиксирован-
ных в течение
сессии.
SESSIONJD NUMBER Числовой
идентификатор
сессий.

335
Раздел 4

ENTRYJD NUMBER Числовой


идентификатор
регистра-
ционной запи-
си.
STATEMENTID NUMBER Числовой
идентификатор
каждой вы-
полняемой ко-
манды.
RETURNCODE NUMBER Код возврата
для каждой
выполняемой
команды.
PRIVJJSED VARCHAR2(40) Системные
привилегии,
используемые
для исполнения
регистриру-
емой команды.
OBJECT_LABEL RAW MLSLABEL Метка объекта
(только для
Trusted Oracle
Server).
SESSION_LABEL RAW MLSLABEL Метка сессии
(только для
Trusted Oracle
Server.)

Представление USER_AUDIT_OBJECT предназначено


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

336
Средства разграничения доступа в Oracle

Представление USER_AUDIT_STATEMENT предназна-


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

Профили пользователя как


средство повышения
защищенности системы
В качестве дополнительного средства повышения защи-
щенности системы можно рассматривать поддержку в систе-
ме Oracle профилей пользователя.
Профиль пользователя — это поименованный набор ог-
раничений на ресурсы системы. Ограничивая такие критиче-
ские ресурсы как процессорное время, число операций ввода-
вывода за сеанс и т. п., администратор может лишить потен-
циального злоумышленника возможности ухудшать характе-
ристики системы путем ее загрузки бессмысленной работой.
Ограничивая время пребывания клиента в неактивном со-
стоянии, администратор может защитить систему от наруши-
теля, получившего доступ к терминалу, оставленному закон-
ным пользователем на долгое время.
Для создания профиля, который позднее может быть на-
значен тому или иному пользователю, необходимо обладать
системной привилегией CREATE PROFILE. Профиль не яв-
ляется объектом какой-либо схемы.
Оператор создания профиля Oracle использует следую-
щий синтаксис:

337
Раздел 4
CREATE PROFILE {имя_профиля_пользователя} LIMIT-
{имя_параметра_рграничения}
{значение_параметра_ограничения} [.., .]

Параметр имя_парометра_ограничения может принимать


значения, приведенные в таблице 30. Список не является ис-
черпывающим, полный список может быть взят из документа
Oracle Server SQL Reference.

Таблица 30. Значения параметра имя_парамет-


ра_ограничения для команды создания профиля
пользователя

Имя параметра Описание


SESSION PER USER Максимальное число одновре-
менных сессий для данного
пользователя.
CPU PER SESSION Максимальное суммарное
время процессора (в сотых до-
лях секунды), выделяемое для
одной сессии данному пользо-
вателю.
CPU PER CALL Максимальное время процес-
сора на операцию (в сотых до-
лях секунды), выделяемое
данному пользователю.
CONNECT TIME Максимальное суммарное
время на период сессии (в ми-
нутах), выделяемое данному
пользователю.
IDLE TIME Максимальное время непре-
рывного неактивного состоя-
ния пользователя в минутах
(время исполнения длитель-
ных операторов не считается
неактивным).
338
Средства разграничения доступа в Oracle

LOGICAL_READS_PER_SE Максимальное суммарное


SSION число блоков данных, считан-
ных за период сессии, выде-
ляемое данному пользовате-
лю.
LOGICAL_READS_PER Максимальное суммарное
CALL число блоков данных,
считанных за время вы-
полнения одного предложения
SQL, выделяемое данному
пользователю.

Параметр значение_параметра_ограниченш может при-


нимать одно из трех значений:
— целое_число
— UNLIMITED
— DEFAULT.

Как правило, изначально в системе существует один про-


филь DEFAULT, у которого отсутствуют ограничения на ис-
пользуемые ресурсы. Обычно этот профиль назначается всем
пользователям по умолчанию. Для введения ограничений на
ресурсы его требуется изменить или создать новые профили и
назначить их пользователям. Для включения системы ограни-
чения использования ресурсов необходимо выполнить коман-
ду ALTER SYSTEM SET RESOURCEJJMIT = TRUE или
изменить значение соответствующего параметра в файле па-
раметров базы данных.
В примере, представленном в листинге 175, создается
профиль с ограничением на время соединения.

SQL> CONNECT SYSTEM/MANAGER0EDUC


Connected.

339
Раздел 4
SQL> ALTER SYSTEM SET RESOURCE_LIMIT = TRUE;
System altered.

SQL> CREATE PROFILE pfl LIMIT


2 CONNECTJTIME 1;
Profile created.

SQL> ALTER USER ul PROFILE pfl;


User altered.

SQL> CONNECT ul/ulpsw@EDUC


Connected.

-- ожидаем
SQL> SELECT . * FROM dual;
SELECT * FROM dual
*
ERROR at line 1:
ORA-02399: exceeded maximum connect time, you are
being logged off

Листинг 175, Пример создания и назначения пользо-


вателю ограничения на используемые ресурсы

Дополнительные сведения
Для большой корпоративной системы ведение разграни-
чения доступа может оказаться затрудненным. Причиной мо-
жет оказаться большое число объектов, пользователей, ролей,
привилегий (системных и доступа к объектам). В этом случае
проблема состоит не в том, что невозможно предоставить все
необходимые привилегии, а в том, что в результате операций
взаимно назначаемых привилегий, ролей и т. д. пользователь
может получить несанкционированный доступ к данным. Для
преодоления проблемы рекомендуется использовать специ-
альные программные продукты третьих фирм, которые по-
зволяют по словарю данных сформировать подробные отчеты
по актуальным привилегиям. Также существуют специальные
утилиты анализа таблиц аудита.
340
Средства разграничения доступа в Oracle

Дополнительно отметим, что, наряду со стандартными


мерами по недопущению компрометации паролей для ком-
пьютерных систем, в Oracle рекомендуется избегать сохране-
ния паролей в открытом виде, например, в командных и
управляющих файлах экспорта/импорта и загрузки данных
(параметры USERID, USER и т. п.).
Кроме того, в базе данных Oracle существует объект
DATABASE LINK, при создании которого указываются все
необходимые сведения для подключения к удаленной базе
данных, Эти сведения сохраняются в словаре данных и поль-
зователь, обладающий необходимыми привилегиями, может
их узнать.
Также необходимо отметить, что при установке различ-
ных дополнительных картриджей, программ и утилит созда-
ется большое число пользователей с известными паролями
(например, картридж WebDB при установке создает пользо-
вателя WEBDB с паролем WEBDB и т. д.). Если администра-
тор по какой-то причине не изменил назначаемые по умолча-
нию пароли этих пользователей, то возникает серьезная угро-
за безопасности системы, так как обычно эти пользователи
обладают многими системными привилегиями.

341
Раздел 5

Создание приложений на
языке Java

Стандартным интерфейсом для взаимодействия прило-


жений, написанных на языке Java, с OracIeS, является JDBC
(Java DataBase Connectivity). Спецификации интерфейса
JDBC определяются организацией JavaSoft и поддерживаются
всеми основными производителями СУБД.
JDBC построен на идеологии объектно-ориентированного
подхода и естественно интегрируется в язык Java. Возможна
интеграция вызовов JDBC как в программы, написанные на
Java, так и в апплеты, интерпретируемые Java-машинами
браузеров. Наличие апплетов, поддерживающих обращение к
базе данных через интерфейс JDBC, позволяет создавать уни-
версальные приложения, не требующие никакого специали-
зированного программного обеспечения на клиентских рабо-
чих станциях.

Средства построения
приложений и организации
доступа к базам данных
Широкое распространение Всемирной паутины (WWW)
и систем обработки данных, построенных на Web-
технологиях, привело к тому, что все производители СУБД
342
Создание приложений на языке Java

промышленного уровня одновременно являются производи-


телями "сопутствующих" средств разработки приложений и
их интеграции с серверами баз данных. Современная модель
информационных технологий обычно включает тонкого кли-
ента на основе браузера, сервер баз данных и набор компо-
нент промежуточного уровня, использующие технологии
распределенной обработке данных.
Клиентские приложения обычно проектируются так, что-
бы обеспечить доступ тс данным независимо от их расположе-
ния и формата и обеспечить анализ и преобразования данных
в осмысленную информацию, которая может быть доставлена
потребителю в форме, определяемой его интерфейсом.
Традиционный подход к построению систем обработки
данных состоит в том, что клиент присоединяется к некото-
рому серверу. При этом программное обеспечение клиента
или коммуникационного интерфейса обычно поставляет фир-
ма-производитель программного обеспечения сервера баз
данных. Web-технология опирается на новую модель, когда
клиент менее функционален и более широко использует
службы (сервисы) сервера баз данных или сервера приложе-
ний.
Тонкий клиент, характерный для Web-технологий, явля-
ется только средством просмотра информации, подготовлен-
ной и отправленной в среду доставки соответствующими сер-
верами.
Задачей, характерной для Web-технологий, является раз-
деление процессов, выполняемых на клиенте и сервере. Раз-
деление процессов является способом эффективной органи-
зации распределенной обработки данных. Оптимальный уро-
вень производительности достигается на любой конфигура-
ции аппаратных средств за счет адекватного разделения ре-
сурсов.
Каким же образом это обеспечивается? По определению
тонкий клиент обладает минимальным набором программных
и аппаратных ресурсов, обеспечивающих только поддержку
сетевого транспорта и интерпретацию данных, получаемых от
343
Раздел 5

Web-приложений. По сути, тонкий клиент должен поддержи-


вать HTTP протокол, интерпретатор языка HTML и вирту-
альную Java-машину. Клиент может быть реализован не толь-
ко на традиционном персональном компьютере, но и на кар-
манном компьютере или даже на сотовом телефоне.
. Расширение функциональности тонкого клиента возмож-
но с помощью использования апплетов на языке Java. Апплет
— это прикладная программа, хранимая в универсальном ко-
де и загружаемая тонким клиентом для последующей интер-
претации. Интерпретация кода осуществляется виртуальной
Java-машиной, встроенной в программное обеспечение тон-
кого клиента.
Одной из наиболее простых и распространенных Web-
технологий является CGI (Common Gateway Interface). Эта
технология обеспечивает тонкому клиенту возможность фор-
мировать запросы на доступ к требуемой информации через
Web-сервер. После получения запроса посредством CGI, ис-
полняемый модуль возвращает ответ в форме HTML-текста.

Создание приложений
на языке Java
Объектно-ориентированным интерфейсом прикладного
программирования (API), обеспечивающим взаимодействие с
Oracle приложений, написанных на языке Java, является
JDBC. Интерфейс JDBC определяет классы объектов Java,
характерных для выполнения операций с базами данных: со-
единение, подготовка и выполнение SQL-операций, доступ к
результатам, доступ к метаданным и т. п.
Набор классов, реализующий интерфейс JDBC для
Oracle, стандартно размещается в файле classeslll.zip или
classesl 12.zip (в зависимости от версии JDK), который обыч-
но располагается в каталоге ORACLE_HOME\JDBC\LIB. Для
разрешения соответствующей ссылки нужно указать место

344
Создание приложений на языке Java

размещения библиотеки, задав соответствующим образом


переменную CLASSPATH.
Для операционных систем Windows значение переменной
CLASSPATH может быть определено явно в файле
autoexec.bat.. Для UNIX-систем дополнительно должны быть
определены пути доступа к необходимым библиотекам.
Для создания приложений, использующих интерфейс
JDBC, важно уяснить назначение и методы классов Connect,
Statement и ResultSet. Прежде чем обращаться к соответст-
вующим методам, необходимо загрузить драйвер JDBC.

Простейшее приложение
на Java
Класс Connect обеспечивает инициализацию сессии
взаимодействия пользователя с сервером Oracle, включая ау-
тентификацию и авторизацию, установку параметров сессии
(режим выполнения транзакций и т. п.).
Сессия открывается вызовом метода getConnection, пара-
метрами которого являются универсальный локатор ресурса
сервера баз данных, имя пользователя и пароль.
Метод getMetaDataQ обеспечивает получение метадан-
ных из словаря базы данных. Метаданные возвращаются в
форме специального объекта типа DatabaseMetaData.
Рассмотрим пример приложения на языке Java, которое
инициализирует сессию взаимодействия с сервером Oracle.
Считаем, что информация, необходимая для установления
связи с сервером, каталогизирована, а имя пользователя (ul) и
пароль (ulpsw) определены соответствующими переменны-
ми.

// Пример программы установления соединения с


/ / Oracle
345
Раздел 5
//

import Java . sql . *;.


public class TestCon

// Шаг 1: Зарегистрировать JDBC драйвер Oracle


// Класс драйвера должен быть загружен до
// выполнения операций с объектами
//
static
{
try
{
DriverManager . registerDriver (new ora-
cle . j dbc . driver . OracleDriver ( ) ) ;
}
catch (Exceptipn e)
{
System. out .println ( "Ошибка регистрации
драйвера JDBC");
e .printStackTrace ( ) ;

public static void main(String args,[] )


{
try
"
// Шаг 2: Создание объекта соединения
ft
String Connectstring =
" j dbc: oracle: thin: @ora_server: 1521 :ORCL";
String UserlD = "Ul";
String Psw = "U1PSW";
Connection con = DriverMan-
ager .getConnection (Connectstring, UserlD, Psw);
//
// Шаг З: Показать информацию о соединении,
// используя метод DatabaseMetaData
//
346
Создание приложений на языке Java

DatabaseMetaData dma =' con.getMetaData ( ) ;

System. out .println ("ConnectString : " +


dma.getURLO ) ;
System. out .println ("UserlD : " +
dma . getUserName ( ) ) ;
System. out .println ( "Oracle Version : " +
dma. getDatabaseProductVersion ( ) ) ;
//
// Шаг 4: Закрыть соединение
//
con. close { ) ;

catch (SQLException e)
{
// Шаг Х: Универсальный обработчик
// исключительных ситуаций
//
System/out .println ("Хотели как лучше.
System. out. println ("SQLState: " +
e.getSQLState() ) ;
System. out. println ("SQLCODE: " +
e . getMessage ( ) ) ;

Листинг 176. Текст приложения, инициализирующего


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

Предположим, что компиляция приложения осуществля-


ется в каталоге C:\WORK, а текст приложения, представлен-
ного в листинге 176, сохранен в файле TestCon.java. Компи-
ляция приложения выполняется командой:

C:\WORK> Javac TestCon.java

347
Раздел 5

После успешной компиляции в текущем каталоге должен


появиться файл с именем TestCon.class. Выполнение осуще-
ствляется командой:

C:\WORK> Java TestCon

При отсутствии сбоев в работе приложения на терминал


выводятся сообщения, представленные в листинге 177.

C:\WORK> Java TestCon


ConnectString : jdbc:oracle:thin:@
ora server:1521:ORCL
UserID : Ul
Oracle Version : OracleS Enterprise Edition Re-
lease 8 . 0 . 5 . 0 . 0 - Production With the Objects op-
tion
PL/SQL Release 8 . 0 . 5 . 1 . 0 - Production

Листинг 177. Протокол штатного режима'работы при-


ложения

Когда установить соединение с сервером невозможно,


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

C:\WORK> Java TestCon


Хотели как лучше...
SQLState: null
SQLCODE:
Connection refused(DESCRIPTION(TMP=)(VSNNUM=
134238208)(ERR=12500)(ERROR_STACK=(ERROR=
(CODE=12500)(EMFI=4))(ERROR=(CODE=12560)(EMFI=4))
(ERROR=(CODE=530)(EMFI=4))(ERROR=(BDF=T'))))

Листинг 178. Протокол регистрации ошибки при ус


тановлении соединения
348
Создание приложений на языке Java

Если, в приложении указано неправильные имя пользова-


теля или пароль, то на терминал выводятся сообщения, пред-
ставленные в листинге 179:

C:\WORK>java TestCon
Хотели как лучше...
SQLState: 72000
SQLCODE: ORA-01017: invalid username/password;
logon denied

Листинг 179. Протокол регистрации ошибки при ус-


тановлении соединения

Простейший апплет
Отличие апплета от представленных программ состоит в
том, что апплет всегда является расширением специального
класса, описание которого хранится в библиотеке java.applet,
и апплет запускается из некоторой HTML-страницы. Рас-
смотрим пример апплета, который обеспечивает инициализа-
цию сессии взаимодействия пользователя с сервером Oracle,
включая аутентификацию пользователя и вывод информации
о параметрах сессии, то есть полный аналог функций прило-
жения, представленного в листинге 176. Текст примера ап-
плета приведен в листинге 180.
Отличие состоит в описании основного класса (являюще-
гося расширением класса Applet) и использовании класса
paint для вывода данных.

// Апплет TestACon. Java: Апплет выполняет


// соединение с Oracle

import j ava . sql . * ;


, 349
Раздел 5
import java.awt.*;
import Java. applet .*;

public class TestACon extends Applet

// Шаг 1: Зарегистрировать JDBC драйвер Oracle


// Класс драйвера должен быть загружен до
// выполнения операций с объектами
//
public void init ( )
{•
try
{
DriverManager . registerDriver (new ora-
cle. jdbc. driver .OracleDriver ( ) ) ;
}
catch (Exception' e)
- . {
System . out . println ( "Ошибка регистрации
драйвера JDBC");
e.printStackTrace ( ) ;

// Метод paint ( ) обеспечивает вывод


//
public void paint (Graphics g)
{
try

// Шаг 2: Создание объекта соединения


(Connection)

g. drawString ("Готовим доступ", 10, 10) ;

String ConnectString =
"jdbc : oracle : thin : @ora_server : 1 521 : ORCL" ;
String UserlD = "Ul";
String Psw = "U1PSW";

350
Создание приложений на языке Java

Connection con = DriverMan- Т


ager.getConnection(ConnectString,UserlD,Psw);

// Шаг З: Показать информацию о соединении,


// используя метод DatabaseMetaData

DatabaseMetaData dma = con.getMetaData ( ) ;

g. drawstring ("URL : " + dma. getURL { } , 10,


30);
g. drawstring {"Пользователь : " +
dma.getUserName () , 10, 50);
g. drawstring ( "Database Version : " +
dma. get Database Product Version ( ) , 10, 70) ;
//
// Шаг 4: Закрыть соединение
//
con. close ( ) ;
}
catch (SQLException e)
{
// Шаг Х: Универсальный обработчик
// исключительных ситуаций
//
g. drawString ("Хотели как лучше.,.", 10,30);
g. drawstring ("SQLState: " +
e.getSQLStateO ,10, 50);
д. drawString {"SQLCQDE: " +
e.getMessage ( ) , 10, 70);

Листинг 180. Текст апплета, выполняющего соедине-


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

Пусть, как и ранее, компиляция апплета осуществляется в


каталоге C:\WORK. Текст апплета, представленного в лис-
тинге 180, должен быть записан в файле TestACon.java, то

351
Раздел 5

есть совпадать с именем класса. Компиляция приложения вы-


полняется командой:

C:\WORK> Javac TestACon.Java

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


сессии взаимодействия пользователя с сервером Oracle, необ-
ходимо подготовить соответствующую HTML-страницу. Ва-
риант текста страницы, из которой выполняется запуск ап-
плета, приведен в листинге 181. Предполагается, что байт-код
апплета получен в результате, приведенной выше команды и
располагается в том же каталоге, что и текст HTML-
страницы (параметр code тэга applet). Размер окна для выво-
да данных в примере определен 400 на 200 пикселов.

<html>
<title>3arc^oBOK апплета

<body>
<Ы>Тест соединения с Oracle </hl>
<applet code="TestACon. class" width=400
height=200>
</applet>
</body>
</html>

Листинг 181. Текст простейшей HTML-страницы, в


которой, запускается апплет .соединения с
сервером Oracle

Сохраним представленный в листинге 181 текст HTML-


страницы, например, в файле TestACon.html. После этого
можно открывать этот файл в окне браузера и получать при
различных условиях результаты, аналогичные результатам,
представленным в листингах 177,178 и 179.
Перейдем к обсуждению программ, осуществляющих об-
работку данных.
352 ' '
Создание приложений на языке Java

Выполнение SQL-операторов
создания таблиц,
ввода и модификации данных
Выполнение предложений на языке SQL, не содержащих
подставляемых параметров, осуществляется в два этапа: сна-
чала с помощью метода createStatementQ класса Connect соз-
дается объект — предложение SQL, а потом оно выполняется
вызовом соответствующего метода класса Statement.
Основным методом, предназначенным для выполнения
SQL-предложений, осуществляющих создание и уничтожение
объектов, является метод executeUpdate (String).
Рассмотрим пример приложения на языке Java, которое
создает таблицу с заранее определенным именем и атрибута-
ми. Инициализация сессии взаимодействия с сервером Oracle
осуществляется по технологии, представленной выше и про-
иллюстрированной в листинге 176.
Пусть создается таблица с именем ТаЫ, включающая два
столбца: Atl, содержащий строки переменной длины не более
5 символов и At2, содержащий числа.

// Пример приложения, создающего таблицу


/1
import j a v a . s q l . * ;

'public class TestCre

// Шаг 1: Зарегистрировать JDBC драйвер Oracle


//
static

try

,353
12. Заказ № 1628.
Раздел 5
DriverManager . registerDriver (new ora-
cle. jdbc .driver .OracleDriver ( ) ) ;
}
catch (Exception' e)
{
System. out .println ( "Ошибка регистрации
драйвера JDBC" ) ;
e.printStackTrace ( ) ;
}
}, •
public static void main (String args [ ] )
{
try
{
//
// Шаг 2: Создание объекта соединения
//
String ConnectString =
" j dbc : oracle : thin : @ora_server : 1521 : ORCL" ;
String UserlD = "Ul";
String Psw = "U1PSW";
Connection con = DriverMan- . *
ager . getConnection (ConnectString, UserlD, Psw) ;

// Шаг З: Подготовить предложение создания


// таблицы, используя метод
// createStatement
//
String CreTab = "CREATE TABLE Tabl (Atl
varchar(S), At 2 Integer)";
Statement cS = con. createStatement ();

// Шаг 4: Выполнить операцию, •


// используя метод executeUpdate
//
cS. executeUpdate (CreTab) ;
System. out .println ( "Таблица создана . " ) ;
//
// Шаг 5: Освободить ресурсы
//
354
Создание приложений на языке Java
cS. close ( ) ;
con. close ( )';
}
catch (SQLException e)

// Шаг Х: Универсальный обработчик исключи-


тельных ситуаций
//
System. out .println ( "Хотели как лучше...");
System. out. println ("SQLState: " +
e.getSQLStateO ) ;
System. out .println ( "SQLCODE: " +
e . getMessage ( ) ) ;

Листинг 182. Текст 'приложения, создающего таблицу


в базе данных

Текст приложения, представленного в листинге 1 82, дол-


жен быть сохранен в файле TestCre.java. После успешной
компиляции в текущем каталоге должен появиться файл с
именем TestCre.class.
В нормальном варианте работы приложения на терминал
выводятся сообщения, представленные в листинге 183.

C:\WORK> Java TestCre

Таблица создана.

Листинг 183. Протокол штатного режима работы при-


ложения, создающего таблицу

В том случае, когда таблица с именем Tab! уже сущест-


вует в базе данных (например, при втором запуске приложе-
ния), выводится сообщение об ошибке.

355
12*
Раздел 5

C:\WORK> Java TestCon


Хотели, как лучше...
SQLState: 4 2 0 0 0
SQLCODE: ORA-00955: name is already used by an
existing object

Листинг 184. Протокол регистрации ошибки при по-


пытке создания таблицы с именем, совпадаю-
щим 'с уже существующим

Для выполнения вставки, удаления и модификации строк


таблиц используется метод executeUpdate (String).
Например, для вставки строки в таблицу, созданную при-
ложением, представленном в листинге 182, выполним сле-
дующие изменения. Строку

String CreTab =
"CREATE TABLE Tabl (Atl varchar(S), At2 Inte-
ger)";

необходимо заменить на строку


String InsTab = "INSERT INTO TABLE Tabl VALUES
ГаЬс' ,10)";

строки
cS.executeUpdate(CreTab);
System.out.println("Таблица создана.");

заменить на строки
-rf V_ . . . " . : • - - . : •

cS.executeUpdate(Crelns);
System.out.println("Строка вставлена.");

356
Создание приложений на языке Java

После выполнения этих действий можно откомпилиро-


вать и выполнить новое приложение, осуществляющее встав-
ку данных.
Простая выборка данных
Основным методом, предназначенным для выполнения
запросов, является метод executeQuery(String). Этот метод
возвращает экземпляр объекта ResultSet, представляющий
собой результат выполнения запроса.
Класс ResultSet используется для отображения результа-
тов выполнения запроса. С каждым экземпляром класса ассо-
циируется положение курсора.
Для перемещения курсора по экземпляру класса исполь-
зуется метод nextQ класса ResultSet. Применение этого мето-
да приводит к перемещению курсора к следующей строке.
После выполнения запроса курсор находится перед первой
строкой результата.
Извлечение данных, полученных в результате выполне-
ния запроса, обеспечивается специальным методом. Для каж-
дого типа данных языка Java используется ассоциированный
метод get. To есть для типа данных STRING используется ме-
тод getString, для типа данных INTEGER используется метод
getlnteger и т.п.
Рассмотрим пример приложения на языке Java, которое
осуществляет выборку данных из таблицы, созданной прило-
жением, представленным в листинге 182. Предполагается, что
предварительно выполнена вставка строки ('abc', 10) как ука-
зано выше.

// •
// Пример приложения, осуществляющего выборку
//
import java.sql.*;

public class TestSel


357
Раздел 5
{
//
// Шаг 1: Зарегистрировать JDBC драйвер Oracle
//
static
{
try
{
DriverManager.registerDriver(new ora-
cle, j dbc. driver. OracleDriver () ) ;
}
catch (Exception e)
{
System.out.println("Ошибка регистрации
драйвера JDBC");
e.printStackTrace{) ;
•}
}

public static void main(String args[])


{
try
{
//
// Шаг 2: Создание объекта соединения
//
String ConnectString =
"j dbc:oracle:thin:@ora_server:1521:ORCL";
String UserlD = "Ul";."
String Psw = "U1PSW";

Connection con = DriverMan-


ager.getConnection(ConnectString,UserlD,Psw);
//
// Шаг З: Подготовить предложение
// выборки из таблицы, используя
// метод createStatement
//
String SelTab = "SELECT * FROM Tabl";
Statement cS = con. createStatement ();

//
// Шаг 4: Выполнить операцию,
// используя метод executeQuery
358
Создание приложений на языке Java

//
ResultSet RS = cS . executeQuery (SelTab) ;
' System, out. printing Atl " + " At2 ") ;
System. out. println (" ----------- ---- ") ;
while (RS.nextO)
{
System. out .print In (RS. get String (1) +
RS.getString(2) } ;

// Шаг 5: Освободить ресурсы


//
cS. close ( ) ;
con. close ( ) ;
}
catch ( SQLException e )
{
// Шаг Х: Универсальный обработчик исключи-
тельных ситуаций
//
System. out. println( "Хотели как лучше. . . "') ;
System. out. println ("SQLState: " +
e.getSQLStateO ) ;
System. out. println ("SQLCODE: " +
e . getMessage ( ) ) ;

Листинг 185. Текст приложения, осуществляющего


выборку из таблицы Tab!

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


данных ORCL доступна и в ней существует таблица с именем
ТаЫ, на терминал выводятся сообщения, представленные в
листинге 186.

C:\WORK\> Java TestSel

359
Раздел 5
Atl At2

abc 10

Листинг 186. Протокол штатного режима работы


приложения, осуществляющего простую выборку

Приложение, представленное в листинге 185, имеет су-


щественное функциональное ограничение в том смысле, что
информация о структуре таблицы Tab! жестко встроена в
приложение. Если структура таблицы Tab! изменится, то
текст приложения нужно будет изменить, а приложение пере-
компилировать.
•Более гибким будет решение, основанное на извлечении
метаданных о структуре таблицы и именах столбцов из сло-
варя данных. Изменим фрагмент текста шага 4 приложения,
представленного в листинге 185, на фрагмент, представлен-
ный в листинге 187, и назовем новое приложение TestSell
(сохранив его в файле TestSell.Java).

// Шаг 4: Выполнить операцию,


// используя метод executeQuery
//
ResultSet RS = cS.executeQuery(SelTab);
int i;
//
// Получить доступ к метаданным
//
ResultSetMetaData RSMD = RS.getMetaData();
//
/У Определить число столбцов таблицы
//
int numCols = RSMD.getColumnCount();
//
// Вывести имена столбцов
//
for (i = 1; i <= numCols;
{
360
Создание приложений на языке Java
if (i > 1) System. out. print (" ");
System. out .print (RSMD. getColumnLabel (i) ) ;
}
System, out .print In ( "\n ------ - ------- -- — ") ;
//
// Вывести содержимое таблицы
//
while (RS.next.O)
{
for (i = 1; i <= numCols;

if i > 1) System. out. print (" ");


System. out .print (RS. get String (i) ) ;
}
System. out .print In ( "\n") ;

Листинг 187. Изменения, связанные с получением


метаданных о структуре таблицы и именах
столбцов при осуществлении простой выборки
(
Запуск модифицированного приложения приводит к тем
же результатам (представленным в листинге 1 86).
Пусть таблица с именем Tab! модифицирована так, что
она теперь включает три столбца: Atl — содержащий строки
переменной длины не более 5 символов, At2 — содержащий
числа и At3 — содержащий даты. Предположим, что допол-
нительно введена строка ('bed', 20, SYSDATE).
Несмотря на достаточно радикальное изменение таблицы,
модифицированное приложение осталось работоспособным!
При этом в нормальном режиме работы приложения, моди-
фицированного в соответствии с листингом 1 87, будут выве-
дены сообщения, представленные в листинге 188.

C:\WORK> Java TestSell

ATI AT2 'АТЗ

abc 10 null
361
Раздел 5
bed 20 2002-03-21

Листинг 188. Протокол штатного режима работы мо-


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

Параметрические запросы
SQL-предложение может содержать подставляемые па-
раметры. Такое предложение готовится вызовом метода
prepareStatement().
Для подстановки параметров в предложение, подготов-
ленное методом prepareStatement, используются специальные
связывающие методы. Каждому типу данных Java соответст-
вует некоторый связующий метод.
Например, для осуществления подстановки символьного
параметра используется метод setString, для осуществления
подстановки целочисленного параметра — метод setlnt. При
вызове метода, осуществляющего подстановку, первый пара-
метр метода указывает относительный номер параметра ис-
ходного запроса. Например, setString(l, "Abe") приведет к
подстановке строки "Abe" на место первого параметра.
Рассмотрим пример, когда критерий запроса содержит
параметр. Пусть запрос формулируется как SELECT * FROM
Tabl WHERE At2 > X, где значение параметра X вводится
пользователем с терминала. По сути изменения коснулись
только шага 3 базового приложения. Текст приложения, вы-
полняющего подстановку вводимого значения в параметри-
ческий запрос, приведен в листинге 189.

// Пример приложения, выполняющего


// параметрический запрос

import java.sql.*;
'import j ava. io. *;
362
Создание приложений на языке Java

public class TestSel2


{
//
// Шаг 1: Зарегистрировать JDBC драйвер Oracle
//
static
<
try
{
DriverManager.registerDriver(new ora-
cle .j dbc.driver.OracleDriver() ) ;
1
catch (Exception e)
{
System.out.println("Ошибка регистрации
драйвера JDBC");
e.printStackTrace();
}
}
public static void main(String args[])
{
try
{
//
J/ Шаг 2: Создание объекта соединения
. //
String Connectstring =
"j dbc:oracle:thin:@ora_server:1521:ORCL";
String UserlD = "Ul";
String Psw = "U1PSW";
Connection con - DriverMan-
ager. getConnection(Connectstring,UserlD,Psw);
//
// Шаг З: Подготовить предложение создания
// таблицы, используя метод
// prepareStatement
//
String SelTab = "SELECT * FROM Tabl WHERE
At2 > ? ";
PreparedStatement pS =,
con.preparestatement(SelTab);
//
363
Раздел 5
// Шаг 3.1 Ввести значение порога
//
InputStreamReader isr = new InputStream-
Reader (System.in);
BufferedReader br = new Buffere-
dReader(isr);
String st;
System.out.println("Введите пороговое зна-
чение ") ;
st = br.readLine() ;
//
// Шаг 3.2 Выполнить подстановку
//
pS.setString(1,st);
//
// Шаг 4: Выполнить операцию,
// используя метод executeQuery
ResultSet RS = pS.executeQuery();
//
// Получить доступ к метаданным
//
ResultSetMetaData RSMD = RS.getMetaData();
//
// Определить число столбцов таблицы
//
int numCols = RSMD.getColumnCount();
//
// Вывести имена столбцов
//
int i;
for (i = 1; i <= numCols; i++)
{
if (i > 1) System.out.print(" ");
System.out.print
(RSMD..getColumnLabel (i) ) ;
}
System.out.println("\n —") ;
//
// Вывести содержимое таблицы
//
while (RS.nextO)
{
for (i' = 1; i <= numCols;
{
364
Создание приложений на языке Java

if (i > 1) System. out .print (" ");


System. out .print {RS . getString (i) ) ;
}
System. out .print ("\n") ;

// Шаг 5: Освободить ресурсы


//
pS. close ( ) ;
con. close ( ) ;
}
catch (SQLException e).
{
// Шаг Х: Универсальный обработчик исключи-
тельных ситуаций
//
System. out .println ( "Хотели как лучше. . .") ;
System. out. println ("SQLState: " +
e.getSQLStateO ) ;
System. out. println ("SQLCODE: " .,+
e . getMessage ( } ) ;
}
catch (lOException ioe)
{
ioe.printStackTrace () ;

Листинг 189. Приложение, осуществляющее парамет-


рический запрос, значение параметра для ко-
торого вводится пользователем

В нормальном режиме работы приложения, представлен-


ного листингом 1 89, на терминал будут выведены следующие
сообщения.

C:\WORK> Java TestSel2

Введите пороговое значение


12
365
Раздел 5
ATI AT2 АТЗ

bed 20 2002-03-21

Листинг 190. Протокол штатного режима работы при-


ложения, выполняющего параметрический за-
прос

Хранимые процедуры
на языке Java
Поддержка языка Java встроена также в ядро сервера
OracleS (наличие поддержки зависит от версии сервера и
комплекта поставки). В настоящее время активно обсуждает-
ся использование Java для написания хранимых программ в
качестве альтернативы PL/SQL. К преимуществам Java перед
PL/SQL относятся, в частности, большое количество готовых
библиотек, динамическая загрузка классов, расширенные
возможности для работы в сети. К преимуществам PL/SQL
следует отнести его изначальную ориентированность на рабо-
ту внутри базы данных, огромное количество строк PL/SQL-
кода различных приложений, сопровождаемого большим
числом программистов.
Компонент, который осуществляет поддержку Java в ядре
СУБД, называется JServer. JServer осуществляет загрузку
классов Java в базу данных, компиляцию Java-кода, специ-
альным образом поддерживает безопасность выполнения. В
его состав входит виртуальная Java-машина (JVM), которая
запускается для каждой сессии при первом обращении к про-
грамме на языке Java. При этом начинается Java-сессия. При
окончании Java-сессии виртуальная машина уничтожается.
Окончание Java-сессии происходит при окончании сессии в
базе данных, при истечении тайм-аута или при вызове специ-
альной инструкции.пользовательским приложением.
Каждому пользователю базы данных могут быть предос-
тавлены привилегии на выполнение определенных действий в
366
Создание приложений на языке Java

Java-приложениях. Для этого используется два метода: назна-


чение специальной роли или прямое предоставление приви-
легий. Приведем список основных ролей для работы с Java:
— JAVA__ADMIN — все привилегии;
— JAVAUSERPRIV — ограниченный набор привилегий;
— JAVASYSPRIV — расширенный набор привилегий.
С помощью конкретных привилегий можно предоставить
возможность чтения/записи в-указанный файл или каталог,
изменения свойств JVM, чтения свойств класса и т. д. Управ-
лять этими ролями и привилегиями можно двумя способами:
с помощью SQL-предложений и с помощью инструкций Java.
Для первого способа используется специальный пакет
DBMSJAVA.
Приведем пример предоставления пользователю U1 при-
вилегий на чтение/запись для каталога C:\DATA2.

SQL> BEGIN'
2 - DBMS_JAVA.GRANT_PERMISSION('Ul',
3 'java.io.FilePermission','C:\DATA2',
4 'read,write');
5 END;
6 /

PL/SQL procedure successfully completed.

SQL> COMMIT;
Commit complete.

Листинг 191. Предоставление привилегий с помощью


пакета DBMS JAVA

После предоставления/отмены привилегий необходимо


выполнить фиксацию транзакций, так как все изменения от-
ражаются в специальной таблице SYS.JAVA$POLICY$ (там
можно посмотреть назначенные привилегии, однако прямое
изменение данных в таблице не рекомендуется). Обратите

367
Раздел 5

внимание при работе с привилегиями с помощью операторов


GRANT и REVOKE фиксация транзакций производится ав-
томатически.
Для разграничения доступа также можно использовать
Java-класс oracle.aurora.rdbms.security.PolicyTableManager с
аналогичными методами.
Создание хранимой программы с использованием Java
включает в себя несколько этапов:
— создание Java-кода;
—- помещение Java-кода в базу данных;
— предоставление доступа к Java-программе.
В процессе программирования создается исходный текст
Java-класса. Этот класс должен содержать минимум один ста-
тический метод. Для создания функции необходимо, чтобы
метод класса возвращал объект Java-типа, имеющего аналог в
SQL.
Помещение этого кода в базу данных может произво-
диться несколькими способами:
— с использованием специальных операторов SQL;
— с использованием загрузчика loadjava (с предвари-
тельной компиляцией (загружается .class) или без (загружает-
ся .Java)).

Для первого способа применяется SQL-оператор


CREATE JAVA. Для работы с ним необходимо иметь систем-
ные привилегии CREATE PROCEDURE и CREATE TABLE.
Существует три типа команды CREATE JAVA (CLASS,
SOURCE, RESOURCE) для создания соответственно класса,
исходного Java-кода и Java-ресурса (рисунка, файла свойств и
т.п.) из значения типа LOB или текста самой команды. Для
создания .кода хранимой процедуры можно использовать
CREATE JAVA SOURCE (загружается и компилируется ис-
ходный код) или CREATE JAVA CLASS (загружается отком-
пилированный класс из значения типа BFILE). Пример созда-
ния кода хранимой процедуры представлен в листинге 192.

368

V
Создание приложений на языке Java

SQL> CREATE OR REPLACE JAVA SOURCE NAMED "jsl"


2 as public class jcl{
•3 public static String Say(){
4 return "Hello from Oracle Java Support ";
5 }}
6 /
Java created.

Листинг 192. Пример загрузки в базу данных Java-


кода с помощью оператора CREATE JAVA SOURCE

Для загрузки кода с помощью утилиты loadjava требуется


те же привилегии, что и для применения оператора CREATE
JAVA, а также привилегии для операций с записями в табли-
це JAVA$CLASS$MD5$TABL'E, в которой хранятся сведения
о классах. Эти сведения используются для контроля измене-
ний в классах, чтобы при необходимости перекомпилировать
классы или заново не загружать старую версию при повтор-
ной загрузке.
Утилита loadjava имеет такие же параметры, что и опера-
тор CREATE JAVA. К дополнительным "параметрам относят-
ся: строка соединения с базой данных; используемый при
этом драйвер; логические параметры: загружать все указан-
ные файлы или только обновленные; создавать ли общедос-
тупные синонимы для загружаемых объектов и т. п. Пример
использования утилиты loadjava приведен в листинге 193.

D:\ORANT\BINMoadjava.bat -user ul/ul@educ -


verbose cl.class
arguments: '-user' ' u l / u l ' '-verbose' ' e l l . c l a s s '
created :JAVA$CLASS$MD5$TABLE
creating : class ell

369
Раздел 5
created :CREATE$JAVA$LOB$TABLE
loading : class ell

Листинг 193. Загрузка•откомпилированного класса с


помощью утилиты loadjava

Данная команда указывает утилите loadjava соединиться


с базой данных, используя учетную запись пользователя U1, и
загрузить в его схему класс ell. Параметр VERBOSE специ-
фицирует вывод на экран протокола загрузки.
Следует отметить, что возможно создание и компиляция
Java объектов в других схемах. Таким образом, можно ис-
пользовать библиотечные классы, загруженные в какую-либо
схему. При этом для их использования надо будет либо соз-
дать синонимы, либо разрешить их при компиляции.
Удаление объектов Java из базы данных производится
оператором DROP JAVA (CLASS, SOURCE, RESOURCE) или
утилитой dropjava. Пример удаления Java-объектов приведен
в листинге 194.

SQL> DROP JAVA SOURCE "jsl";


Java dropped.

SQL> DROP JAVA CLASS "ell";


Java dropped.

Листинг 194. Пример удаления Java-кода из базы


данных

За этапом загрузки следует этап публикации, который


представляет собой создание хранимой программы, ссылаю-
щейся на статический метод загруженного класса. Эта про-
грамма может представлять собой хранимую процедуру или
функцию, процедуру или функцию в пакете или метод объек-
та. Синтаксис команд создания Java-процедур такой же, как и
при создании обычной хранимой процедуры, отличается
370
Создание приложений на языке Java

только описание тела процедуры. В листинге 195 представле-


на публикация метода Say() класса j c l . После публикации ее
можно использовать как обычную хранимую функцию. Ком-
пиляция класса будет произведена автоматически при первом
обращении к нему.

SQL>CREATE OR REPLACE FUNCTION f l RETURN VARCHAR2


2 AS LANGUAGE JAVA NAME
3 ' j c l . S a y ( ) return j a v a . l a n g . S t r i n g ' ;
4 /
Function created.

SQL> SELECT fl FROM dual;

Fl

Hello from Oracle Java Support

Листинг 195. Публикация'и использование Java-кода

Приведем пример создания хранимой процедуры с пере-


даваемыми и возвращаемыми параметрами. Пусть таблица
Tab! создана предложением:

CREATE TABLE Tab!(Atl VARCHAR2(100));

SQL> CREATE OR REPLACE JAVA SOURCE NAMED


"test_stored_proc" AS
2 import java.sql.*;
3 public class store_proc{
4 private static String query = "";
5 public static void selectData(String
query,String[] answer){
6 try{
7 store_proc.query = query;
8 Connection conn =
9 DriverMan-
ager.getConnection("jdbc:default:connection:") ;
371
Раздел 5
10 Statement stmt = conn.createStatement();
11 ResultSet rset = stmt.executeQuery(query);
12 if (rset.next ()){
. 13 answerfO] = rset.getString(1);
14. }
15 else {
16 answer-[0] = "empty";
17 }
18 stmt = conn.createStatement();
19 stmt.executeUpdate("INSERT INTO Tabl VAL-
UES (' "+answer [0] +"' ) ") ;
20 }
21 catch(Exception e){
22 System.out.println("Error:
"+e.toString().) ;
23 } •
24 }
25
26 public static void selectData(){
27 store_proc.selectData(store_proc.query,new
String[1])T
28 }
29
30 }
31 /
Java created.

Листинг 196. Загрузка Java-кода класса store_proc

В классе store_proc содержится два статических метода и


статическое поле, в котором будут храниться данные между
вызовами второго и первого методов. Первый метод сохраня-
ет запрос в статическом поле, выполняет его, записывает зна-
чение из первого столбца первой строки результата запроса в
таблицу Tabl и возвращает его. Второй метод вызывает пер-
вый метод, но ничего не возвращает. Для работы с таблицами
базы данных в примере используется соединение по умолча-
нию "jdbc:default:connection:", которое является внутренним
каналом базы данных.

372.
Создание приложений на языке Java

Для публикации этого класса выполним следующие дей-


ствия:

SQL> CREATE OR REPLACE PROCEDURE


2 selDataQuery(query IN varchar2,
3 answer IN OUT varchar2)
4 as language .Java name 'store_proc.selectData
5 (Java.lang.String,Java.lang.String[])';
6 /
Procedure created.

SQL>CREATE OR REPLACE PROCEDURE selData AS


2 LANGUAGE JAVA NAME store_proc. selectData (•)';
3 /
Procedure created.

Листинг 197. Публикация класса store_proc

Проверим функционирование опубликованного класса.


Результаты работы его методов представлены в листинге 198.

SQL> DECLARE
2 str VARCHAR2(200);
3 BEGIN
4 selDataQuery('SELECT TO_CHAR(SYSDATE) FROM
dual',str); '
. 5 selData();
6 END;
7 /
PL/SQL procedure successfully completed.

SQL> SELECT * FROM Tabl;


ATI •-•••'

12-03-2002
12-03-2002

Листинг 198. Результат работы методов класса


store_proc
373
Раздел 5

В заключение рассмотрим использование в Java-


программах статических операторов SQL (т.н. "Embedded
SQL in Java" или SQLJ). Для того чтобы запись SQL-
выражений в Java-коде была так же естественна, как и в про-
граммах на PL/SQL, применяется следующая технология:
операторы SQL внутри кода Java записываются по опреде-
ленным правилам, затем транслируются в "чистый" код Java
(один или несколько классов) и только после этого компили-
руются в байт-код.
Пусть таблица ТаЬ2 создана и заполнена следующими
предложениями:

CREATE TABLE Tab2


(Atl VARCHAR2(10), At2 VARCHAR2(10));
INSERT INTO Tab2 VALUES ('A^'B');
INSERT INTO Tab2 VALUES ('C','D');

В листинге 199 представлена программа, с помощью ко-


торой выводятся все записи из таблицы ТаЬ2 с использовани-
ем технологии SQLJ.

SQL> CREATE OR REPLACE JAVA SOURCE NAMED


"test_sqlj_source" AS
2 public class test_sqlj{
3 #sql public static iterator objec- .
tlter(String,String);
4 public static String giveAll()
5 throws Java.sql.SQLException{'
6 objectlter oi=null;
String answer = "";
8 String Atl = "";
9 String At2 = "";
10 #sql oi = {select Atl,At2 from Tab2} ;
11 while (true) {#sql{ FETCH -:oi INTO
:Atl,:At2 };
12 if (oi.endFetchO ) break;
13 answer+= Atl+" - "+At2+"; ";}
14 return answer;}
15 }
'374
Создание приложений на языке Java
16 /
Java created.

SQL> CREATE FUNCTION giveList RETURN VARCHAR2


2 AS LANGUAGE JAVA NAME ' t e s t _ s q l j . g i v e A l l ( )
3 return J a v a . l a n g . S t r i n g ' ;
4 /
Function created.

SQL> SELECT giveList FROM dual;

GIVELIST

A - В; С - D;

Листинг 199. Использование технологии SQLJ

375
Раздел 6

Средства обеспечения
целостности данных

Современный уровень развития распределенной обработ-


ки данных характеризуется размещением логически единой
информационной базы в сетевой среде и асинхронной много-
пользовательской обработкой с развитыми средствами обес-
печения целостности данных. Наличие единой информацион-
ной базы и асинхронной обработки данных ставит сложную
задачу поддержки согласованности данных независимо от
вносимых изменений различными пользователями в различ-
ное время.
Средства обеспечения целостности данных обеспечивают
защиту от непреднамеренного искажения или уничтожения.
Источниками соответствующих угроз являются:
— нарушения нормального режима функционирования
аппаратуры;
— ошибки, связанные с необходимостью обеспечить па-
раллельное проведение операций с единой информационной
базой;
— ошибки, присутствующие в программном обеспече-
нии;
— ошибки администраторов, осуществляющих штатные
операции с базами данных;
— ошибки пользователей при выполнении операций
ввода и модификации данных.
376
Средства обеспечения целостности данных в Oracle

Защита данных от проблем, вызванных нарушениями


нормальной работы аппаратуры, обычно обеспечивается
осуществлением процедур резервного копирования баз дан-
ных. Для создания резервных копий баз данных используются
две основные технологии: оперативное копирование файлов
(или содержимого псевдоустройств для UNIX-систем) и экс-
порт баз данных.
Экспорт баз данных обычно осуществляется в некоторый
специальный формат данных, независимый от особенностей
используемой операционной системы и аппаратной платфор-
мы. Экспорт требует большего времени, но обеспечивает бо-
лее универсальный результат.
Физическое копирование файлов выполняется быстрее,
но доступ к копии требует воссоздания операционной среды:
необходимо наличие соответствующей условиям копирова-
ния операционной системы и файловой структуры. Кроме то-
го, в условиях необходимости постоянной эксплуатации баз
данных этот способ трудно применим.
Проблемы, связанные с необходимостью обеспечить па-
раллельное проведение операций с единой информационной
базой, решаются за счет блокировок и других механизмов
управления многопользовательским доступом к данным.
Для защиты от ошибок администраторов и пользователей
баз данных применяются ограничения целостности. Ограни-
чения целостности — это задаваемые разработчиком правила,
которые проверяются при вставке, изменении или удалении
данных.
Ограничения целостности могут быть сформулированы в
статической (декларативной) или динамической форме. Спо-
собы описания ограничений в статической форме определены
в стандарте SQL92 и более поздних стандартах в области об-
работки данных.
Описание ограничений целостности в динамическом виде
обычно осуществляется в форме создания триггеров. Триггер
—- это программа, автоматически запускаемая сервером баз
данных при наступлении некоторых событий.
377

-

Раздел 6

Рассмотрим проблемы, связанные с распараллеливанием


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

Определение транзакции
и ее роль в СУБД
Транзакция — это последовательность операторов обра-
ботки данных, которые рассматриваются как логически неде-
лимая единица работы с базой данных. В дальнейшем будем
считать, что в роли операторов обработки данных выступают
SQL-предложения, при проведении которых база данных пе-
реводится из одного допустимого состояния в другое. Под
допустимым состоянием понимается такое состояние базы
данных, при котором выполняются ограничения целостности.
Система гарантирует невозможность фиксации некоторой
части действий из транзакции в базе данных. Например, пусть
модификация строк некоторой таблицы оформлена в виде
транзакции. Тогда система гарантирует, что пользователь,
выполняющий выборку из таблицы, будет получать либо
только "старые" данные, либо только "новые". То есть, не-
возможна ситуация, когда в результате запроса возвращается
часть "старых" и часть "новых" данных.
Oracle гарантирует согласованность данных на транзак-
ции. Именно для транзакции данные либо сохраняются в базе
данных в том виде, который доступен всем пользователям,
либо откатываются в состояние, предшествующее началу
транзакции. Если в процессе выполнения транзакции про-
изошел сбой операционной системы или прикладной про-
граммы, после ликвидации последствий сбоя, данные в базе
автоматически восстанавливаются в состояние, предшест-
вующее началу выполнения транзакции.
До тех пор пока транзакция не зафиксирована, ее можно
"откатить" (ROLLBACK), то есть отменить все сделанные
операторами из транзакции изменения в базе данных. Обра-
378
Средства обеспечения целостности данных в Oracle

тите внимание, что смысл фразы "SQL-операторы транзакции


успешно завершены" отличается от смысла фразы "транзак-
ция зафиксирована" (COMMITTED). Успешное выполнение
SQL-операторов означает, что операторы проанализированы,
интерпретированы как правильные, а затем безошибочно ис-
полнены. "Зафиксировать транзакцию" :— означает сделать
изменения, выполненные данной транзакцией в базе данных,
постоянными. Пока транзакция не зафиксирована, результат
ни одного из ее действий не виден другим пользователям.
Например, пусть регистрируется переход работника из
одного подразделения в другое оформленный в виде транзак-
ции, изменения в базе данных организации либо будут прове-
дены в совокупности, либо будут отменены, если в процессе
их проведения будет зафиксирована ошибка. То есть такой
ситуации, когда сотрудник.будет зарегистрирован в двух под-
разделениях сразу (обычно этому соответствует две записи),
не может быть, если удаление "старой" и вставка "новой" за-
писей представлено как транзакция. Отметим, что для систем
типа dBase, изначально ориентированных на ведение локаль-
ных баз данных, проблема согласованности данных, даже в
сетевой среде, либо не возникает вообще, либо решается с
помощью средств операционной системы.

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

Транзакция начинается при поступлении первого SQL-


оператора и завершается при появлении одного из следую-
щих событий:
— выдана команда COMMIT или ROLLBACK;
'— выдана одна из таких команд языка описания данных
(DDL), как CREATE или DROP (при этом фиксируется пре-
дыдущая транзакция);
— завершился оператор DDL (транзакция, содержащая
оператор языка описания данных, автоматически фиксирует-
ся);

379
Раздел 6

-—пользователь завершил сеанс (последняя транзакция


автоматически фиксируется);
— процесс пользователя аварийно завершен (транзакция
автоматически откатывается).
} . -

Как только транзакция завершена, следующий SQL-


оператор начинает новую транзакцию. Если в конце транзак-
ции отсутствуют операторы COMMIT или ROLLBACK, то
нормальное завершение программы приведет к фиксации
транзакции, а аварийное завершение (вызванное, например,
разрывом связи в локальной сети) вызовет откат транзакции.
Если произошел сбой на стороне сервера, то откат транзакции
с использованием сведений из журналов транзакций будет
автоматически выполнен при запуске экземпляра после вос-
становления нормального режима работы сервера.

Предложения SQL,
управляющие транз акциями
Для фиксации или отката транзакции в языке SQL ис-
пользуются предложения COMMIT WORK, SAVEPOINT и
ROLLBACK WORK.
Предложение COMMIT фиксирует транзакцию. Предло-
жение SAVEPOINT сохраняет промежуточную копию со-
стояния задействованных в транзакции объектов базы данных
для того, чтобы впоследствии, при необходимости, можно
было вернуться к состоянию в точке сохранения. Предложе-
ние ROLLBACK выполняет откат транзакции, то есть отме-
няет изменения, выполненные данной транзакцией в базе дан-
ных. Откат транзакции обычно выполняется в том случае,
когда произошла ошибка в приложении, обнаружено наруше-
ние ограничений целостности или обнаружен клинч систем-
ных ресурсов. Для иллюстрации понятия клинча системных
ресурсов рассмотрим пример.

380
Средства обеспечения целостности данных в Oracle

Пусть процесс А в момент времени ti запросил в моно-


польное использование ресурс X. Ресурс X был предоставлен
процессу А. В момент времени t2 > ti процесс В запросил в
монопольное использование ресурс Y. Ресурс Y был предос-
тавлен процессу В. В момент времени tj > i? процесс А запро-
сил в монопольное использование ресурс Y. Поскольку ре-
сурс Y находится в монопольном использовании процесса В,
то процесс А переводится в состояние ожидания. В момент
времени ti > t2 процесс В запрашивает в монопольное исполь-
зование ресурс X. Поскольку ресурс X находится в моно-
польном использовании процесса А, то процесс В переводит-
ся в состояние ожидания. В результате — клинч. Оба процес-
са могут находиться в состоянии ожидания сколь угодно дол-
го.
Предложенный Н. Виртом формальный алгоритм разре-
шения таких конфликтов не всегда приемлем, так как требует
единовременного запроса на все монопольно используемые
ресурсы. Для СУБД такой подход мог бы привести к потере
эффективности обработки данных. Альтернативный подход
состоит в том, что пользовательские приложения должны са-
ми определять ситуацию клинча и выполнять откат транзак-
ции.

Предложение COMMIT WORK

Предложение COMMIT WORK имеет следующий син-


таксис:

COMMIT [WORK]

Ключевое слово WORK может быть опущено. Предложе-


ние COMMIT WORK обеспечивает выполнение следующих
действий:
— фиксируются все изменения в базе данных, сделанные
в текущей транзакции;
— завершается транзакция;
381
Раздел 6

— уничтожаются все точки сохранения для данной


транзакции;
— освобождаются объекты, заблокированные в процессе
выполнения транзакции.

Хорошим стилем разработки кода прикладных программ


является явное завершение транзакций. Рекомендуется выда-
вать предложение COMMIT WORK и перед завершением се-
анса. Использование такой практики обеспечит автоматиче-
ский откат неуспешной транзакции с прогнозируемым ре-
зультатом при аварийном завершении прикладного процесса,
вызванного программным или аппаратным сбоем.
В процессе выполнения транзакции, в которой содержат-
ся операторы изменения данных, происходит выполнение
следующих действий:
— создается копия данных в сегментах отката;
— выполняется формирование соответствующих записей
в журнальный файл;
— производятся изменения в буферах базы данных.

Когда транзакция явно или неявно завершается, выполня-


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

Команда COMMIT также позволяет указывать значение


параметра COMMENT для комментирования подтверждае-
мой транзакции.

382
Средства обеспечения целостности данных в Oracle

Использование предложения SAVEPOINT

Точки сохранения (SAVEPOINT) используются для раз-


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

SAVEPOINT имя_^точки_сохранения

Параметр шля_точки_сохранения содержит идентифика-


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

Предложение ROLLBACK WORK

Это предложение служит для отката транзакции к исход-


ному состоянию или точке сохранения и имеет следующий
синтаксис:

ROLLBACK [WORK] TO имя_точки_сохранения

Использование ключевого слова WORK необязательно.


Использование предложения ROLLBACK приводит к сле-
дующим действиям:
— завершению выполнения транзакции;
— отмене всех изменений в текущей транзакции;
— отмене всех блокировок транзакции.

Проиллюстрируем назначение команд SAVEPOINT и,


ROLLBACK следующими примерами.
383
Раздел б

Пример 1 Пример 2
SQL> INSERT INTO Tab! SQL> INSERT INTO
VALUES(1,1,1); Tabl VALUES(1,1,1) ;
1 row created. ч
1 row created.

SQL> ROLLBACK; SQL> SAVEPOINT si;


Rollback complete. Savepoint created.

SQL> SELECT * FROM SQL> INSERT INTO


TAB1; Tabl VALUES(1,1,1);
no rows selected 1 row created.

SQL> SELECT COUNT (*)


FROM Tabl;

COUNT(*)

SQL> ROLLBACK TO si;


Rollback complete.

SQL> SELECT COUNT(*)


FROM Tabl;

COUNT(*)

Все отмеченные выше технические детали приведены


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

384
Средства обеспечения целостности данных в Oracle

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

Подобные ситуации подробно описаны в стандартах SQL


и имеют собственные названия.
Очевидным решением проблемы согласованного изме-
нения базы данных является формирование очереди пользо-
385
13. Заказ № 1628.
4
• • ' • ' " •
Раздел 6

вателей к каждому ресурсу системы (таблице, представле-


нию, индексу и т. п.)- Недостатком этого решения является
резкое снижение производительности. Если количество поль-
зователей исчисляется десятками или сотнями, то блокировка^
дефицитного ресурса приведет к очень большому времени
ожидания.
Сервер Oracle использует иной метод решения сформу-
лированной проблемы — многоверсионную модель, при ко-
торой в системе может одновременно существовать несколь-
ко различающихся версий данных. Механизм версионности
реализован в Oracle через сегменты отката, в которых хранят-
ся старые версии данных. В случае когда оператор пытается
прочитать данные, модифицированные другими пользовате-
лями за время его работы, старые версии данных на момент
начала запроса считываются из сегментов отката. При этом
Oracle не обеспечивает гарантированного чтения предыдущих
версий данных из-за возможного их затирания в сегментах
отката. В случае затирания в сегментах отката старых версий
данных выдается ошибка "ORA-1555 Snapshot too old, rollback
segment too small". Эта ситуация характерна для выполняю-
щихся длительное время сложных запросов в динамично из-
меняющейся базе данных. Чем дольше выполняется оператор,
тем больше вероятность затирания старых версий данных.
Oracle обеспечивает непротиворечивость данных на уров-
не оператора и на уровне транзакции. Оператор выборки
SELECT всегда считывает непротиворечивые данные — по
спецификации оператора и разработчик не должен беспоко-
иться об этом. Для транзакций используются более сложные
схемы поддержки непротиворечивости в условиях необходи-
мости обеспечить требуемый уровень производительности.
Во многих случаях внутренние механизмы СУБД могут
значительно сократить накладные расходы системы поддер-
жания непротиворечивости данных, если пользователь явно
укажет, какие действия будут выполняться во время транзак-
ции. Для явного указания технологии использования данных
введено понятие задаваемого пользователем уровня изоляции.
386
Средства обеспечения целостности данных в Oracle

Уровень изоляции позволяет найти некоторый компромисс


между степенью изоляции и эффективностью работы. В спе-
цификации стандарта SQL это понятие формализовано и рас-
ширено. По мере уменьшения уровня изоляции сокращается
число проблем, от которых OracleS защищает пользователя.
Всего существует четыре уровня изоляции: SERIALIZABLE;
REPEATABLE READ; READ COMMITTED; READ UN-
COMMITTED.
При использовании сериализованных транзакций Oracle
гарантирует, что результаты параллельного выполнения тран-
закций будут точно такими же, как если бы эти транзакции
выполнялись последовательно. Если приложению во время
транзакции требуется дважды выполнить один и тот же за-
7
прос и при этом необходимо гарантировать, что результаты
будут идентичными независимо от параллельно выполняемых
в базе данных транзакций, то следует установить уровень
изоляции SERIALIZABLE.
Уровень изоляции "повторяемое чтение" (REPEATABLE
READ) является вторым по степени изоляции после уровня
SERIALIZABLE. На этом уровне транзакция не имеет доступа
к промежуточным или окончательным результатам других
транзакций, выполняющих обновления данных. Однако во
время транзакции можно увидеть строку, добавленную в базу
данных другой транзакцией. Поэтому один и тот же запрос к
нескольким строкам, выполненный дважды в течение одной
транзакции, может возвратить различные результаты.
Уровень "завершенное чтение" (READ COMMITTED) яв-
ляется третьим по степени изоляции. На этом уровне транзак-
ция не имеет доступа к промежуточным результатам других
транзакций. Однако окончательные результаты других парал-
лельно выполняемых транзакций могут быть доступны. В те-
чение транзакции дважды можно выполнить запрос и обнару-
жить, что некоторая строка была изменена другим приложе-
нием.
Уровень изоляции "незавершенное чтение" (READ
UNCOMMITTED) является наиболее низким уровнем изоля-
387
13*
Раздел 6

ции. В этом режиме на выполнение транзакции могут повли-


ять как окончательные, так и промежуточные результаты дру-
гих транзакций. В общем случае этот уровень подходит толь-
ко для некоторых приложений со специальными запросами,
где пользователь может позволить, чтобы результаты запро-
сов содержали "грязные" данные. Если важно, чтобы резуль-
таты запроса предоставляли только ту информацию, которая
является окончательной на текущий момент для базы данных,
то не следует использовать этот режим.
В инструкции SET TRANSACTION можно указать, опе-
рации какого типа осуществляет транзакция: выполняет ли
она только запросы на выборку данных (атрибут READ
ONLY) или может выполнять как выборку, так и изменение
(атрибут READ WRITE). Сервер использует эту информацию
наряду со сведениями об уровне изоляции для оптимизации
работы базы данных.
Oracle поддерживает следующие типы транзакций: Тран-
закция, читающая зафиксированные другими транзакциями
данные во время ее работы. Пользователь может явно начать
такую транзакцию при помощи оператора SET
TRANSACTION READ WRITE. Транзакция по умолчанию
(от начала сеанса до первой команды COMMIT/ROLLBACK,
от команды COMMIT/ROLLBACK до следующей команды
COMMIT/ROLLBACK, или до конца сеанса) является тран-
закцией этого типа. Перед началом любой транзакции по
умолчанию неявно выполняется оператор SET
TRANSACTION READ WRITE. Если два оператора SELECT
в разных частях транзакции этого типа обращаются к одним и
тем же строкам в таблице, то возможно получение противо-
речивых результатов. Противоречие возникнет в том случае,
если какой-либо пользователь модифицировал и зафиксиро-
вал изменения этих строк на интервале времени между двумя
вышеупомянутыми операторами SELECT. To есть в рамках
одной транзакции возможно чтение данных, модифицирован-
ных зафиксировавшим изменения другим пользователем.
Пример таких транзакций приведен ниже.
388
Средства обеспечения целостности данных в .Oracle

SQL> SET TRANSACTION SQL> CREATE TABLE


READ WRITE; Tabl(Atl NUMBER, At2 -
VARCHAR2 (200) );
Table, created. '
SQL> SELECT * FROM Tabl;
no rows selected.
SQL> INSERT INTO
Tabl VALUES (1, 'a') ;
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM Tabl;

1 a

Транзакция "только для чтения". Внутри такой транзак-


ции допустимы только запросы, другие операторы языка
DML недопустимы. При обращении операторов SELECT из
различных частей транзакции к одним и тем же строкам дан-
ных Oracle выдает либо одинаковые непротиворечивые дан-
ные, находившиеся в базе данных на момент начала транзак-
ции, либо ошибку ORA-1555. Пользователь может начать та-
кую транзакцию при помощи оператора SET TRANSACTION
READ ONLY и закончить оператором COMNUT/ROLLBACK.

SQL> SET TRANSACTION SQL> CREATE TABLE


READ ONLY; Tabl ( At 1 NUMBER, At2
VARCHAR2(200) ) ;
Table created.
SQL> SELECT * FROM Tabl;
no rows selected.
SQL> INSERT INTO
Tabl VALUES (1, 'a') ;
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM Tabl;
no rows selected.

389
Раздел б .

Сериалюуемая транзакция. Такие транзакции предна-


значены для сериализации обновлений при конкурентной ра-
боте нескольких пользователей с одними и теми же данными.
Способ выполнения набора транзакций называется сериаль-
ным, если результат совместного выполнения транзакций эк-
вивалентен результату некоторого последовательного выпол-
нения этих же транзакций. При помощи этих транзакций, од-
новременно выполняемых разными, пользователями, резуль-
тат модификации данных в базе таков, как если бы соблюда-
лась очередность, то есть сначала один пользователь начал и
закончил транзакцию, после него второй провел свою тран-
закцию, потом третий и т. д. Вообще говоря, процесс сериа-
лизации транзакций очень сложен, и не всегда возможно се-
риализовать одновременно проводимые несколькими пользо-
вателями транзакции. Сериализуемые транзакции всегда
непротиворечивы, то есть все выборки получают данные из
"снимка" базы, сделанного на момент выдачи оператора SET
TRANSACTION ISOLATION LEVEL SERIALIZABLE. При
условии, что запись осуществляется только в таблицы данно-
го пользователя, можно трактовать сериализуемые транзак-
ции как транзакции только для чтения (READ ONLY) с воз-
можностями выдачи операторов DML. Сериализуемая тран-
закция начинается оператором SET TRANSACTION
ISOLATION LEVEL SERIALIZABLE.
Проведенные примеры иллюстрируют еще одно принци-
пиальное различие настольных СУБД и систем промышлен-
ного уровня. Конечно, реальная проблема гораздо сложнее и
многограннее, но ее серьезное обсуждение выходит за рамки
этой книги. Практический же вывод из сказанного состоит в
том, что производительность системы обработки данных, ра-
ботающей с большим количеством пользователей, зависит в
том числе и от правильной настройки работы механизмов па-
раллельной обработки, в частности рационального выбора
типов транзакций.
В большинстве случаев автоматически используемые
Oracle механизмы поддержки параллельной работы вполне
390
Средства обеспечения целостности данных в Oracle

достаточны для решения практических задач. Тем не менее


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

Типы блокировок
Блокировка — это механизм, предназначенный для пре-
дотвращения некорректного изменения данных при парал-
лельной и асинхронной работе пользователей распределенной
системы. Блокировка используется:
— для обеспечения гарантированной неизменности дан-
ных другими пользователями в рамках транзакции;
—*- для обеспечения естественного временного порядка
изменений, проводимых в базе данных.

В большинстве стандартных ситуаций сервер Oracle


обеспечивает необходимые блокировки автоматически и не
требует дополнительных действий пользовательского процес-
са. Однако иногда может потребоваться явное управление
. блокировками для настройки производительности или вы-
полнения специальных требований к прикладной системе.
Чаще всего пользователи блокируют определенные стро-
ки таблиц, используя оператор SELECT ... FOR UPDATE,
или полностью таблицы, используя оператор LOCK TABLE.
Блокировка данных может иметь различный тип. Тип
блокировки определяет, какие действия можно выполнять с
заблокированным ресурсом другим пользователям. Напри-
мер, если один процесс получил исключительную блокировку
некоторой таблицы, никакой другой процесс не сможет изме-
нять строки в этой таблице. Основные типы блокировки при-
ведены в таблице 31.
Использовать блокировки следует в зависимости от логи-
ки приложения. Например, программа пакетного обновления,
391
Раздел 6

которая обращается к каждой строке таблицы, в процессе ра-


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

У блокировки таблицы есть недостаток, состоящий в том,


что все остальные транзакции, которые пытаются модифици-
ровать данные в таблице, должны ждать. Но, поскольку тран-
закция, выполняющая пакетное обновление, обычно работает
быстрее остальных, общая производительность при явной
блокировке таблицы может даже увеличиться.
•Синтаксис оператора .блокировки выглядит следующим
образом:
LOCK TABLE [имя_схемы.]имя_таблицы
IN { тип_блокировки } MODE

Таблица 31. Основные типы блокировок ресурсов


Oracle

Тип блокировки Содержательный смысл


Exclusive (X) Исключительные блокировки разре-
(исключительная) шают выполнять запросы для забло-
кированных объектов, но запреща-
ют любые другие действия.
Share (S) Разделяемые блокировки разрешают
(разделяемая) запросы, но запрещают изменения в
таблицах.
Row Share (RS) Блокировка типа разделения строк
(разделение строк) разрешает параллельный доступ к
392
Средства обеспечения целостности данных в Oracle

таблице. Этот тип запрещает другим


пользователям блокировать таблицу
в исключительном режиме.
Row Exclusive (RX) Исключительные для строк блоки-
(исключительная ровки аналогичны блокировкам ти-
для строк) па разделения строк, но, кроме того,
запрещают блокировку в разделяе-
мом режиме. Эта блокировка при-
меняется при изменении, удалении
и вставке строк.
Share Row Блокировки типа исключительного
Exclusive (SRX) разделения строк используются для
(исключительное просмотра всей таблицы для выбо-
разделение строк) рочных изменений и позволяют
другим пользователям просматри-
вать строки в этой таблице, но не
позволяют блокировать таблицу с
разделяемом типом или с типом для
обновления строк. .

Примеры блокировки данных для изменения в условиях


многопользовательского доступа приведены в .специальной
части раздела "PL/SQL — процедурное расширение языка
SQL".

Ограничения 'целостности
Средства обеспечения целостности баз данных включают
автоматическую поддержку некоторой системы правил, опи-
сывающих допустимость и достоверность хранимых и вводи-
мых значений. Реляционная модель включает некоторые ха-
рактерные правила, вытекающие из существа модели: огра-
ничения домена и ограничения таблицы.
Целостность домена предполагает, что допустимое мно-
жество значений каждого атрибута является формально
393
Раздел 6

определенным. То есть существуют формальные способы


проверки того, что конкретное значение атрибута в базе дан-
ных является допустимым. Строка не будет вставлена в таб-
лицу, пока каждое из значений ее столбцов не будет нахо-
диться в соответствующем домене (множестве допустимых
значений).
Целостность таблицы означает, что каждая строка в
таблице должна быть уникальной. Хотя не все СУБД про-
мышленного уровня требуют выполнения такого ограниче-
ния, возможность уникальной идентификации каждой строки
представляется необходимой для большинства реальных при-
ложений.
Ограничения целостности позволяют гарантировать, что
требования к данным будут соблюдаться независимо от спо-
соба их загрузки или изменения. Рассмотрим предусмотрен-
ные в OracleS типы статических ограничений целостности:
— ограничение на определенность значения атрибута
(NOT NULL);
— ограничение на уникальность значения атрибутов
(UNIQUE);
— ограничение — первичный ключ;
— ограничение —- внешний ключ;
— ограничение целостности, задаваемое предикатом.

Ограничения связываются с конкретной таблицей либо в


момент ее создания, либо создаются оператором ALTER
TABLE. Ограничения целостности могут быть поименованы с
помощью ключевого слова CONSTRAINT. Именование огра-
ничений обычно используется для локализации нарушенного
ограничения в большой системе. Система всегда присваивает
некоторое имя каждому ограничению целостности, но реко-
мендуется явно назначать унифицированные имена ограниче-
ниям, скажем, первичные ключи именовать РК_имя_таблицы.
Пример имени, сформированного по умолчанию, представ-
лен в листинге 201 (U1.SYS_C005873). Пример более осмыс-
394
Средства обеспечения целостности данных в Oracle

ленного именования ограничений целостности приведен в


листинге 202 (PKJTAB1,).
Наличие ограничения NOT NULL для некоторого атрибу-
та приводит к автоматическому запрещению изменений или
вставок строк, содержащих неопределенные значения этого
атрибута. В листинге 200 представлен пример ограничения на
определенность значения атрибута:

SQL> CREATE TABLE Tabl- (Atl VARCHAR2(3) NOT NULL,


2 At2 INTEGER) ;
Table created.

S,QL> INSERT INTO Tabl VALUES ( ' A ' , I) ;


I row created.

SQL> INSERT INTO Tabl VALUES (NULL, 1 ) ;


INSERT INTO Tabl VALUES (NULL, 1)
*
ERROR at line 1:
ORA-01400: cannot insert NULL into

Листинг 200. Пример ограничения на определенность


_ значения атрибута _

Если множество атрибутов (или атрибут) описаны, как


уникальные, сервер автоматически запретит выполнение опе-
рации по вставке строки, содержащей значение атрибутов,
совпадающие с ранее введенными.
Для создания ограничений целостности UNIQUE и
PRIMARY KEY требуется, чтобы владелец таблицы имел ли-
бо квоту для табличного пространства, в котором должен
быть создан ассоциированный индекс, либо системную при-
вилегию UNLIMITED TABLESPACE.
В листинге 201 представлен пример ограничения на уни-
кальность значения атрибута.

395
Раздел 6

SQL> CREATE TABLE Tab! (Atl VARCHAR2(3),


2 At2 INTEGER UNIQUE);
Table created.

SQL> INSERT INTO Tabl VALUES('A1, 1);


1 row created.

SQL> INSERT INTO Tabl VALUES{'A1, 1);


INSERT INTO Tabl VALUES('A', 1)
*
ERROR at line 1:
ORA-00001: unique constraint (Ul.SYS_C005873)
violated

Листинг 201. Пример проверки ограничения на уни-


кальность значения атрибута

Ограничение — первичный ключ описывает совокуп-


ность атрибутов или атрибут, который для данной таблицы
выбран в качестве первичного ключа. Отметим, что в таблице
может быть только один первичный ключ. Первичный ключ
может состоять как из одного столбца, так и из нескольких,
т.е. быть составным. Для OracleS первичный ключ может со-
держать не более 16 столбцов.
Рекомендуется избегать составных первичных ключей.
Их использование менее удобно. В частности, значения со-
ставных первичных ключей не могут назначаться с помощью
последовательностей.
При выполнении вставки новой записи или модификации
атрибутов, входящих в состав первичного ключа, автоматиче-
ски проверяется уникальность набора их значений (для этого
служит ассоциированный индекс) и отсутствие неопределен-
ных (NULL) значений атрибутов, входящих в состав первич-
ного ключа.
Рассмотрим пример автоматической проверки ограниче-
ний, связанных с выбором атрибута в качестве первичного
ключа. Попытка создать еще один первичный ключ отверга-
396
Средства обеспечения целостности данных в Oracle

ется системой. Попытка изменить значение атрибута At2 так,


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

SQL> CREATE TABLE Tab! (Atl VARCHAR2(3),


2 At2 INTEGER,
3 CONSTRAINT pk_tabl PRIMARY KEY (At2));
Table created.

SQL> ALTER TABLE Tabl


2 ADD PRIMARY KEY (Atl);
ADD PRIMARY KEY (Atl)
*-
ERROR at line 2:
ORA-02260: table can have only 6ne primary key

SQL> INSERT INTO Tabl VALUES ('A.1, 1).;


1 row created.

SQL> INSERT INTO Tabl VALUES('В', 2);


1 row created.

SQL> UPDATE Tabl SET At2=2 WHERE At2=l;


UPDATE Tabl SET At2=2 WHERE At2=l
*

ERROR at line 1:
ORA-00001: unrque constraint (U1.PK_TAB1) vio-
lated

Листинг 202. Пример ограничения, связанного с вы-


бором первичного ключа

Ограничение — внешний ключ связывает значения набо-


ров атрибутов двух таблиц: базовой (PARENT TABLE) и про-
изводной (CHILD TABLE). В частном случае одна таблица
может быть и базовой и производной одновременно. Ограни-
чения, определяемые внешними ключами, обычно называют
поддержкой ссылочной целостности.
397
Раздел 6

Ссылочная целостность определяет соотношения между


различными столбцами, когда значения в одном наборе
столбцов должны соответствовать значениям другого набора
столбцов. Если некоторый набор атрибутов производной таб-
лицы объявлен внешним ключом (FOREIGN KEY), то для
каждого его значения должна найтись запись родительской
таблицы с тем же значением ключа.
Например, если в некоторой базе данных, с помощью ко-
торой осуществляется учет населения, есть таблица с пас-
портными данными, то при занесении сведений о новом пас-
порте будет автоматически проверяться существование в таб-
лице со сведениями о физических лицах записи с идентифи-
катором лица, которому принадлежит паспорт.
Рассмотрим пример. Определим таблицу ТаЬ2, у которой
значение атрибута At4 является внешним ключом по отноше-
нию к первичному ключу таблицы Tab!. Ввод данных со зна-
чением внешнего ключа, совпадающим с одним из значений
первичного ключа таблицы Tabl, выполняется успешно. По-
пытка ввести строку в таблицу ТаЬ2 со значением атрибута
At4, которому не соответствует ни одно значение первичного
ключа таблицы ТаЫ, приводит к сообщению об ошибке. Про-
токол взаимодействия с системой представлен в листинге 203.

SQL> CREATE TABLE ТаЫ (Atl VARCHAR2(3) NOT NULL,


2 At2 INTEGER,
3 CONSTRAINT pk_tabl PRIMARY KEY (At2));
Table created.

SQL> CREATE TABLE Tab2 (At3 VARCHAR2 (3)",


2 At4 CONSTRAINT fk_tab2 REFERENCES Tabl(At2));
Table created.

SQL> INSERT INTO Tab2 VALUES('B', 10);


INSERT INTO Tab2 VALUES('B', 10)
*

ERROR at line 1:
398
Средства обеспечения целостности данных в Oracle
ORA-02291: integrity constraint (U1.FKJTAB2) vio-
lated - parent key not found

Листинг 203. Пример проверки ограничения — внеш-


него ключа •

Ограничение ссылочной целостности не только опреде-


ляет допустимые значения во внешнем ; ключе производной
таблицы, но и действие при операции с первичным ключом
базовой таблицы.
Например, ссылочное действие каскадного удаления ог-
раничения — внешнего ключа определяет, что при удалении
строки базовой таблицы должны удаляться все зависящие от
нее строки производной таблицы. Рассмотрим пример, иллю-
стрирующий каскадное удаление. Определим соответствую-
щую модификацию таблицы ТаЬ2. Тогда удаление строки в
базовой таблице приводит к автоматическому удалению
строк в производной таблице. Пример использования ограни-
чения внешнего ключа с опцией каскадного удаления пред-
ставлен в листинге 204.

SQL> DROP TABLE Tab2;


Table dropped.

SQL> CREATE TABLE Tab2 (At3 VARCHAR2(3) ,"


2 At4 CONSTRAINT fk_tab2
3 REFERENCES t a b l ( a t 2 ) ON DELETE CASCADE);
Table created.

SQL> INSERT_INTO Tabl V A L U E S ( ' A 1 , 1);


1 row created.

SQL> INSERT INTO Tab2 V A L U E S ( ' B ' , 1);


1 row created.

SQL> SELECT * FROM Tab2;

399
Раздел 6
АТЗ АТ4

В 1

SQL> DELETE FROM Tab! WHERE At2=l;


1 row deleted.

SQL> SELECT * FROM Tab2;


no rows selected

Листинг 204. Пример использования ограничения


внешнего ключа с опцией каскадного удаления

Если по внешнему ключу не определены никакие допол-


нительные ограничения, то любое количество строк в подчи-
ненной таблице может ссылаться на одно и то же значение
первичного ключа. В этом случае устанавливается отношение
"один ко многим". Когда по внешнему ключу определено ог-
раничение UNIQUE, лишь одна строка в подчиненной табли-
це может ссылаться на данное значение первичного ключа.
Таким образом устанавливается связь "один к одному" между
.первичным и внешним ключами. Для удаления таблицы, на
строки которой ссылаются строки другой таблицы, требуется
указание конструкции CASCADE CONSTRAINTS. Пример
удаления таблицы, для которой существует зависимая табли-
ца, представлен в листинге 205.

SQL> DROP TABLE tabl;


DROP TABLE tabl ~.
*
ERROR at line 1:
ORA-02449: unique/primary keys in table refer-
enced by foreign keys

SQL> DROP TABLE tabl CASCADE CONSTRAINTS;


Table dropped.

Листинг 205. Пример удаления таблицы, для которой


существует зависимая таблица

400
Средства обеспечения целостности данных в Oracle

Ограничение целостности, задаваемое предикатом, по-


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

CHECK (предикат)

Параметр предикат может быть любым предикатом,


определенным на множестве атрибутов таблицы.
Ограничение CHECK имеет следующие ограничения: оно
должно быть выражением, вычисляемым над значениями
вставляемой или обновляемой строки, не должно содержать
подзапросов и ссылаться на последовательности.
В листинге 206 представлен пример добавления ограни-
чения целостности в таблицу ТаЫ. Попытка ввести данные,
не удовлетворяющие ограничению целостности, отвергается
системой. Ввод данных, для значений которых предикат при-
нимает истинное значение, выполняется.

SQL> ALTER TABLE ТаЫ


2 ADD CONSTRAINT Atl_check CHECK ( A t l O ' W , 1 ) ;
Table -altered.

SQL> INSERT INTO Tab! VALUES ( ' W , 1) ;


INSERT INTO Tabl VALUES ( ' W , 1)
* ~\
ERROR.at line 1:
ORA-02290: check constraint (U1.AT1_CHECK) vio-
lated

SQL> INSERT INTO Tabl VALUES(NULL, 1);


1 row created.

Листинг 206. Пример использования ограничения це-


лостности, заданного предикатом -

401
Раздел б

По умолчанию проверка ограничений целостности про-


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

SQL> CREATE TABLE Tabl (Atl INT UNIQUE


2 INITIALLY DEFERRED DEFERRABLE);
Table created.

SQL> INSERT INTO Tabl VALUES(1);


1 row created.

SQL> INSERT INTO Tabl VALUES(1);


1 row created.

SQL> COMMIT;
COMMIT
*
ERROR at line 1:
ORA-02091:' transaction rolled back
ORA-00001: unique constraint (Ul.SYS_C005885)
violated

Листинг 207. Пример выполнения отложенной провер-.


ки ограничений целостности.

Такая проверка удобна, например, при изменении значе-


ния первичного ключа для записи, у которой существуют
подчиненные записи в другой таблице. В этом случае можно
выполнить каскадное изменение значений ключей и зафикси-
ровать транзакцию, что было невозможно в предыдущих вер-
сиях Oracle.
Для включения отложенной проверки ограничений тре-
буется при определении таблицы указать следующую конст-
рукцию:
402
Средства обеспечения целостности данных в Oracle
CONSTRAINT . . . [ { [[NOT] DEFERRABLE]
[INITIALLY {IMMEDIATE|DEFERRED}]
| [ I N I T I A L L Y {IMMEDIATE|DEFERRED}]
[[NOT] DEFERRABLE]} ]

По умолчанию ограничения целостности создаются не


откладываемыми. Для создания откладываемого ограничения
при его объявлении надо использовать ключевое слово
DEFERRABLE. Если транзакция не начинается с команды
SET CONSTRAINTS, то для откладываемого ограничения
Oracle использует стандартный алгоритм проверки. При этом
данные- проверяются на соответствие ограничению в конце
каждой команды DML. Если при определении ограничения
были использованы ключевые слова INITIALLY DEFERRED,
данные проверяются на соответствие ограничениям при фик-
сации транзакции.
При проведении массовых операций над данными иногда
целесообразно некоторые ограничения целостности отклю-
чить, провести операции, а затем опять включить ограниче-
ния.

Массовая загрузка данных


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

403
Раздел 6

При использовании такого подхода процесс загрузки


данных включает решение двух задач: собственно загрузка
данных и проверка достоверности загруженных данных.
Для загрузки данных предназначена утилита Oracle
SQL*Loader. SQL*Loader способен загружать данные самых
различных форматов. Кроме того, перед загрузкой записи
можно логически объединять и обрабатывать средствами язы-
ка SQL.
Для того чтобы запустить SQL*Loader, нужно набрать в
командной строке sqlldr (конкретное имя программы зависит
от поставки) и указать параметры загрузки данных.
Например,

D:\ORANT\BIN\SQLLDR80 USERID=system/manager§educ
CONTROL=l.ctl LOG=l.log

В качестве параметров здесь указан пароль и имя пользо-


вателя, который будет производить загрузку, управляющий
файл и файл протокола. Для настройки параметров загрузки
предназначен управляющий файл (control file). В нем указы-
ваются символьный набор, тип и способ размещения данных,
таблицы, в которые будет осуществляться загрузка и т. п. Па-
раметры, которые обычно передаются SQL*Loader в команд-
ной строке, также могут быть указаны в управляющем файле.
Форматы данных, используемые при загрузке, могут быть
самыми различными — текстовые файлы с записями, dbf-
файлы, файлы, загружаемые как LOB и т. п. Наиболее часто
используются следующие форматы: текстовые файлы с запи-
сями переменной длины и текстовые файлы с записями фик-
сированной длины.
Файлы с записями переменной длины включают записи
со значениями атрибутов, разделенных некоторыми стан-
дартными разделителями (как правило, запятой). Строки раз-
деляются стандартным разделителем. Значения атрибутов,
имеющих символьный тип, и даты, могут заключаться в

404
Средства обеспечения целостности данных в Oracle

двойные кавычки. NULL-значения, как правило, отображают-


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

CREATE TABLE Tabl (Atl NUMBER,


At2 NUMBER, At3 VARCHAR2(10));

Требуется загрузить в нее данные из файла 1 .dat, который


имеет такое содержимое:

1;Александр
2;Михаил
3;Мария
4;Ирина

Пример управляющего файла для загрузки записей пере-


менной длины в таблицу ТаЫ представлен в листинге 208:.

LOAD DATA CHARACTERSET CL8MSWIN1251


INFILE ' l . d a t '
INTO TABLE Tabl
TRUNCATE
FIELDS TERMINATED BY ";"
TRAILING NULLCOLS •
(Atl INTEGER EXTERNAL,
At2 SEQUENCE ( M A X , 1 ) ,
At3 CHAR)-

Листинг 208. Управляющий файл для загрузки данных


переменной длины

После загрузки в таблице ТаЫ находятся следующие


данные:

'405
Раздел 6

SQL>, SELECT * FROM Tabl;


ATI AT2 AT3

1 1 Александр
2 2 Михаил
/ 3 3 Мария
4 4 Ирина

Листинг 209. Таблица Tab! после загрузки

Управляющий файл начинается с конструкции LOAD


DATA. Параметр INFILE определяет файл, в котором разме-
щаются данные. Если данные находятся в нескольких файлах,
требуется последовательность параметров INFILE.
Параметр CHARACTERSET определяет кодировку сим-
вольных данных. При необходимости, в ходе загрузки данные
могут быть перекодированы.
Параметр INTO TABLE определяет таблицу, в которую
будут загружены данные. Таблица должна быть создана зара-
нее. После названия таблицы указывается способ вставки в
нее записей: APPEND (записи добавляются в таблицу, кото-
рая, возможно, уже содержит данные), INSERT (перед загруз-
кой таблица не должна содержать записей), REPLACE (перед
загрузкой все записи в таблице удаляются с использованием
команды DELETE), TRUNCATE (перед загрузкой все записи
в таблице удаляются с использованием команды
TRUNCATE).
Далее в управляющем файле следует перечисление атри-
бутов записей, накладываются на них логические условия,
приводятся ссылки на вложенные данные, специфицируется
использование встроенного генератора последовательностей,
И т. д. С полным списком параметров SQL*Loader можно оз-
накомиться в руководстве Oracle Utilities, Release 8.
В ходе загрузки SQL*Loader ведет протокол. Его распо-
ложение специфицируется параметром log командной строки.

406
Средства обеспечения целостности данных в Oracle

Протокол загрузки из предыдущего примера приведен в лис-


тинге 210.

SQL*Loader: Release 8.0.5.0.0 - Production on.Thu


Feb 14 13:54:29 2002 (c) Copyright 1998 Oracle
Corporation. All rights reserved.
Control. File: l.ctl
Character Set CL8MSWIN1251 specified for all in-
put .
Data File: l.dat
Bad File: l.bad
Discard File: none specified (Allow all dis-
cards)
Number to load: ALL '
Number to skip: 0
Errors allowed: 50
Bind array: 64 rows, maximum of 65536 bytes
Continuation: none specified
Path used: Conventional

Table TAB1, loaded from every logical record.


Insert option in effect for this table: TRUNCATE
TRAILING NULLCOLS option in effect
r
Column Position Len Rerm Encl Datatype,

ATI FIRST * CHARACTER


AT 2 SEQUENCE (MAX, 1)
AT3 NEXT * CHARACTER

Table TABl:
4 Rows successfully loaded.
0 Rows not loaded due to data errors.
0 Rows not loaded because all WHEN clauses were
-failed.
0 Rows not loaded because all fields were null.

Space allocated for bind array: 65219 bytes(121


rows)
Space allocated for memory besides bind array:
0.bytes

407
Раздел 6
Total logical records skipped: 0
Total logical records read: 4
Total logical records rejected: 0
Total logical records discarded: 0
Run began on Thu Feb-14 13:54:29 2002
Run ended on Thu Feb 14 13:54:32 2002

Elapsed time was: 00:00:03.10


CPU time was: 00:00:00.00

Листинг 210. Протокол загрузки данных

При загрузке SQL*Loader производит проверку данных- в


две стадии. Сначала проверяется соответствие форматов и
типов данных в файле форматам и типам данных, указанным
в управляющем файле. Если какая-либо запись не удовлетво-
ряет этому условию, то она отстраняется от загрузки и поме-
щается в файл не прошедших проверку записей (Bad File). В
противном случае производится попытка вставки данных в
таблицы базы данных. При этом производится проверка огра-
ничений целостности. Если данные не соответствуют им, то
они также отстраняются от загрузки и помещаются в файл
плохих записей. При достижении специфицированного коли-
чества ошибок загрузка прекращается. Число допустимых
ошибок регулируется параметром ERRORS (по умолчанию он
равен 50). В самом управляющем файле тоже могут быть на-
ложены условия на значения атрибутов записей. Если записи
не удовлетворяют им, то они помещаются в файл некоррект-
ных данных (Discard File). Форматы обоих файлов идентичны
формату исходных файлов данных. Поэтому после отгрузки
их можно отредактировать и загрузить повторно.
Для получения значений числовых данных при загрузке
можно использовать встроенный генератор последовательно-
стей SQL*Loader. Обратите внимание, этот генератор не име-
ет никакого отношения к последовательностям, хранимым-в
базе данных. Его использование не приводит к изменению их
состояний.
408
Средства обеспечения целостности данных в Oracle

Если возникает задача загрузки больших объемов данных


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

Экспорт/импорт данных
Одна из важных задач, решаемых администратором баз
данных, — обеспечение восстановления базы после аппарат-
ного или программного сбоя. Решение задачи восстановления
данных может быть выполнено различными способами. В
качестве необходимой основы для выполнения операции вос-
становления должна быть некоторая логическая копия базы
данных.
Копия может содержать информацию обо всей или части
базы данных, звписанную на некоторый носитель с помощью
специальных утилит. Администратор баз данных должен ре-
гулярно, в соответствии с некоторым регламентом выполнять
контрольное копирование. Для критически важных и особо
ценных данных обычно поддерживается несколько копий ба-
зы.
Для реализации экспорта/импорта данных предназначены
утилиты Oracle IMPORT и EXPORT. Результат экспорта
409
Раздел 6

представляет собой совокупность файлов в бинарном форма-


те, поддерживаемом Oracle. По умолчанию создается файл с
именем expdat.dmp.
Эти утилиты могут быть использованы для создания ре-
зервных копий базы данных, перемещения объектов и данных
между схемами (то есть тиражирования таблиц, индексов,
привилегий, хранимых программ и других объектов в другие
схемы и другие базы данных Oracle), для дефрагментации
табличного пространства (достаточно экспортировать дан-
ные, а затем импортировать их обратно). Важной особенно-
стью является то, что результат экспорта является платфор-
монезависимым и может быть использован для серверов, ра-
ботающих под управлением различных операционных сис-
тем.
Имеется два способа работы с этими утилитами — инте-
рактивный и автоматический. При первом способе пользова-
тель непосредственно задает параметры экспорта/импорта,
отвечая на вопросы в диалоговом режиме. При втором спосо-
бе параметры считываются из предварительно созданных
файлов. Следует отметить, что второй способ более гибкий,
так как позволяет специфицировать параметры, которые не
запрашиваются в диалоговом режиме.
Для запуска утилиты экспорта необходимо в командной
строке набрать команду ехр80 (конкретное имя программы
зависит от операционной системы и версии Oracle). В этом
случае утилита перейдет в интерактивный режим и будет за-
прошена информация, необходимая для подключения к базе
данных. Существует три вида экспорта:
— FULL — экспортируются все объекты, структуры и
данные в пределах базы данных. При экспорте данного вида
экспортируются и табличные лространства. При этом необ-
ходимо, чтобы пользователь обладал ролью
EXP_FULL_DATABASE. По умолчанию этой ролью обладает
пользователь SYSTEM;

410
Средства обеспечения целостности данных в Oracle

— OWNER — экспортируются только объекты, принад-


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

D:\ORANT\BIN\EXP80.EXE

Export: Release 8.0.5.0.0 - Production on Thu Feb


14 15:21:54 2002
(c) Copyright 1998 Oracle Corporation. All
rights reserved.
Username: system/manager@educ

Connected to: OracleS Enterprise Edition Release


8.0.5.0.0
Production 15:
With the Objects option
PL/SQL Release 8.0.5.1.0 - Production
Enter array fetch buffer size: 4096 > 4096

Export file: EXPDAT.DMP > EXPDAT.DMP


(l)E(ntire database), (2)U(sers), or (S)T(ables):
(2)U > Т

Export table data (yes/no): yes > yes

Compress extents (yes/no): yes > yes .

Export done in CL8MSWIN1251 character set and


CL8MSWIN1251 NCHAR character set

About to export specified tables via Conventional


Path ...
Table(T) or Partition(Т:Р) to be exported: (RE-
TURN to quit) > TAB1
411
Раздел 6

' . . exporting table


TAB1 4 rows exported
Table(T) or Partition(Т:Р) to be exported: (RE-
TURN to quit) >

Export terminated successfully without warnings.

Листинг 211. Использование утилиты экспорта в ин-


терактивном 'режиме

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

D:\ORANT\BIN\EXP80.EXE USERID=system/manager@educ
PARFILE=exp.par

Рассмотрим структуру файла параметров экспорта с базо-


вым набором параметров. Полный список параметров файлов
утилиты EXPORT, а также дополнительная информация для
пользователя представлены в руководстве Oracle Utilities,
Release 8.
Параметр INCTYPE=(COMPLETE | CUMULATIVE |
INCREMENTAL) — указывает тип экспорта (инкременталь-
ный, кумулятивный или полный). При полном экспорте экс-
портируется вся база данных. При инкрементальном — толь-
ко те таблицы базы данных, которые изменялись с момента
последнего инкрементального экспорта. В том случае, если
такой экспорт не проводился, экспортируются те таблицы,
которые изменились, начиная с последнего кумулятивного
экспорта. При кумулятивном экспорте обрабатываются все
таблицы, изменившиеся с момента последнего полного экс-
порта. С помощью гибкой стратегии создания файлов экспор-
та различных типов достигается возможность гарантирован-
ного восстановления базы данных на некоторый момент вре-
мени и экономия пространства для хранения копий.

412
Средства обеспечения целостности данных в Oracle

Параметр ТАВЬЕ8=с«мсок_/яаблмг/ определяет, какие


таблицы и секции следует экспортировать. Этот параметр ис-
пользуется для табличного вида экспорта.
Параметр COMPRESS (Y/N) определяет, изменять ли
сценарий создания таблиц при импорте так, чтобы после им-
портирования существовал один экстент.
Параметр INDEXES (Y/N) определяет, создавать ли ин-
дексы при последующем импорте. Следует отметить, что ин-
дексы, которые автоматически создаются Oracle, например
индексы, ассоциированные с первичными ключами, экспор-
тируются независимо от значения этого параметра.
Параметр STATISTIC (Y/N) определяет, собирать ли ста-
тистику для оптимизатора после импорта.
Параметр L,OG=mtx_(pawia определяет нахождение фай-
ла, в который будет осуществляться вывод протокола экспор-
та.
Параметр CONSISTENT (Y/N) — экспортировать ли дан-
ные на момент экспорта. В противном случае в резервной ко-
пии будут данные, которые изменялись в течение экспорта.
По умолчанию устанавливается N.
Параметр USERID требуется для подключения к базе
данных. В целях безопасности рекомендуется передавать его
в командной строке, а не указывать в файле параметров. За-
дается как имя_пользователя/паролъ@строка_связи.
Параметр ROWS (Y/N) — будут ли экспортироваться
данные таблиц и объектов. В противном случае будут экспор-
тированы только определения объектов.
Параметр FlLE=uMxjpaivia, в который осуществляется
экспорт.
Параметр РАКР1ЬЕ=иуия_фаша — файл, из которого бу-
дут считываться параметры.
Параметр GRANTS (Y/N) — будут ли экспортироваться
привилегии для объектов.
Экспортируемые данные могут быть не только содержи-
мым одной или нескольких таблиц базы данных, но и резуль-

413
Раздел 6

татом любого синтаксически правильного запроса. Пример


файла параметров приведен в следующем листинге.

USERID=system/manager@educ
LOG=export.log
FILE=expdat.dmp
TABLES=Tabl
INDEXES=N

Листинг 212. Файл параметров экспорта

Протокол этой операции представлен в листинге 213.

Connected to: OracleS Enterprise Edition Release


8.0.5.0.0 Production .
With the Objects option
PL/SQL Release 8.0.5.1.0 - Production
Export done in CL8MSWIN1251 character set and
CL8MSWIN1251 NCHAR"character set
Note: indexes on tables will not be exported
N
About to export specified tables via Conventional
Path .,.
. . exporting table
TAB1 4 rows exported
Export terminated successfully without warnings.

Листинг 213. Протокол экспорта

Для восстановления базы данных 'с использованием ре-


зервных копий, созданных утилитой EXPORT, служит утили-
та IMPORT. Во многом порядок работы с ней аналогичен ра-
боте с EXPORT, но вместе с тем имеется ряд особенностей.
Для запуска IMPORT необходимо в командной строке
набрать impSO и далее указать необходимые параметры.

414
Средства обеспечения целостности данных в Oracle
D:\ORANT\BIN\imp80 USERID=system/manager@educ
FILE=expdat.dmp

Аналогично EXPORT, утилита IMPORT поддерживает


три режима экспортирования (в зависимости от заданных па-
раметров). Виды операции для экспорта и импорта, естест-
венно, совпадают. Существенное различие состоит лишь в
том, что для импорта вида FULL требуется наличие роли
IMP_FULL_DATABASE.
Рассмотрим синтаксис команды разгрузки данных с базо-
вым набором параметров. Полный список параметров файлов
утилиты IMPORT, а также дополнительная информация пред-
ставлены в руководстве Oracle Utilities, Release 8.
Параметр ANALYZE (Y/N) — проводить ли для импор-
тируемых таблиц сбор статистики для оптимизатора.
Параметр ¥1ЪЕ=имя_фаша, в котором находятся импор-
тируемые объекты базы данных.
Параметр INDEXES (Y/N) — создаются ли индексы для
импортируемых таблиц.
Параметр ТАВЕЕ8=сямсол:_/ийгблмг/ — список таблиц (че-
рез запятую) или секций секционированных таблиц, которые
буду импортированы. Для Windows список таблиц требуется
заключить в скобки.
Параметр USERID требуется для подключения к базе
данных. Имеет вид имя_полъзователя/пароль@строка_связи.
В целях безопасности рекомендуется передавать его в ко-
мандной строке, а не указывать в файле параметров. ,
Параметр TOUSER — пользователь, в схему которого
будет произведен импорт.
Параметр FROMUSER — импортируются те объекты,
владельцем которых является этот пользователь.
Параметр LOG определяет нахождение файла, в который
будет осуществляться вывод протокола экспорта.
Виды импорта устанавливаются параметрами
FROMUSER, TABLES, FULL. В режиме владельцев импор-
тируются таблицы, владельцем которых является указанный
415
Раадел 6

пользователь. В режиме таблиц импорт» >уются указанные


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

USERID=system/manager@educ
FILE=expdat4 dmp
TABLES=(Tab!,Tab2)
INDEXES=n
LOG=import.log

Листинг 214. Файл параметров импорта

В процессе импорта данных все действия производятся в


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

416
Раздел 7

Методы повышения
производительности

Под управлением сервера Oracle могут храниться и обра-


батываться значительные объемы данных. Управление боль-
шими и сверхбольшими базами данных, проектирование и
разработка приложений для них имеет свои особенности. По-
этому, чтобы не допустить ухудшения характеристик как от-
дельных приложений, так и всей системы в целом, требуется
использование специальных методов, повышающих скорость
доступа к данным.
Как правило, используется комплексный подход. Под
этим понимается оптимизация всех звеньев системы — сер-
верной, клиентской и сетевой части. Существует целый ряд
способов настройки производительности: настройка рабочих
станций клиентов, сетевого транспорта, оптимизация клиент-
ских приложений, оптимизация серверного PL/SQL-кода и
SQL-выражений. Для настройки клиентских компьютеров и
сети требуется обновление аппаратной части и системного
программного обеспечения. Для улучшения работы клиент-
ских приложений необходимо переработать их исходный код,
как правило, написанный на языке программирования высо-
кого уровня, или применить специальные средства оптимиза-
ции программ для конкретной аппаратной конфигурации. Та-

417
14. Заказ № 1628.


- - . .
Раздел 7

кие средства есть практически во всех современных интегри-


рованных средах разработки.
Для оптимизации серверной части необходима настройка
параметров базы данных Oracle, перепроектирование струк-
туры базы данных и переработка серверного кода. Настройку
базы данных обычно выполняют администраторы Oracle на
основе статистики из словаря данных, а перепроектирование
и переработку серверного кода — производители приложе-
ний.
Далее будут рассмотрены вопросы оптимизации взаимо-
действия с сервером базы данных с помощью SQL-
выражений. Объясняется это тем, что, как показывает опыт,
это наиболее "узкое" место. По разным оценкам, общая про-
изводительность системы на 15-20% зависит от настройки
базы данных, а остальные 80-85% приходятся на приложе-
ние. Поэтому, прежде всего, требуется настроить приложение
в процессе его создания.

Оптимизатор
В разделе "Архитектура распределенных систем обработ-
ки данных" рассматривалась последовательность прохожде-
ния оператора SQL через архитектуру сервера Oracle. После
этапа синтаксического анализа на основе информации из сло-
варя базы данных для разобранного оператора создается план
его выполнения. Эту работу выполняет оптимизатор.
Оптимизатор представляет собой программный продукт,
который является важнейшей частью сервера Oracle и пред-
назначен для оптимизации — поиска наиболее эффективного
способа доступа к данным. Оптимизатор должен выбрать та-
кую последовательность действий, которая обеспечит самый
эффективный путь доступа к данным, и сформировать план
выполнения запроса, основанный на найденных методах дос-
тупа. Под методом доступа (access path) подразумевается
вариант алгоритма доступа, а под планом выполнения
418
Методы повышения производительности

(execution plan) — последовательность выполняемых дейст-


вий, которые обеспечивают выбранные методы доступа. Су-
ществует два основных вида оптимизаторов:
Оптимизатор по правилам (rule-based) — оптимизатор,
основанный на анализе жестко заданных правил. Этот опти-
мизатор выбирает методы доступа на основе предположения
о статичности базы данных и в соответствии с заданной сис-
темой правил выбора методов доступа.
Оптимизатор по стоимости (cost-based optimizer) — оп-
тимизатор, основанный на анализе накладных затрат систе-
мы. Для этого оптимизатора выбор метода доступа основан
на хранимой внутренней статистике. Под статистикой пони-
маются точные или аппроксимированные сведения о распре-
делении значений данных в таблицах. Сервер Oracle может
собирать статистику двумя способами: путем оценки, осно-
ванной на произвольной выборке данных, и путем точных
вычислений.
Для управления оптимизатором используются специали-
зированные подсказки (hint), которые записываются в SQL-
выражениях. Подсказки влияют на выбор сервером конкрет-
ного способа обращения к данным. Представленный в лис-
тинге 215 пример содержит выражение SELECT, включаю-
щее подсказку оптимизатору для использования индекса.
Здесь предполагается, что для указанной таблицы существует
только один индекс. Для задания в подсказке конкретногр
индекса из нескольких имеющихся следует использовать имя
таблицы и имя нужного индекса.

SQL> SELECT /*+ index*/ At2,At3


2 FROM Tab! WHERE Atl=10;

Листинг 215. Запрос с подсказкой для оптимизатора

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


сразу же после начала оператора SQL (ключевых слов
419
14*
Раздел 7
DELETE, UPDATE, SELECT), и обозначается символом "+".
после конструкции, начинающей комментарий. В предыду-
щем примере подсказка начинается с символов "/*", за кото-
рыми следуют символы "+", пробел и заканчивается симво-
лами "*/". Пример другой записи подсказки приведен в лис-
тинге 216.

SQL> SELECT --+ index


2 At2, At3 FROM Tabl WHERE Atl=10;

Листинг 216. Другой способ записи подсказки

Оптимизатор воспринимает только один набор подсказок,


оформленный как комментарий, для данного SQL-выражения
или блока выражений. Например, для составного запроса, со-
стоящего из двух подзапросов, объединенных оператором
UNION, подсказка в первом выражении будет учитываться,
при формировании плана только для него и не будет учиты-
ваться для второго. Подсказки с неверным синтаксисом игно-
рируются, начиная с места ошибки.

Ранжирование методов доступа


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

420
Методы повышения производительности
Таблица 32. Методы доступа оптимизатору

Ранг Метод доступа


1 Одна строка по ее идентификатору (по ROWID)
2 Одна строка по объединению кластеров
3 Одна строка по хэш-ключу кластера с
уникальным или первичным ключом
4 Одна строка по уникальному или первичному
ч
ключу^
5 Объединение кластеров
6 Ключ хэш-кластера
7 Ключ индексированного кластера
8 Составной индекс
9 Индекс на основе одного столбца
10 Ограниченный диапазон поиска по
индексированным столбцам
И Неограниченный диапазон поиска по
индексированным столбцам
12 Соединение через сортировку слиянием
13 Поиск максимального или минимального
значения по индексированным столбцам
14 Упорядочение по индексированным столбцам
15 Полное сканирование таблицы

Таким образом, если оптимизатор основан на анализе


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

421
Раздел 7

SQL> SELECT —+ index


2 A t 2 , A t 3 FROM Tabl WHERE Atl>45612367;

Листинг 217. Запрос с указанием неограниченного


диапазона поиска

При использовании стратегии, основанной на анализе


правил, и наличии первичного ключа — столбца Atl, для вы-
полнения этого запроса будет применен метод доступа II
(неограниченный диапазон поиска по индексированным
столбцам).
Если критерий запроса содержит ограниченный диапазон
поиска (т. е. содержит два условных оператора — по одному с
каждой границы диапазона), то обе границы диапазона будут
известны еще во время синтаксического анализа выражения.
Превратить неограниченный диапазон в ограниченный можно
с помощью указания максимального значения (если оно из-
вестно) или с помощью предполагаемого (гипотетического)
максимального значения для столбца, исходя из априорных
знаний о данных. Например, сделать это так:

SQL> SELECT At2,At3 FROM Tabl


2 WHERE Atl>45612367 AND Atl<99999999;

Листинг 218. Использование ограниченного диапазо-


на поиска с указанием гипотетического мак-
симума

422
Методы повышения производительности

Анализ запросов
с целью повышения скорости
их выполнения
Изменение SQL-выражений на основе знаний о данных,
индексах, связях таблиц для повышения эффективности их
выполнения, называется коррекцией запросов (query
rewriting). Изменение предложений SQL отличается от напи-
сания новых предложений. Для того чтобы эффективно пере-
писывать запросы, необходимо в течение некоторого времени
накопить знания о системе. Сюда относятся сведения о том,
какие предложения SQL нуждаются в переписывании в связи
с их частым использованием или использованием ими значи-
тельных ресурсов, какие данные ими обрабатываются, каковы
характеристики и распределение этих данных, какие логиче-
ские условия в выражениях можно убрать или трансформиро-
вать в связи с логикой функционирования системы. При ре-
шении задач оптимизации проблемных запросов необходимо
следовать следующим рекомендациям:
Во-первых, при необходимости доступа к значительной
части строк какой-либо таблицы полное сканирование (full
scan) является более эффективным, чем использование ин-
дексов. Граница применения данных методов доступа в об-
щем случае составляет 5-10% записей таблицы, к которым
обращается запрос. Дело в том, что для сканирования индекса
и извлечения строки требуются, по крайней мере, две опера-
ции чтения для каждой строки (одна — для чтения индекса,
другая для чтения данных из таблицы). А при полном скани-
ровании таблицы для извлечения строки требуется только
одна операция чтения. При доступе к большому количеству
строк становится очевидной неэффективность использования
индекса по сравнению с полным сканированием таблицы, при
котором строки считываются непосредственно из таблицы.

423
Раздел 7

Для небольших таблиц полное сканирование практически


всегда оказывается эффективнее использования индекса.
Во-вторых, на различных этапах выполнения запросов
следует максимально использовать результаты предыдущих
этапов. Например, если результирующий набор данных тре-
буется отсортировать по значениям некоторого столбца, то
при выполнении операции соединения таблиц можно указать
способ выполнения этой Операции, при котором будет прове-
дена сортировка этих значений. Полученные результаты бу-
дут использованы при окончательной сортировке.
В-третьих, при использовании различных видов подза-
просов на основе знаний о данных следует учитывать особен-
ности вычисления специальных предикатов и применения
операторов теоретико-множественных операций. Например,
оператор MINUS может выполняться гораздо быстрее, чем
запросы с WHERE NOT IN (SELECT) или WHERE NOT
EXISTS.
Помимо таких, достаточно очевидных, способов улучше-
ния качества запросов можно использовать другие. Как пра-
вило, на основе опыта работы с конкретной базой данных у
каждого пользователя формируется свой стиль написания оп-
тимальных SQL-выражений. При этом существуют объектив-
ные средства определения качества запроса. В первую оче-
редь к ним относится трассировка.

Задание режима оптимизации


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

424
Методы повышения производительности

использовать выражение следующего вида: ALTER SESSION


SET ОРТ1МКЕК_ООАЬ=<режим>;
Заданный таким образом режим оптимизации будет ис-
пользоваться только для данной сессии, при начале другой
его требуется указать вновь. В качестве режима оптимизатора
может быть задано одно из следующих значений:
"CHOOSE" —при указании этого значения будет выбра-
на стоимостная оптимизация, основанная на анализе затрат. В
противном случае будет использована оптимизация, основан-
ная на анализе правил.
"RULE" — при указании этого значения будет использо-
вана оптимизация, основанная на анализе правил. Следует
отметить, что при указании только этого значения (или соот-
ветствующей подсказки) будет использован оптимизатор по
правилам.
"FIRST_ROWS" — это значение используется для мини-
мизации времени отклика, то есть для сведения к минимуму
временного интервала между началом выполнения запроса и
появлением результатов на экране. Это значение следует ис-
пользовать в системах, где критичным является время реак-
ции. Оптимизатор игнорирует эту подсказку для предложе-
ний DELETE и UPDATE, а также в тех предложениях
SELECT, которые содержат хотя бы одну конструкцию вида
UNION, INTERSECT, MINUS, UNION ALL, GROUP BY, FOR
UPDATE, DISTINCT или групповые функции. Как уже отме-
чалось ранее, при вычислении этих выражений неявно произ-
водится сортировка и будет извлечен весь набор данных.
"ALL_ROWS" — при указании этого значения будет ис-
пользована оптимизация, основанная на анализе затрат (при
наличии соответствующих статистических данных) для ми-
нимизации общего количества строк, обрабатываемых систе-
мой за единицу времени (в транзакциях за секунду). Это зна-
чение следует использовать в высокопроизводителЁных сис-
темах пакетной обработки. Например, рассмотрим предложе-
ние соединения таблиц, которое может быть выполнено либо
операцией вложенных циклов, либо операцией сортировки-
425

• .
Раздел 7

слияния. Операция сортировки-слияния быстрее возвратит


весь результат запроса, тогда как операция вложенных цик-
лов может быстрее возвратить первую строку. Поэтому, если
целью является лучшая пропускная способность, оптимизатор
скорее выберет соединение через сортировку-слияние.
Если в запросе указана подсказка ALL_ROWS или
FIRST_ROWS, но словарь данных не содержит статистики
для таблиц, перечисленных во фразе FROM, то оптимизатор
воспользуется сведениями о параметрах хранения этих таб-
лиц, чтобы оценить статистику и на этой основе выбрать план
исполнения. Для задания режима оптимизации на уровне вы-
ражения следует использовать ключевые слова методов дос-
тупов, которые содержит таблица 33, либо использовать одно
из приведенных выше значений (CHOOSE, RULE,
FIRST_ROWS, ALL_ROWS). При использовании в SQL-
выражении любой подсказки, отличной от RULE, осуществ-
ляется автоматический выбор оптимизатора по стоимости!

Таблица 33. Подсказки, специфицирующие метод дос-


тупа

Подсказка Описание
ROWID Использование идентификатора.
CLUSTER Сканирование ключа кластера.
HASH Сканирование хэш-индекса.
INDEX Сканирование индекса.
INDEX_ASC Сканирование индекса в порядке возрас-
тания.
INDEX_DESC Сканирование индекса в порядке убыва-
ния.
INDEX FFS Быстрое полное сканирование индекса.
AND_EQUAL Использование нескольких индексов со
слиянием результатов.
FULL Полное сканирование таблицы.

426
Методы повышения производительности

Обзор индексов Oracle


Понятие индекса было введено при изложении назначе-
ния основных объектов базы данных Oracle. Напомним, что
индекс — это объект базы данных, предназначенный для по-
вышения производительности при проведении выборки дан-
ных. Цель использования индекса состоит в том, чтобы полу-
чить требуемые в запросе данные более эффективным, по
сравнению с полным просмотром таблицы, способом. Индек-
сы улучшают производительность тех запросов, которые вы-
бирают небольшой процент строк из таблицы с помощью от-
носительно простых условий во фразе WHERE. Индексиро-
вать целесообразно лишь столбцы, обладающие высокой се-
лективностью.
Селективность (selectivity) столбца — это процент строк,
имеющих одинаковое значение для индексированного столб-
ца. Селективность столбца высокая, если мало строк имеют
одинаковые значения для этого столбца. Oracle автоматиче-
ски создает индексы для первичных ключей или столбцов,
для которых существует ограничение на уникальность значе-
ний. Эти индексы наиболее эффективны (что видно из табли-
цы рангов методов доступа). Столбцы с мало различающими-
ся значениями имеют низкую селективность. Отметим важ-
ный факт — если для индексированного столбца логическое
условие накладывается не на значение столбца, а на результат
некоторой функции от него, то этот индекс не используется.
Индексы бывают двух видов — простые и составные. Со-
ставной индекс — это индекс, включающий более чем один
столбец. Можно совместно проиндексировать два или более
столбца, каждый из которых обладает низкой селективно-
стью, а пара их значений — высокой. Если все столбцы, ис-
пользуемые запросом, входят в составной индекс, то обраще-
ния к таблицам можно вовсе избежать — вся данные будут
считаны только из индекса. Для эффективного использования
составного индекса необходимо, чтобы логические условия
427
Раздел 7

были наложены на ведущие столбцы индекса, то есть на те


столбцы, которые были указаны первыми при создании ин-
декса.
В индексах хранятся значения из одного или нескольких
стоЛ*бцов таблицы и значения ROWID для каждого из храни-
мых значений столбца (столбцов). Сервер Oracle, чтобы найти
строку в таблице по заданному значению столбца, ищет соот-
ветствующие ROWID в индексе и затем сразу переходит к
указанным ими строкам в таблице. В Oracle имеется несколь-
ко типов индексов:
— двоичные древовидные индексы (В*-Тгее-индексы);
— хэшированные индексы (hash);
— двоичные масочные индексы (bitmap).

В*-Тгее-индексы были реализованы в Oracle практически


с самого начала. Хэшированные индексы появились в Oracle
7.0. Двоичная индексация была реализована в Oracle 7.3. В
OracleS введены секционированные индексы и индекс-
таблицы. Понимание того, когда и где следует использовать
конкретные типы индексов, очень важно для эффективного
их применения. В*-Тгее-индексы используются наиболее час-
то, в то время как хэшированные и двоичные масочные ин-
дексы лишь при наличии некоторых условий могут обеспе-
чить существенные преимущества в выполнении определен-
ных запросов. Далее рассматривается, как работают индексы,
а также приводятся рекомендации, в каких случаях и почему
их следует использовать.
В*-Тгее-индекс содержит по одному индексному элемен-
ту для каждой строки таблицы, в которой имеется непустое
(NOT NULL) индексное значение. В*-Тгее-индекс состоит из
блоков-ветвей, которые содержат значения индекса и адреса
- или других блоков-ветвей, или блоков-листьев. Листовые
блоки содержат значения индекса и идентификаторы строк
(ROWID). Листовые блоки образуют дважды связанный спи-
сок, так что листья могут просматриваться в любом направ-

428
Методы повышения производительности

лении (как по возрастанию, так и по убыванию значений ин-


дексного столбца). Oracle автоматически балансирует глуби-
ну дерева так, чтобы все листовые блоки были на одной и той
же глубине, и поэтому для доступа к ним требовалось бы од-
но и то же число операций чтения. Однако сбалансированное
дерево автоматически не уравновешивает распределение
ключей в пределах дерева так, чтобы половина ключей нахо-
дилась бы на одной стороне В*-Тгее-индекса, а другая поло-
вина — на другой. Очевидно, что нет необходимости пере-
страивать дерево всякий раз, когда добавляются или удаля-
ются ключи. Однако если ключи добавляются или удаляются
только на одной стороне дерева, то распределение индексных
ключей может стать неравномерным, с изрядным числом раз-
реженных и даже опустошенных блоков по одну сторону де-
рева. В этом случае индекс рекомендуется перестроить.
На В*-Тгее-индексах для извлечения данных по запросу
может использоваться механизм быстрого полного просмот-
ра (fast full scan). Этот механизм дает существенные преиму-
щества, если все запрошенные из конкретной таблицы дан-
ные могут быть получены только из индекса. При быстром
полном просмотре эффективный многоблочный ввод/вывод,
обычно применяемый для полных просмотров таблиц, ис-
пользуется для прочтения всех листовых блоков В*-Тгее-
индекса. Поскольку число листовых блоков индекса, скорее
всего, намного меньше, чем блоков данных в таблице, для
выполнения запроса требуется просмотреть меньшее число
блоков. Поэтому просмотр индекса совершится значительно
быстрее, чем полный просмотр таблицы, хотя иногда нерав-
номерное распределение ключей снижает эффективность бы-
строго полного просмотра, поскольку требуется просмотреть
большее число листовых блоков (содержащих малое или во-
обще нулевое число элементов). При этом следует учитывать
наличие или отсутствие в таблице пустых значений, которые,
как было сказано выше, в индекс не заносятся. *
В*-Tree-индексы можно использовать для поиска данных
как по условиям равенства, так и по условиям неравенства.
429
Раздел 7
Это единственный тип индексов, который можно использо-.
вать для предикатов неравенства: LIKE, BETWEEN, ">", ">=",
"<", "<=". Исключение представляет случай использования
предиката LIKE при сравнении с шаблоном вида '%выраже-
ние' или '_выражение\ Хэшированные и двоичные масоч-
ные индексы работают только с предикатами равенства. В*-
Tree-индексы хранят только непустые значения ключей, так
что можно построить разреженный В*-Тгее-индекс.
Хэшированные индексы реализованы в Oracle в виде хэ-
шированных кластеров. Хэшированный кластер — специали-
зированный вид организации данных, обеспечивающий быст-
рый доступ к строкам таблицы. При обращении к хэширован-
ному кластеру по значению кластерного ключа применяется
функция хэширования (hashing), результатом которой являют-
ся значение хэшированного ключа и адрес блока данных.
Хэшированный кластер группирует в одном блоке строки,
содержащие одинаковые значения этой функции от ключей.
На любой таблице можно построить только один хэширован-
ный индекс.
Доступ к таблице посредством В*-Тгее-индекса требует
выполнения, по меньшей мере, двух операций ввода/вывода,
а обычно больше (если таблица, а потому и дерево ее индек-
са, большая). Доступ к хэшированному кластеру потребует
один вызов функции хэширования и одну операцию вво-
да/вывода для кластера.
Хэшированные кластеры целесообразно использовать для
больших таблиц, поиск по которым, как правило, осуществ-
ляется с условиями равенства по ключевому столбцу (столб-
цам). При этом значения ключей не модифицируются. Поэто-
му заранее можно точно определять число значений хэширо-
ванных ключей и размер кластера. В дополнение к этому,
ключевой столбец (столбцы) должен быть высокоселективен.
Главным преимуществом хэшированного индекса по
сравнению с В*-Тгее-индексом является лучшая производи-
тельность выборки, вставки, обновления и удаления записей,

430
Методы повышения производительности

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


столбцов кластера.
Двоичные масочные индексы обеспечивают быстрое об-
ращение к данным больших таблиц, когда доступ организует-
ся по столбцам с низкой или средней селективностью с ис-
пользованием различных сочетаний условий равенства. Дво-
ичный масочный индекс построен в виде двоичной карты
(bitmap) по значениям ключа. Это означает, что для каждой
строки таблицы в двоичной карте, то есть в определенном
бите некоторой последовательности байтов, поставлена 1 или
О ("да" или "нет") в соответствии со значением ключа кон-
кретной строки. Например, если столбец содержит кодируе-
мые значения и размерность множества возможных значений
не очень большая (скажем, цвета или ученые звания и степе-
ни).
Двоичные масочные индексы целесообразно использо-
вать для таблиц, к которым обращаются от случая к случаю.
Также двоичные масочные индексы целесообразно приме-
нять, когда запросы содержат фразу WHERE с несколькими
условиями равенства, относящимися к низко и средне селек-
тивным столбцам.
Двоичные масочные индексы меньше по объему, чем В*-
Тгее-индексы, и значительно меньше по сравнению с хэширо-
ванными кластерами. Двоичные масочные индексы не следу-
ет строить по столбцам с высокой селективностью. В этом
случае целесообразно, использовать хэшированные или В*-
Tree-индексы. Двоичные масочные индексы можно использо-
вать для поиска только по условиям равенства ("=", IN). Если
необходим доступ по интервалу индексированных значений,
то предпочтительнее использовать В*-Тгее-индексы.
Отметим, что возможности по управлению индексами в
OracleS значительно расширены и допускается указание не-
скольких десятков параметров, специфицирующих тип, свой-
ства индексов, способ их построения, хранения и т. п. Опера-
тор создания индекса использует следующий синтаксис:

431
Раздел 7
CREATE [UNIQUE I BITMAP] INDEX
[имя_схемы. ]имя_индекса
ON {CLUSTER [имя_схемы.]имя_кластера
} | { [имя_схемы. ] имя_таблицы ( имя_столбца , [-••])}

Проиллюстрируем использование оператора CREATE


INDEX для создания индексов различных типов для таблицы
ТаЬ2, созданной следующим выражением:

CREATE TABLE Tab2 (Atl"NUMBER, At2 DATE,


At3 NUMBER CHECK (At3 IN (1,3,5,7)));

Протокол взаимодействия с системой представлен в лис-


тинге 219.

— создадим В*-Тгее-индекс для столбцов Atl, At2


SQL> CREATE INDEX Tab2$Atl$At2 ON Tab2 (Atl,At2);
Index created.

— создадим еще один В*-Тгее-индекс для Atl, At3


SQL> CREATE INDEX Tab2$Atl$At3 ON Tab2 (Atl,At3);
Index created.

— создадим еще один индекс


-- для уже индексированных столбцов
SQL> CREATE INDEX Tab2$Atl$At3_2
2 ON Tab2 {Atl, At3') ;
CREATE INDEX Tab2$Atl$At3_2 ON Tab2 (Atl,At3)
*
ERROR at line 1:
ORA-01408: such column list already indexed

— создадим масочный индекс для столбца At3


SQL> CREATE BITMAP INDEX Tab2$At3 ON Tab2(At3);
Index created.

Листинг 219. Примеры создания различных индексов


- (В*-Тгее и масочного)

432
Методы повышения производительности

Для изменения индексов используется оператор ALTER


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

SQL> ALTER INDEX Tabl$Atl$At2 REBUILD;


Index altered.

Листинг 220. Пример изменения индекса с помощью


оператора ALTER INDEX

Для удаления индекса используется оператор "DROP


INDEX. Оператор удаления индекса Oracle использует сле-
дующий синтаксис:

DROP INDEX [имя_схемы.]имя_индекса

Пример удаления индекса приведен в листинге 221. Есте-


ственно, на данные в таблице удаление индекса никакого
влияния не оказывает.

SQL> DROP INDEX Tabl$Atl$At2;


Index dropped.

Листинг1 221. Пример удаления индекса оператором


DROP INDEX

Эффективное кодирование
SQL-выражений
Почти все типичные проблемы, возникающие при на-
стройке производительности, связаны с неэффективным ко-

433
Раздел 7

дированием SQL-выражений либо с неоптимальным исполь-


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

SELECT Atl FROM Tab! WHERE Atl>9;


SELECT At2/Atl FROM Tabl WHERE Atl>9;

Очевидно, что требуемые результаты могут быть получе-


ны с помощью одного сканирования:

SELECT Atl,At2/Atl FROM Tabl WHERE Atl>9;

Также не следует выбирать данные из таблицы, если


идентичные сведения можно вывести каким-то другим спосо-
бом. Следует руководствоваться следующим общим прави-
лом: лучше пожертвовать расходами на дополнительное вы-
числение, чем на дополнительные операции с устройствами
хранения. Исключение составляют выражения, в которых
большое число раз вызываются встроенные функции SQL
(значения которых вычисляются для каждой строки больших
таблиц или их соединений). В этом случае следует пересмот-
реть выражение и исключить лишние вызовы.
Особенно внимательно следует отнестись к использова-
нию операторов DISTINCT, ORDER BY и UNION, поскольку
при выполнении этих операций происходит создание времен-
ных таблиц с дополнительными накладными расходами на
выполняемую сортировку. При необходимости использования

434 •
Методы повышения производительности

оператора DISTINCT желательно сохранять результаты его


выполнения для последующего использования. Вместо опе-
ратора UNION рекомендуется применять оператор UNION
ALL (если это допускается логикой запроса), при использова-
нии которого не выполняется исключение дубликатов и, со-
ответственно, сортировка.
Рассмотрим использование операторов теоретико-
множественных операций MINUS и INTERSECT. Как было
указано ранее, оператор UNION и подзапросы могут в значи-
тельной степени повлиять на производительность приложе-
ния, поэтому вместо него следует использовать операторы
MINUS и INTERSECT. Рассмотрим в качестве примера такой
запрос:

SELECT Atl FROM Tab! WHERE Atl NOT IN


(SELECT Atl FROM Tab2);.

Его можно переписать в таком виде:

SELECT Atl FROM Tab! MINUS'SELECT Atl FROM Tab2;

Оба этих запроса фактически возвращают один результат


(если результирующий набор не содержит дубликатов). С по-
мощью просмотра статистических сведений о выполнении
запросов можно обнаружить, что общее количество логиче-
ских операций чтения для первого варианта запроса гораздо
больше, чем для второго. Использование оператора MINUS
может оказаться очень эффективным.
Логические выражения используются для оценки истин-
ности (с результатом TRUE) или ложности (с результатом
FALSE) высказываний. Использование встроенных функций
Oracle для гибкой подстановки в логические выражения зна-
чений данных может значительно улучшить производитель-
ность системы. Рассмотрим в качестве примера таблицу, в
которой регистрируется наступление некоторых событий.
Пусть требуется узнать число событий, произошедших до

435
Раздел 7

1 марта 2002 года, между 1 марта 2002 и 1 апреля 2002 года и


с 1 апреля 2002 года по настоящее время. Первое решение —
выполнить три следующих запроса:

SELECT COUNT(*) FROM Tab2 WHERE


At2 < TO_DATE('01032002', 'ddmmyyyy');

SELECT COUNT(*) FROM Tab2 WHERE


At 2 BETWEEN TO_DATE (' 01.032002 ',' ddmmyyyy') AND
1
TO_DATE('01042002','ddmmyyyy );

SELECT COUNT(*) FROM Tab2 WHERE


At2 > TO_DATE('01042002', 'ddmmyyyy');

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


всего, придется три раза выполнить полное сканирование
таблицы ТаЬ2. Этот пример хорош тем, что в нем приходится
иметь дело с тремя разными интервалами, которым должно
принадлежать значение столбца At2 и, на первый взгляд, не-
понятно, каким образом можно применить здесь двузначную
логику? Прежде всего, следует выполнить логическое преоб-
разование. В Oracle для этой цели предусмотрена специальная
функция DECODE. При внимательном ознакомлении с при-
веденным ниже примером ее использования можно обнару-
жить, что данный запрос приводит к тем же результатам, но
за счет всего одного сканирования:

SELECT
SUM(DECODE(SIGN{TO_DATE('01032002','ddmmyyyy')-
At2),-1,0,1)) suml,
SUM(DECIDE(SIGN(At2-
TO_DATE('01032002','ddmmyyyy')),-1,0,
DECODE (SIGiJ(TO_DATE('01042002' ,'ddmmyyyy')-
At2),-1,0,1))) sum2,
SUM(DECODE(SIGN(At2-
TO_DATE( '01042002','ddmmyyyy')),-1,0,1}) sum3
FROM Tab2;

436
Методы повышения производительности

Эффективность выполнения данного запроса, по сравне-


нию с исходными тремя, будет просто невероятной. Однако
читаемость программы и удобство ее сопровождения заметно
ухудшаются. Хотя, если вспомнить определения функций
DECODE, SIGN и семантику операций с датами в Oracle, ло-
гика вычисления выражений suml, sum2, sum3 становится
прозрачной.
Очевидно, что наиболее трудоемкой частью процесса
коррекции является просмотр текстов исходных запросов и
выявление тех из них, для которых может быть использована
простая функция логического преобразования, приводящая к
тем же результатам.

Изменение плана выполнения


запроса
При формировании плана выполнения запроса оптимиза-
тор обычно принимает верные решения. Как правило, 95%
всех запросов в системе не нуждаются в дополнительной на-
стройке. Оставшиеся 5% проблемных запросов подлежат Ли-
бо ручной коррекции, которая была рассмотрена выше, либо
принудительному изменению и фиксации плана с помощью
подсказок. На основе сведений о данных в таблицах для за-
просов, которые выполняются недостаточно быстро, пользо-
ватель может выбрать иной план выполнения, чем тот, что
автоматически генерирует оптимизатор.
Для изменения и фиксации плана выполнения запроса с
помощью подсказок необходимо выполнить следующие опе-
рации:
— зафиксировать порядок обхода таблиц с помощью
подсказки ORDERED;
— зафиксировать методы доступа с помощью подсказок
FULL, INDEX и т. д.;
— зафиксировать методы соединения таблиц с помощью
подсказок USE_NL, USE_HASH, USE_MERGE;
437
Раздел 7

— дополнительными подсказками тонко настроить за-


прос.

Дальнейшее изложение будем иллюстрировать на приме-


ре. Пусть таблицы Tab! и ТаЬ2 созданы предложениями:

CREATE TABLE Tab! (Atl NUMBER,


At2 NUMBER, At3 NUMBER);
CREATE TABLE Tab2 (Atl NUMBER, At2 NUMBER);

Построим для них индексы с помощью следующих вы-


ражений:

CREATE INDEX Tabl$Atl ON Tabl(Atl);


CREATE INDEX Tab2$Atl ON Tab2(Atl);
CREATE INDEX Tab2$At2 ON Tab2(At2);

Заполним таблицы случайными данными с помощью


следующего анонимного PL/SQL-блока (предварительно соз-
дав циклическую последовательность — генератор этих дан-
ных).

CREATE SEQUENCE sq$Tab MAXVALUE 10 CYCLE CACHE 5;


BEGIN
FOR i IN 1. .8000 LOOP
INSERT INTO Tabl
VALUES(sq$Tab.nextval, 15,2);
END LOOP;
FOR i IN 1..992000 LOOP
INSERT INTO Tabl
VALUES(sq$Tab.nextval, 15,3);
END LOOP;
COMMIT;
END;

Заполним таблицу ТаЬ2 случайными данными с помощью


другого анонимного PL/SQL-блока:

438
Методы повышения производительности
BEGIN
FOR i IN 1..333 LOOP
INSERT INTO Tab2 VALUES(sq$Tab.nextval, . 1);
END LOOP;
FOR 1 IN 1. .333 LOOP
INSERT INTO Tab2 VALUES(sq$Tab.nextval, 2 ) ;
END LOOP;
FOR i IN 1. .334 LOOP
INSERT INTO Tab2 VALUES(sq$Tab.nextval, 3 ) ;
END LOOP;-
COMMIT;..
END;

Теперь у нас есть большая (миллион строк) таблица Tab!


и связанная с ней относительно маленькая таблица ТаЬ2.
Пусть требуется выполнить следующий запрос:

.SELECT Tabl.At2, COUNT(l) FROM Tabl, Tab2


WHERE T a b l . A t l = T a b 2 . A t l
AND Tabl.At3=2
AND Tab2.At2=l
GROUP BY T a b l . A t 2 ;

Отправим его на выполнение и отметим, нто выполняется


он достаточно долго. Очевидно, требуется внести коррективы
в план выполнения запроса. Настройка любого проблемного
запроса начинается с просмотра собственно плана. Для этого
предназначена команда EXPLAIN PLAN. Результаты созда-
ния плана сохраняются в специальную таблицу
PLANJTABLE, которую предварительно необходимо создать
с помощью специального сценария. Каждому выражению,
для которого создается план, пользователь назначает специ-
альный идентификатор (в данном примере "Z"). После созда-
ния плана его можно просмотреть с помощью специального
иерархического запроса в SQL*Plus (объем текста запроса не
позволяет привести его в книге полностью) или в каком-либо
графическом средстве, например в SQL Navigator.
План выполнения запроса, который предложил оптимиза-
тор Oracle, приведен ниже.
439
Раздел 7

SQL> DELETE FROM plan_table


2 WHERE statement_id = 'Z';
2 rows deleted.

SQL> COMMIT;
Commit complete.

SQL> EXPLAIN PLAN SET stateme.nt^id=' Z' FOR


2 SELECT Tabl.At2, COUNT(1) FROM Tabl, Tab2
3 WHERE Tabl.Atl=Tab2.Atl
4 AND Tabl.At3=2
5 AND Tab2.At2=l
6 GROUP BY Tabl.At2;
'Explained.

SQL> COMMIT;
Commit complete.
— результат специального иерархического запроса
1.0 SELECT STATEMENT Z Optimizer: CHOOSE
2.1 SORT (GROUP BY)
3.1 TABLE ACCESS (BY INDEX ROWID) - TAB1
4.1 NESTED LOOPS
5.1 TABLE ACCESS (BY INDEX ROWID) - TAB2
6.1 INDEX(RANGE SCAN)-TAB2$AT2 (NON-UNIQUE)
5.2 INDEX(RANGE SCAN)-TAB1$AT1 (NON-UNIQUE)
7 rows selected.

Листинг1 222. План выполнения запроса, предложен-


ный оптимизатором Oracle

Что же представляет собой этот план? План выполнения


запроса представляет собой пошаговые действия сервера при
обращении к данным на основании сведений, полученных на
предыдущих шагах. Графически план представляется ft виде
древовидной структуры, пример которой приведен в листинге
222. Рассмотрим, какие действия при выполнении запроса
будет производить сервер, руководствуясь этим планом.
В нашем случае сначала по индексу Tab2$At2 был найден
идентификатор строки в таблице ТаЬ2, у которой значение

440
Методы повышения производительности

столбца At2 равно 1. Затем по этому идентификатору про-


изошло обращение к самой таблице ТаЬ2 за значением столб-
ца Atl в этой строке. Если бы индекс Tab2$At2 был состав-
ным и наряду с At2 включал в себя и Atl, то обращения к
таблице не ^произошло бы вовсе, необходимое значение Atl
было бы считано из индекса.
На следующем шаге по найденному значению Atl из таб-
лицы ТаЬ2 происходит поиск в индексе Tabl$Atl таблицы
Tab! значений. Такой порядок действий сервера будет пред-
принят для всех записей таблиц Tab! и ТаЬ2. Если соответст-
вующие значения в индексе будут найдены, то по идентифи-
каторам строк таблицы Tab! из индекса происходит обраще-
ние к таблице Tab! за необходимыми для вычислений значе-
ниями столбцов, которых нет в индексе Tabl$Atl. Для наше-
го примера это At2 и At3. На следующем этапе происходит
сравнение значения столбца At3 с константой (At3=2) и, если
оно истинно, то эта строка из таблицы Tab! будет учитывать-
ся в конечном результате (в той или иной группе —в зависи-
мости от значения столбца At2). В нашем случае оптимизатор
выбрал способ соединения таблиц с помощью вложенных
циклов, поэтому изложенная последовательность действий
сервера будет использована для каждой строки таблицы ТаЬ2
циклично. Последний этап плана выполнения запроса (сор-
тировка) появился из-за присутствия в запросе агрегирующей
функции.
Приступим к оптимизации запроса. Как уже отмечалось
выше, качественная оптимизация невозможна без знаний о
данных априори либо знаний, которые пользователь может
собрать сам с помощью простых запросов, условия которых,
как правило, частично взяты из оптимизируемого запроса. В
этом случае посмотрим, как распределены значения, для ко-
торых у нас есть условия сравнения с константами
(Tabl.At3=2, Tab2.At2=l). Выясняется, что в ТаЬ2 записей со
значением столбца At2, равным 1, примерно треть, а в Tab!
записей со значением столбца At3, равным 2, около ста. Ме-
нее процента! Очевидно, что целесообразнее начинать поиск
441
Раздел 7

именно с Tabl. Пользуясь таким хорошим логическим усло-


вием (Tabl .At3=2). провести ее полное сканирование, ото-
брать эти 100 строк и уже по их значениям Atl найти подхо-
дящие строки в ТаЬ2 (таких строк будет немного, так как таб-
лица ТаЬ2 небольшая) и для них выполнить операцию срав-
нения с константой (Tab2.At2=l). А так как таблица ТаЬ2 не-
большая, то для нее также можно использовать полное скани-
рование и отказаться от метода соединения с помощью~вяо-
женных циклов, применив, например, HASH_JOIN.
Приступим к реализации этой идеи. Начнем с фиксации
порядка обхода таблиц. Подсказка ORDERED указывает на
то, что порядок обхода таблиц слева направо — таблицы со-
единяются в той последовательности, в какой они перечисле-
ны во фразе FROM. Обратите внимание, если эту подсказку
не использовать, то оптимизатор сам примет решение, в какой
последовательности соединять таблицы (как правило, в об-
ратной последовательности, чем таблицы перечислены во
фразе FROM). Рекомендуется таким образом организовать
соединение, чтобы на ранних этапах (в начале списка таблиц)
были таблицы, на данные в которых накладываются самые
селективные условия. Делается это для того, чтобы было как
можно меньше операций соединений со строками из других
таблиц на следующих этапах. Если в запросе выполняется
соединение большой таблицы, для которой целесообразно
полное сканирование, с несколькими маленькими, практиче-
ски всегда целесообразно ее поставить на первое место. Спи-
сок подсказок, влияющих на последовательность обхода таб-
лиц, приведен в таблице 34.

Таблица 34. Методы обхода таблиц

Подсказка Описание
ORDERED Использование порядка таблиц, указан-
ного в предложении FROM, в качестве
порядка их объединения.

442
Методы повышения производительности

PUSH_SUBQ Использование плана выполнения за-


проса с вложенным подзапросом на пер-
вом месте.
STAR Использование плана выполнения за-
проса на основе составного ключа
("звездочки") при разрешении объеди-
нения.

После фиксации порядка соединения таблиц необходимо


указать методы доступа к ним с помощью подсказок, которые
описаны в таблице 33. Если эта подсказка содержит список
доступных индексов, то оптимизатор вычисляет стоимость
просмотра по каждому из индексов в списке, после чего вы-
бирает метод доступа с наименьшей стоимостью. Полное
сканирование таблицы или доступ с использованием других
индексов (не перечисленных в списке) оптимизатором не рас-
сматриваются.
В заключение следует указать методы соединения таб-
лиц. Эти методы перечислены в таблице 35. Их назначение
понятно из названий. Для того чтобы выполнить соединение
для двух таблиц, соединение способом вложенных циклов
использует в цикле строки ведущей таблицы для поиска под-
ходящих по условию соединения строк другой таблицы: по-
сле первой — вторую, третью и т. д. При сортировке слияни-
ем производится сортировка строк таблиц по столбцу, по ко-
торому выполнятся соединение и затем производится их слия-
ние. Этот способ характеризуется большими затратами ресур-
сов на сортировку и должен использоваться аккуратно. В
пользу его выбора может повлиять необходимость получения
отсортированных результатов (наличие в запросе конст-
рукции ORDER BY) или наличие подходящих индексов. От
некоторых недостатков сортировки со слиянием освобождено
хэш-объединение, в котором используется хэш-таблица для
значений столбца, по которому производится объединение.

443
Раздел 7

Как правило, чаще всего используется самый простой способ


— объединение с помощью вложенных циклов.

Таблица 35. Методы объединения таблиц

Подсказка Описание
USE NL Использование вложенных циклов.
USE MERGE Использование сортировки со слиянием.
USE HASH Использование hash-объединения.

Оптимизированный запрос представлен в листинге 223.

SQL> DELETE FROM plan_table


2 WHERE statement_id = 'Z';
2 rows deleted.
SQL> COMMIT;
Commit complete.
SQL> EXPLAIN PLAN SET statement_id='Z' FOR
2 SELECT /*+ ORDERED FULL(Tabl) FULL(Tab2)
3 USE_HASH (Tab2)*/ Tabl.At2, COUNT(1)
4 FROM Tabl, Tab2 WHERE Tabl.Atl=Tab2.Atl
5 AND Tabl.At3=2
6 AND Tab2.At2=l GROUP BY Tabl.At2;
Explained.
— результат специального иерархического запроса
1.0 SELECT STATEMENT Z Optimizer: CHOOSE Cost
2.1 SORT (GROUP BY)
3.1 HASH JOIN
4.1 TABLE ACCESS (FULL) - TAB1
4.2 TABLE ACCESS (FULL) - TAB2
i
Листинг 223. Запрос с подсказками оптимизатору и
его план выполнения, полученный командой
EXPLAIN PLAN

444
Методы повышения производительности

Секционирование таблиц
Понятие секционирования может иметь много разных
значений. В Oracle подразумевается, что термин секциониро-
вание (partitioning) означает возможность разбиения на раз-
делы (секции) таблиц и индексов. Секции образуют новый
физический уровень архитектуры Oracle, который находится
между таблицей и ее экстентами. При этом таблица отобра-
жается на набор секций, которые в свою очередь, однозначно
отображаются на набор экстентов, а каждый экстент отобра-
жается на одно или несколько табличных пространств с од-
ним или несколькими файлами данных.
Секционирование таблиц и индексов применяется, как
правило, в двух случаях:
— падение производительности при увеличении объемов
обрабатываемых данных;
-'— при проектировании, когда прогнозируется большой
размер создаваемых таблиц.

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


наряду с параллельными запросами. Степень параллелизма
обычно устанавливается кратной количеству секций, которые
образуют таблицу. При этом используются не только пре-
имущества исключения секций, но и возможность параллель-
ного выполнения запросов по отношению к неисключенным
секциям.
В OracleS таблица или индекс может содержать до 64000
секций. Ключом секционирования (partition key) называется
столбец (столбцы), на основании которого выполняется сек-
ционирование таблицы или индекса. Ключ секционирования
может быть составным и насчитывать до 16 столбцов.. В каче-^
стве ключа секционирования обычно выбирается столбец,
значения которого редко изменяются, равномерно распреде-
лены и для которых можно выделить логические интервалы.
Например, время начала разговора для таблицы, в которой
445

• '-
Раздел 7

хранятся сведения о телефонных разговорах. Секции в этом


случае могут содержать разговоры, которые были в течение
одних суток или одной недели. В секционированных табли-
цах не поддерживаются кластеры и большие объекты (напри-
мер, объекты LONG и RAW). Пример создания секциониро-
ванной таблицы приведен в листинге 224.

SQL> CREATE TABLE Tab!


2 (Atl NUMBER, At2 V A R C H A R 2 ( 2 0 Q ) )
3 PARTITION BY RANGE (Atl)
4 (PARTITION pi VALUES LESS THAN (10001)
5 TABLESPACE Tsl STORAGE (INITIAL 1M NEXT 1M) ,
6 PARTITION p2 VALUES LESS THAN (20001)
7 TABLESPACE Ts2. STORAGE (INITIAL 1M NEXT 1M) ,
8 PARTITION p3 VALUES LESS THAN "(30001)
9 TABLESPACE Ts3 STORAGE (INITIAL 1M NEXT 1M),
10 PARTITION p4 VALUES LESS THAN (40001)
11 TABLESPACE Ts4 STORAGE (INITIAL 1M NEXT 1M),
12 PARTITION p5 VALUES LESS THAN (50001)
13 TABLESPACE Ts5 STORAGE(INITIAL 1M NEXT 1M) ) ;
Table created.

Листинг1 224. Пример создания секционированной


таблицы

Выражение VALUES LESS THAN указывает верхнюю


границу секции. Например, секция р! может содержать стро-
ки со значением столбца Atl, не превышающим 10000 (LESS
THAN в предложении VALUES LESS THAN означает строго
меньше). Такое ограничение автоматически устанавливается
в каждой секции. Например, при попытке вставить строку со
значением 60000 столбца Atl будет получено сообщение об
ошибке, так как максимальное допустимое значение для
крайней секции (р5) равно 50001.

SQL> INSERT INTO Tab! VALUES(60000,'A1);


446
Методы повышения производительности
INSERT INTO Tab! V A L U E S ( 6 0 0 0 0 , ' А ' )
*

ERROR at line 1:
ORA-14400: inserted partition key does not map to
any partition

Листинг 225. Пример попытки вставки записи, у ко-


торой значение столбца-ключа секционирова-
ния не попадает в указанный при создании
таблицы диапазон -

Для того чтобы избежать возникновения таких ошибок,


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

SQL> CREATE TABLE Tab2


2 (Atl NUMBER, At2 VARCHAR2(200))
3 PARTITION BY RANGE (Atl).'
4 (PARTITION pi VALUES LESS THAN (10001),
5 PARTITION p2 VALUES LESS THAN (20001),
6 PARTITION p3-VALUES LESS THAN (30001),
7 PARTITION p4 VALUES LESS THAN (40001),
8 PARTITION p5 VALUES LESS THAN (MAXVALUE));
Table created.
SQL> INSERT INTO Tab2 VALUES ( 60000, 'A1 ) ,"
1 row created;

Листинг 226. Пример создания секционированной


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

Единственным отличием двух последних примеров явля-


ется указание ключевого слова MAXVALUE для крайней сек-
ции. Следует учесть, что в предложении VALUE LESS THAN
не допускается использование значений NULL. В тех случаях,,
когда вставляются строки со значениями ключа секциониро-
вания NULL, строки сортируются так же, как строки,

447
Раздел 7

которые обладают большими литеральными значениями, чем


у остальных, но меньшими, чем значение MAXVALUE.
Ключ секционирования может быть создан на основе не-
скольких столбцов (то есть быть составным). При этом при-
оритет операций сравнения убывает слева направо и, если в
такой операции сравнения используется значение
MAXVALUE, все остальные расположенные за ним значения
игнорируются. Секционирование по составному ключу имеет
смысл применять для таблицы с составным первичным клю-
чом или при необходимости разбить ее на секции по комби-
нациям первичного ключа и внешних ключей часто объеди-
няемых таблиц. В листинге 227 представлен пример создания
секционированной таблицы с составным ключом секциони-
рования.

SQL> CREATE TABLE ТаЬЗ


2 (Atl NUMBER, At2 NUMBER, At3 VARCHAR2(200))
3 PARTITION BY RANGE (Atl,~At2)
4 (PARTITION pi VALUES LESS THAN (10001,10),
5 PARTITION p2 VALUES LESS THAN (20001,20),
6 PARTITION p3 VALUES LESS THAN (30001,30),
7 PARTITION p4 VALUES LESS THAN (40001,40),
8 PARTITION p5 VALUES LESS THAN
9, (MAXVALUE,MAXVALUE));
Table created.
—запись попадет в секцию PI
SQL> INSERT INTO ТаЬЗ VALUES(10000, 5, 'A');
1 row created.

—запись попадет в секцию РЗ


SQL> INSERT INTO ТаЬЗ VALUES(25000,35,'В');
1 row created.

Листинг 227. Пример секционирования таблицы с ис-


пользованием составного ключа секционирова-
ния

448
Методы повышения производительности

Секционирование индексов
В секционированных и несекционированных таблицах
могут использоваться четыре основных типа индексов:
— несекционированный индекс;
— глобальный префиксный индекс;
— локальный префиксный индекс;
— беспрефиксный индекс.

Секционированные и несекционированные таблицы мо-


гут иметь как секционированные, так и несекционированные
индексы. Единственным ограничением в данном случае явля-
ется невозможность секционирования кластерного индекса.
Индекс считается префиксным (prefixed), если его край-
ние слева столбцы находятся в том же порядке и имеют точно
такой же размер, как и ключ секционирования. Кроме того,
подобные индексные столбцы могут быть множеством ключа
секционирования, но не его подмножеством.
Глобальный (global) индекс может-быть только префикс-
ным, но его секционирование обычно отличается от секцио-
нирования связанной с ним таблицы. Глобальные индексы не
поддерживаются в Oracle, то есть не поддерживаются особые
взаимосвязи (соответствие диапазона значений) между сек-
ционированным индексом и секционированной таблицей. Ос-
новным недостатком глобального индекса является то, что
оптимизатор Oracle не может использовать преимущества
исключения секций. G другой стороны, глобальные индексы
могут быть разбиты на секции на основе диапазонов значе-
ний, отличных от тех, которые имеются в связанной с ним
таблице. Это может быть полезным при работе с несколькими
индексами, которые связаны с приложениями интерактивной
аналитической обработки.
Локальный (local) индекс может быть префиксным или
беспрефиксным. В случае его использования между секциями
индекса и соответствующими секциями таблицы устанавли-
449
15. Заказ № 1628.
Раздел 7

вается взаимно однозначное соответствие. Такое секциониро-


вание называется эквивалентным (equi-partitioned) и поддер-
живается Oracle. Оптимизатор Oracle использует преимуще-
ства отсутствия обращения к секциям. Следовательно, основ-
ными преимуществами локальных индексов являются авто-
матическая эквивалентная для всех секций поддержка раз-
биения и соответствующие преимущества от использования
оптимизатора. Единственным недостатком локального индек-
са является необходимость иметь такое же секционирование,
как и для связанной с ним таблицы (независимо от того, пре-
фиксный этот индекс или беспрефиксный).
Следующий пример содержит SQL-выражение для созда-
ния секционированной таблицы и связанных с ней локального
префиксного и локального беспрефиксного индексов.

SQL> CREATE TABLE Tab4


2 (Atl NUMBER, At2 NUMBER, At3 VARCHAR2(200))
3 PARTITION BY RANGE (Atl)
- 4 (PARTITION pi VALUES LESS THAN (10001),
.5 PARTITION p2 VALUES LESS THAN (20001),
6 PARTITION p3 VALUES LESS THAN (30001),
7 PARTITION p4 VALUES LESS THAN (40001));
Table created.

SQL> CREATE INDEX Tab4$Atl$At2 ON Tab4 (Atl,At2)


2 LOCAL
3 (PARTITION pi,
4 PARTITION p2,
5 PARTITION p3,
6 PARTITION p4);
Index created.

SQL> CREATE INDEX Tab4$At2


2 ON Tab4 (At2)
3 LOCAL
4 (PARTITION PI,
5 PARTITION P2,
6 PARTITION P3,
7 PARTITION P4);
450
Методы повышения производительности
Index created.

Листинг 228. Пример создания секционированной


таблицы и связанных с ней локального пре-
. фиксного и беспрефиксного индексов

Обратите внимание на то, что в обоих случаях не испольг


зуются предложения PARTITION BY RANGE и VALUES
LEES THAN, так как с помощью ключевого слова LOCAL
Oracle уведомляется о типе индекса и в индексе будет приме-
нено эквивалентное секционирование по тем же специфика-
циям, которые используются в таблице.

Операции с секциями
Для выполнения всех операций с секциями предусмотре-
но использование двух основных выражений: ALTER TABLE
и ALTER INDEX. Эти выражения обладают следующими
расширениями, предназначенными для работы с секциями: •

Таблица 36. Операции с секциями

ALTER TABLE ALTER INDEX


DROP PARTITION DROP PARTITION
ADD PARTITION RENAME PARTITION
RENAME PARTITION REBUILD PARTITION
MODIFY PARTITION MODIFY PARTITION
TRUNCATE PARTITION SPLIT PARTITION
SPLIT PARTITION PARALLEL
MOVE PARTITION UNUSABLE
EXCHANGE PARTITION
MODIFY PARTITION

Многие из операций, связанных с работой с секциями,


уже по своим названиям могут быть понятны или известны,
поскольку, на первый взгляд, они выглядят так же, как обыч-
451
15*
Раздел 7
ные операции с таблицами и индексами, например DROP
TABLE и DROP INDEX. Однако здесь следует обратить более
пристальное внимание на расширения, которые свойственны
только секциям (SPLIT, MOVE, EXCHANGE и UNUSABLE).
Проиллюстрируем технику работы с секциями на примере
таблицы ТаЫ, созданной следующим выражением:

CREATE TABLE ТаЫ


(Atl NUMBER, At2 NUMBER, At3 V A R C H A R 2 ( 2 0 0 ) )
PARTITION BY RANGE (Atl)
(PARTITION pi VALUES LESS THAN (10001),
PARTITION p2 VALUES LESS THAN ( 2 0 0 0 1 ) ,
PARTITION p3 VALUES LESS THAN ( 3 0 0 0 1 ) ) ;

На основе секции рЗ с помощью спецификации SPLIT


PARTITION создадим новую секцию р4. Прежняя секция рЗ
будет содержать все строки, для которых значения поля Atl
меньше значения 25000, а новая секция р4 будет содержать
все строки, значения которых больше или равны 25000.

SQL> ALTER TABLE Tab! SPLIT PARTITION рЗ


2 AT (25000)
3 INTO (PARTITION p3, PARTITION p4);
Table altered.

Листинг1 229. Изменение способа секционирования


таблицы с . помощью конструкции 'SPLIT
,, PARTITION

В листинге 230, изменяется место хранения одной из сек-


ций таблицы ТаЫ.

SQL> ALTER TABLE ТаЫ MOVE PARTITION рЗ


2 TABLESPACE TS4;
Table altered.

Листинг1 230. Изменение места хранения секции рЗ с


помощью оператора ALTER TABLE
452
Методы повышения производительности

Как уже отмечалось выше, для ранних версий Oracle


проводилось ручное секционирование путем создания не-
скольких таблиц и представления UNION ALL над ними. Для
миграции из такой базы данных специально предназначена
команда EXCHANGE PARTITION. С ее помощью можно
преобразовать как таблицу в секцию, так и наоборот. Резуль-
тат преобразования секции в несекционированную таблицу
представлен в листинге 231. В этом примере включаются ин-
дексы и не производится проверка диапазонов значений для
перемещаемых строк.

-SQL> ALTER TABLE Tab! EXCHANGE PARTITION pi


2 WITH TABLE Tabla INCLUDING INDEXES
3 WITHOUT VALIDATION;
Table altered.

Листинг 231. Пример преобразования секций и таб-


лиц

Индекс-таблицы
Индекс-таблица — это таблица, которая физически по-
строена в виде двоичного дерева относительно своего пер-
вичного ключа. Oracle, начиная с версии 6, допускает воз-
можность не производить чтение блоков данных таблицы в
тех случаях, когда в запросах на выборку данных использу-
ются только столбцы индекса. Однако при операциях добав-
ления, обновления и удаления записей обязательно должна
была участвовать основная таблица. Начиная с OracleS,.суще-
ствует возможность определить таблицу, которая одновре-
менно является и собственным индексом, что устраняет веде-
ние двух отдельных структур. Как правило, это таблицы с ко-
роткими строками, обращение к которым всегда производит-
ся или по первичному ключу, или полным сканированием.

453
Раздел 7

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


строки имеют относительно большую длину, например свы-
ше 20% от размера блока. В этом случае лучшим выбором
является использование обычных таблиц и индексов. Для
создания индекс-таблиц в предложении CREATE TABLE ука-
зываются ключевые слова ORGANIZATION INDEX. Пример
создания индексно-организованной таблицы представлен в
листинге 232.

SQL> CREATE TABLE Tablndex


2 , (Atl NUMBER PRIMARY KEY,
3 At2 VARCHAR2(40))
4 ORGANIZATION INDEX;
Table created.

Листинг 232. Пример создания индекс-таблицы "

Существуют некоторые ограничения при работе с ин-


декс-таблицами. Наиболее важно, что их строки не имеют
идентификаторов (ROWID), поэтому не могут быть созданы
никакие дополнительные индексы, за исключением обяза-
тельного первичного ключа.

454
Раздел 8

Объектные расширения
в Oracle8

В конце 60-х годов в методологии программирования


возникла идея объединить два понятия: данные и операции в
одно целое, которое впоследствии получило название объект:
Объект = Данные + Операции.
Понятие объекта естественным образом согласуется с
нашими представлениями об окружающем мире. Объект
можно представить себе как сущность предметной области,
которая характеризуется определенным набором свойств и
"умеет" выполнять некие действия (методы). Чтобы понять
суть и назначение объекта, нужно обязательно знать его свой-
ства и методы.
Каждый объект всегда принадлежит некоторому классу.
Класс — это обобщенное описание множества однотипных
объектов. Объекты являются конкретными представителями
своего класса, их принято называть экземплярами класса. В
объектно-реляционных СУБД классы принято называть объ-
ектными типами.

455
Раздел 8

Объектно-ориентированное программирование строится


на основе трех принципов: инкапсуляции, наследовании и
полиморфизме.
Инкапсуляция означает наблюдаемое в объектах объеди-
нение данных и операций в одно целое, которое ведет к со-
крытию внутреннего устройства объектов.
Наследование означает, что на основе уже существующих
объектов можно строить новые, которые могут отличаться от
родительского объекта собственными методами и свойства-
ми. Иными словами, при наследовании происходит переход
общего к частному.
Полиморфизм означает, что в производных объектах
функционирование наследуемых операций может быть изме-
нено. При этом весь код, управляющий элементами родитель-
ского объекта, пригоден для управления дочерним объектом
без всякой модификации.
OracleS можно считать первым шагом корпорации Oracle
на эволюционном пути к объектной ориентации. OracleS ра-
ботает с объектами с помощью процессора реляционной базы
данных. Такой механизм в конечном счете должен привести к
истинно объектно-ориентированным системам управления
базами данных (ОРСУБД). В настоящее время сервером под-
держиваются инкапсуляция и полиморфизм. В следующей
версии сервера (Oracle 9i) декларируется поддержка меха-
низма наследования.

Объектные типы
Под объектным типом понимается объект базы данных
Oracle, которая объявляет структуру данных (атрибуты) и
разрешенные операции над ней. Объектный тип — это шаб-
лон, по которому можно создавать переменные, таблицы,
столбцы и другие конструкции этого типа. Объектный тип во
многом похож на класс или абстрактный тип данных объект-
но-ориентированного программирования.
456
Объектные расширения в OracleS

Объект — это экземпляр объектного типа OracleS. Объ-


екты могут храниться в таблицах (в таких случаях они явля-
ются постоянными), либо они могут существовать только
временно в переменных PL/SQL.
Атрибут — это структурная часть объекта Oracle. Каж-
дый атрибут может принадлежать одному типу данных, либо
скалярному, например VARCHAR2, либо составному, как
объявленные пользователем вложенные таблицы или масси-
вы. К объявлениям атрибутов предъявлены следующие тре-
бования: не допускается указание ограничения NOT NULL,
значений по умолчанию, типы данных должны соответство-
вать типам данных, которые используются при описании таб-
лиц и других объектов схем (за исключением LONG и LONG
RAW). To есть нельзя объявить атрибут, например, типа
BOOLEAN.
Метод — это процедура или функция, которая, как пра-
вило, производит операции над атрибутами объекта. Методы
для объекта могут быть вызваны только в контексте конкрет-
ного объекта этого типа. Методы могут быть созданы на
PL/SQL и других языках программирования. Для каждого
объектного типа существует специальный метод по умолча-
нию — так называемый конструктор, который инициализиру-
ет объекты. При определении объектного типа можно преду-
смотреть методы, которые будут являться членами объектно-
го типа. В определение типа входит только заголовок метода
со спецификациями доступа к объектам базы данных.^ Для
определения тела метода необходимо определить тело типа
(TYPE BODY), в котором определены тела всех методов. Оп-
ределению тела каждого метода должно предшествовать клю-
чевое слово MEMBER FUNCTION (MEMBER PROCEDURE).
Для доступа к атрибутам и методам в контексте экземпляра
объекта в функции используется ключевое слово SELF. Для
доступа к методам используется точечная нотация.
Конструкция "объявление типа—тело" очень похожа на
конструкцию "спецификация—тело пакета". Работа с ними
очень похожа, но, вместе с тем, имеется ряд различий. Так,
457
Раздел 8

для объектных типов нельзя использовать дополнительные


программы, отсутствующие в объявлении типа.
Для сравнения объектов в определении объектного типа
необходимо предусмотреть реализацию двух стандартных
методов MAP и ORDER. Метод MAP не имеет аргументов и
возвращает значение скалярного типа (DATE, NUMBER,
VARCHAR2, CHAR, REAL). При сравнении двух объектов
для каждого из них вычисляется значение этой функции, и
объекты упорядочиваются в соответствии с этими значения-
ми.
Метод ORDER предоставляет пользователю несколько
больше возможностей по определению внутренней логики
оператора сравнения для данного объектного типа. Он ис-
пользует в качестве аргумента другой объект того же типа и
возвращает -1,0 или 1, если собственный объект (объект, для
которого вызывается данный метод) соответственно меньше,
равен или больше объекта, переданного в качестве аргумента
функции. Следует отметить, что тип может иметь только одну
функцию MAP или ORDER.
Для создания объектных типов используется оператор
CREATE TYPE. В следующем листинге приведен пример соз-
дания объектного типа, который имеет пять атрибутов и один
метод.

SQL> CREATE OR REPLACE TYPE~Otl AS OBJECT


2 (Atl NUMBER,
3 At2 VARCHAR2(50),
-4 At3 VARCHAR2(50) ,
5 At4 VARCHAR2{50) ,
6 At5 DATE,
7 MEMBER FUNCTION AtlAt2At3 RETURN VARCHAR2,
8 MAP MEMBER FUNCTION M RETURN NUMBER);
9 /
Type created.

Листинг 233. Пример, иллюстрирующий создание объ-


ектного типа
458
Объектные расширения в Oracle8

Код методов объектного типа создается при создании его


тела. При создании самого типа они только объявляются, а
реализуются с помощью оператора CREATE OBJECT TYPE
BODY.

SQL> CREATE OR REPLACE. TYPE BODY Otl IS


2 MEMBER FUNCTION AtlAt2At3 RETURN VARCHAR2 AS
3 BEGIN
4 RETURN Atl||' '|IAt2||' '||At3;
5- END;
6 MAP MEMBER FUNCTION m RETURN NUMBER AS
7 BEGIN
8 RETURN Atl;
9 -END;
10 END;
11 /
Type body created.

Листинг 234. Пример, иллюстрирующий создание тела


объектного типа

Для изменения или замены объектного типа используется


оператор ALTER TYPE имя_тта. С его помощью, например,
можно добавить новые методы или перекомпилировать тело
объекта.

SQL> ALTER TYPE Otl REPLACE AS OBJECT


2 (Atl NUMBER,
3 At2 VARCHAR2(50),
4 At3 VARCHAR2(50),
5 At4 VARCHAR2(50),
6 At5 DATE,
7 MEMBER FUNCTION AtlAt2At3 RETURN VARCHAR2,
8 MEMBER FUNCTION AtlAt2 RETURN VARCHAR2);
Type altered.

Листинг 235. Пример, иллюстрирующий замену объ-


ектного типа с добавление нового метода
459

' ' .. • '


Раздел 8

Для удаления объектного типа используется оператор


DROP TYPE имя_типа. Если существуют объекты, завися-
щие от удаляемого объектного типа, то требуется указание
ключевого слова FORCE. Удаление объектного типа Otl
представлено в листинге 236.

SQL> DROP TYPE Otl FORCE;


Type dropped. x

Листинг 236. Пример удаления объектного типа

Если при объявлении двух типов используются взаимные


ссылки объектов друг на друга или один из атрибутов типа
ссылается на объект этого же типа, то объявить эти типы
обычным способом не получится, так как в момент объявле-
ния одного типа второй будет еще не объявлен. Для таких
объявлений используются неполные типы. В этом случае объ-
является заголовок типа, что сообщает серверу Oracle, что
такой тип существует и будет полностью определен позднее.
Рассмотрим пример создания такого типа.

SQL> CREATE OR REPLACE TYPE Ot2;


Type created.

SQL> CREATE OR REPLACE TYPE Ot2 AS OBJECT


2 (Atl NUMBER,
3 At2 REF Ot2);
Type created.

Листинг 237. Пример предварительного объявления


типа

460
Объектные расширения в OracleS

Объекты в базе данных


После определения объектногб типа его можно использо-
вать как при определении столбца реляционной таблицы, так
и при определении таблицы объектов. Объекты, хранящиеся в
объектных таблицах, называются объектами в таблице. Объ-
екты, хранящиеся в столбце таблицы или как атрибут другого
объекта, называются объектами в столбцах. Для их создания
при описании таблицы нужно просто указать тип данных од-
ного из столбцов как соответствующий объектный тип. В сле-
дующем примере таблица ТдЫ содержит столбец At2,
объявленный как объектный тип Otl.

SQL> CREATE TABLE Tab!


2 (Atl NUMBER,
3 At2 Otl);
Table created.

Листинг 238. Пример создания таблицы, один из


столбцов которой имеет объектный тип

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


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

461
Раздел 8

SQL> • INSERT INTO Tabl VALUES'


(i'0,Qtl(l, ' A ' , ' B ' , 'C',SYSDATE) ) ;
1 row created.

Листинг 239. Пример вставки записи с помощью


функции-конструктора объекта

Для выборки данных из этой таблицы необходимо объя-


вить алиас для таблицы и в явном виде специфицировать ка-
ждый атрибут объекта.

SQL> SELECT t.Atl,t.At2.At2 FROM Tabl t


2 WHERE t.At2.At2='A';

ATI AT2.AT2

10 A

Листинг 240. Пример запроса к таблице, содержащей


объекты в столбцах

Наряду с хранением объектов в столбцах, можно исполь-


зовать таблицы объектов. Таблицы объектов — это специаль-
ный вид таблиц, содержащих объекты и обеспечивающих ре-
ляционное представление их атрибутов. Для следующего
примера объектная таблица ТаЬ2 может рассматриваться
двумя способами: таблица с одним столбцом, каждый эле-
мент которого объект типа ОН; таблица с несколькими
столбцами, каждый из которых имеет тип и имя соответст-
вующего атрибута объектного типа, то есть Atl, At2, At3, At4,
At5. Для создания таблицы объектов используется следую-
щий упрощенный синтаксис:

CREATE TABLE [имя__схемы. ] имя_таблицы OF


имя объектного типа.

462
Объектные расширения в OracleS

Пример создания объектной таблицы приведен в листин-


ге 241.

SQL> CREATE TABLE Tab2 OF Otl;


Table created.

Листинг 241. Пример создания объектной таблицы

Для вставки данных в объектную таблицу можно исполь-


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

SQL> INSERT INTO Tab2 VALUES


(Otl(10,'D1,'E','F',SYSDATE));
1 row created.

SQL> INSERT INTO Tab2 VALUES


(10,'D1,'E1,'F',SYSDATE);
1 row created.

Листинг 242. Пример различных способов вставки


данных в объектную таблицу

Выборку данных из объектной таблицы можно произво-


дить двумя способами: с помощью оператора VALUE (в дан-
ном случае использование алиаса обязательно) и с помощью
спецификации атрибутов объектного типа. Примеры обоих
способов приведены в листинге 243.

SQL> SELECT VALUE(t) FROM Tab2 t


2 WHERE t.At4='F';

463
Раздел 8
SQL> -SELECT sql.NEXTVAL FROM dual;
NEXTVAL

62

SQL> INSERT INTO Tab2


2 VALUES (NULL,'X','¥','Z',SYSDATE);
1 row created.

SQL> SELECT VALUE(t) FROM Tab2 t


2 WHERE t.At4='Z';
VALUE(T)(ATI, AT2, АТЗ, АТ4, ATS)

OT1(63, 'X', 'У, 'Z', 40-MAR-02')

Листинг 246. Пример создания триггера для объект-


ной таблицы

Ссылки на объекты
В реляционной модели данных для выражения отноше-
ний между строками разных таблиц используются механизмы
внешних ключей и поддержание ссылочной целостности. Для
объектных расширений предусмотрен другой способ.
Для каждого объекта в таблице объектов Oracle создает
уникальный и неизменный идентификатор объекта. Этот
идентификатор позволяет обращаться к соответствующему
объекту таблицы из другого объекта или реляционной табли-
цы. Гарантируется, что во всей базе данных нет пары объек-
тов с одинаковыми идентификаторами, также гарантируется
повторное неиспользование идентификаторов удаляемых
объектов. Встроенный тип данных, обеспечивающий возмож-
ность использования таких ссылок, называется REF. Пере-
менную типа REF можно использовать для доступа к объекту,
как если бы данная переменная имела бы тот же тип, что и
объект, на который она ссылается.
В OracleS в операторах INSERT и UPDATE используется
конструкция RETURNING, которая позволяет без дополни-
466
Объектные расширения в OracleS

тельных перезапросов копировать в локальные переменные


новые значения. В приведенном ниже листинге приведена
техника работы с ссылками ha объекты (заносится объект в
объектную таблицу ТаЬЗ с ссылкой на объект из объектной
таблицы ТаЬ2).

SQL> CREATE OR REPLACE TYPE Ot2 AS OBJECT


2 (Atl VARCHAR2(20),
3 At2 VARCHAR2{20),
4 At3 BLOB,
5 At4 DATE);
6 /
Type created.

SQL> CREATE OR REPLACE TYPE Ot3 AS OBJECT


2 (Atl NUMBER,
3 At2 REF Ot3) ;
4 /
Type created.

SQL> CREATE TABLE Tab2 OF Ot2;


Table created. •

SQL> CREATE TABLE ТаЬЗ OF Ot3;


Table created.

SQL> DESC ТаЬЗ


Name Null? Type

ATI NUMBER
AT2 REF OF OT2

SQL> DECLARE
2 'I_ref_ot2 REF Ot2;
3 BEGIN
4 INSERT INTO Tab2 t
5 VALUES('A','В',EMPTY_BLOB(),SYSDATE)
6 RETURNING REF(t) INTO I_ref_ot2;
7 INSERT INTO ТаЬЗ VALUES (I, I_ref_ot2);
8 END; . .
9 /
467
16*
Раздел 8
I

PL/SQL procedure successfully completed.

Листинг 247. Пример работы с REF-ссылками

Очевидно, что для REF напрашивается прямая аналогия с


ROWID, но есть и различия. ROW1D не изменяется в течение
жизни строки в таблице (если с базой данных не производятся
специальные операции), а с переменными типа REF можно
производить следующие действия: присваивать значение дру-
гой переменной типа REF; устанавливать ее значение в NULL
и т. п.
REF состоит из следующих частей: ROWID (при опреде-
лении атрибута таблицы, имеющего тип REF, необходимо
указать WITH ROWID); уникального идентификатора табли-
цы; уникального идентификатора объекта. При объявлении
переменной типа REF можно определить ее структуру (какие
из перечисленных частей включать в нее, т. к. единственной
обязательной частью REF является идентификатор объекта).
Когда сервер Oracle обращается к объекту, на который
ссылается REF, он использует ROWID для выбора строки из
таблицы. Если ссылка не содержит ROWID, то сервер ис-
пользует идентификатор таблицы и идентификатор объекта,
по которым построены индексы.
Как следует из вышесказанного, REF является ссылкой на
объект. Обратной функцией, которая позволяет по ссылке
. обратиться к объекту, является DEREF. Пример работы с ней
представлен в листинге 248.

SQL> DECLARE
2 I_ref_ot2 REF Ot2;
3 I_ot2 Ot2;
4 BEGIN •
5 SELECT At-2 INTO I_ref_ot2
6 FROM Tab3 WHERE At 1=1;
7 SELECT DEREF(I_ref_ot2) INTO I_ot2
468
Объектные расширения в OracleS
8 FROM dual;
9 DBMS_OUTPUT.PUT_LINE(l_ot2.Atl);
10 END;
11 /
A

PL/SQL procedure successfully completed.

Листинг 248. Применение операции DEREF

При определении атрибута таблицы, имеющего тип REF,


можно ограничить область действия ссылки, указав таблицу
объектов, в которой хранятся объекты, на которые может
ссылаться данная переменная. Такие ссылки называются ог-
раниченными. Они могут ссылаться только на объекты, хра-
нящиеся в специфицированной таблице. Если создать другую
таблицу объектов того же типа, то данная переменная не
сможет указывать на объект из новой таблицы. В ограничен-
ных ссылках не используются ROWID и идентификатор таб-
лицы (то есть они состоят только из идентификатора объек-
та). Так как при обращении к объекту по ограниченной
ссылке сервер заранее знает таблицу, в которой хранятся объ-
екты, то доступ к объектам через такие ссылки осуществляет-
ся быстрее. Для работы с такими ссылками требуется приви-
легия на получение данных из этой таблицы или системная
привилегия SELECT ANY TABLE.
Следующий листинг демонстрирует изменение описания
таблицы объектов ТаЬЗ.

SQL> ALTER TABLE ТаЬЗ


2 ADD (SCOPE FOR (At2) is. ТаЬЗ);.
Table altered.

Листинг 249. Пример указания таблицы, в которой


хранятся объекты, с •помощью ограниченных
ссылок

469

.
Раздел 8

Если в таблице объектов удалить объект, на который име-


ется REF-ссылка, то такая ссылка становится "зависшей". Для
поиска таких ссылок используются запросы со специальными
предикатами IS DANGLING. "Зависшие" ссылки не то-
ждественны пустым. Для проверки ссылки на "пустоту" ис-
пользуется стандартный предикат IS NULL. При попытке об-
ратиться к объекту по пустой или "зависшей" ссылке ошибки
не произойдет, будет возвращено NULL-значение. Для
иллюстрации вышесказанного приведем следующий пример:

SQL> DELETE FROM Tab2;


1•row deleted.

SQL> SELECT COUNT(*) FROM Tab3 WHERE At2 IS NULL;

COUNT(*)

SQL> SELECT COUNT(*) FROM ТаЬЗ


2 WHERE At2 IS DANGLING;

COUNT(*)

Листинг 250., Пример поиска зависших (DANGLING) и


пустых (NULL) ссылок

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

TABLES). Наборы имеют конструкторы, представляющие


собой функцию, имя которой совпадает с именем типа набо-
ра, а аргументами является некоторое число объектов.
' Массив — это упорядоченный набор данных одного типа.
Каждый элемент массива имеет индекс, который является
числом, соответствующим позиции элемента в массиве. Ко-
личество элементов в массиве называется размером массива.
Массив имеет переменную длину. При объявлении массива
необходимо указать его максимально возможный размер.
При проектировании базы данных рекомендуется вы-
брать VARRAY, если:
— важен порядок элементов в наборе (записи в массивах
переменной длины упорядочены);
—известно ограничение на количество элементов в на-
боре (при описании массива указывается его максимально
возможный размер, что позволяет более эффективно хранить
их по сравнению с вложенными таблицами, размер которых
неограничен).

Для объявления массивов используется оператор


CREATE TYPE следующего вида:

SQL> CREATE OR REPLACE TYPE Tml AS


2 VARRAY(10) OF NUMBER;
3 /
Type created.
Листинг 251. Пример, иллюстрирующий объявление
массива

Можно объявить массив, элементы которого будут иметь


скалярный тип, тип записи или объектный тип PL/SQL. Для
элементов массива можно указать ограничение NOT NULL.
Создание массивов производится стандартным образом — с
помощью конструктора, имя которого совпадает с именем

471
Раздел 8

типа, а обращение к элементам — с указанием индекса. Для


увеличения размера массива служит метод EXTEND, однако
увеличить размер массива так, чтобы он вышел за пределы,
указанные при его объявлении, нельзя.
Также массивы можно использовать для объявления типа
переменных в программах на PL/SQL.

SQL> DECLARE
2 TYPE m IS VARRAY(26) OF VARCHAR2(1};
3 l_mass m;
4 BEGIN
5 1 mass := m ( ' A ' , ' B ' , ' C 1 , ' D 1 , ' E 1 ) ;
6
DBMS_OUTPUT.PUT_LINE(l_mass(l)||l_mass(2)||l_mass
(3));
7 END;
8 /
ABC

PL/SQL procedure successfully completed.

Листинг 252. Пример, иллюстрирующий объявление


массива

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


ется метод COUNT. В листинге 253 приведен пример созда-
ния таблицы, один из столбцов которой объявлен как массив,
и функции, которая позволяет вывести в запросе все значения
элементов массива через точку с запятой. Аналогичным обра-
зом можно определить и другие функции, например, для дос-
тупа к конкретному элементу набора по его индексу или по-
лучения актуального размера массива.

gQL> CREATE OR REPLACE TYPE Tm2 AS OBJECT


2 (Atl VARCHAR2(30),
3 At2 Tml);
4 /
472
Объектные расширения в OracleS
Type cheated.

SQL> CREATE TABLE Tab4 OF Tm2;


Table created.

SQL> INSERT INTO Tab4 .


2 VALUES ('Tm2('A', Tml(1,2,3)));
1 row created.-

SQL> INSERT INTO Tab4


2 VALUES (Тт2('В', Tml(4,5,6)});
1 row created.

SQL> CREATE OR REPLACE FUNCTION f2(pi IN Tml)


2 RETURN VARCHAR2 AS
3 s VARCHAR2(255);
4 i INTEGER;
5 BEGIN
6 FOR i IN 1..pi.COUNT LOOP
7 s:=s| Г; ' | ITO_CHAR(pl(i));
8 END LOOP;
9 RETURN SUBSTR(s,2);
10 END;
11 /
Function created.

.SQL> SELECT Atl,f2(At2) FROM Tab4;


ATI F2(AT2)

A 1;2;3
B. 4; 5; 6

Листинг 253. Пример, иллюстрирующий обработку


функцией массива в запросе ,

С помощью операторов SQL с массивами в таблицах


можно работать только целиком, модифицировать его от-
дельные элементы нельзя. То есть сначала необходимо счи-
тать значение массива в переменную такого же типа в про-
грамме на PL/SQL, изменить ее значение (значения элементов
массива) и занести обратно в таблицу.

473
Раздел 8

Вложенные таблицы
Вложенная таблица — это неупорядоченный набор дан-
ных одного типа. Она имеет один столбец встроенного или
определенного пользователем типа. Если этот столбец объ-
ектного типа, то вложенная таблица может рассматриваться
как многостолбцовая таблица со столбцом для каждого атри-
бута типа объекта. Работа с вложенными таблицами очень
похожа на работу с PL/SQL таблицами. Работать с вложен-
ными таблицами можно как с динамическими переменными в
программах на PL/SQL, а также хранить в базе данных. Далее
будем рассматривать вложенные таблицы в базе данных.
При создании таблицы объектов необходимо указать таб-
лицу-хранилище для строк вложенной таблицы. Все вложен-
ные таблицы данной объектной или реляционной таблицы
хранятся в таблице-хранилище. Для разных таблиц объектов
необходимо использовать разные таблицы-хранилища. С точ-
ки зрения реализации отличие между массивами-переменной
длины и вложенными таблицами заключается в том, что дан-
ные вложенных таблиц хранятся в еще одной специальной
таблице, а данные массивов хранятся в той же таблице. При-
мер создания таблицы, тип одного из столбцов которой объ-
явлен как вложенная таблица, приведен ниже. Для хранения
вложенной таблицы используется таблица-хранилище
Tab5 At2 NESTED TABLE.

SQL> CREATE OR REPLACE TYPE Ot4 AS OBJECT


2 ( Atl NUMBER,
3 At2 VARCHAR2(2000));
4 /
Type created.

SQL-> CREATE OR REPLACE TYPE Ttl


2 AS TABLE OF Ot4;
3 /
Type created.
474
Объектные расширения в OracleS

SQL> CREATE TABLE Tab5


2 (Atl NUMBER,
3 At2 Ttl)
4 NESTED TABLE At2
5 STORE AS Tab5_At2_NESTED_TABLE;
Table created.

Листинг 254. -Пример объявления вложенной таблицы

Инициализация вложенной таблицы производится с по-


мощью функции конструктора, имя которого совпадает с на-
званием таблицы.
С вложенными таблицами, хранящимися в базе данных,
можно выполнять различные операции, как со всей таблицей,
так и со строками. Порядок работы с родительской таблицей
ничем не отличается от обычного, а для доступа к вложенным
таблицам предназначены расширения, предусмотренные в
реализации SQL. Первым из них является раскрывающий
подзапрос (оператор THEQ), позволяющий выбрать одну таб-
лицу, над которой будут производиться операции. Обязатель-
ным условием является единственность возвращаемой табли-
цы (запрос в предложении THE должен возвращать одну за-
пись, в противном случае будет получено сообщение об
ошибке). Также раскрывающий подзапрос используется для
вставки строк во вложенную таблицу, обновления данных в
ней и удаления строк из нее. Проиллюстрируем технику
вставки записей во вложенную таблицу на примере следую-
щего выражения INSERT. Здесь использован конструктор ти-
па Ttl.
После инициализации вложенной таблицы как значения
столбца родительской таблицы можно обратиться к ней непо-
средственно.

SQL> INSERT INTO Tab5 VALUES (10,Ttl());


1 row created.
475
Раздел 8
SQL> INSERT INTO
2 THE
3 (SELECT At 2 FROM Tab5 .t
4. WHERE t.At1=10) VALUES (Ot4(1,'A')); ~
1 row created.

-SQL> INSERT INTO Tab5 VALUES (10,Ttl()).;


1 row created.
. \ .
SQL> INSERT INTO
2 THE
3 {SELECT At2 FROM Tab5 t
4 WHERE t.Atl=10) VALUES (Ot4(1,'A'));
(SELECT At2 FROM Tab5 t
*
ERROR at line 3:
ORA-01427: single-row subquery returns more than
one row

Листинг 255. Пример вставки записей во вложенную


таблицу, идентифицированную оператором THE

Техника удаления и изменения данных во вложенных


таблицах идентична и представлена в листинге 256.

SQL> UPDATE
2 THE
3 (SELECT At2 FROM Tab5 ,'t
4 WHERE t.At1=10) nt
5 SET nt.At2 ='B';
1 row updated.

SQL> DELETE FROM


2 THE
3 (SELECT At2 FROM Tab5 t
4 WHERE t.At1=10) nt
5 WHERE nt.At2 ='В';
1 row deleted.

Листинг 256. Пример, иллюстрирующий изменение и


удаление данных во вложенной таблице,
идентифицированной выражением THE()
476
Объектные расширения в OracleS

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


ются вложенные курсоры (NESTED CURSORS). Вложенный
курсор объявляется с помощью ключевого слова CURSOR в
списке операндов оператора SELECT. Вложенные курсоры
можно использовать только для выбора данных из таблицы.
Для вставки, удаления или обновления данных во вложенных
таблицах их использовать нельзя. В приведенном в листин-
ге 257 запросе выражение CURSOR возвращает курсор-
указатель (в открытом состоянии) для каждой строки'запроса.
После получения значения вложенного курсора его можно
использовать аналогично обычным курсорам для доступа к
строкам вложенной таблице.

SQL> SELECT At 1, CURSOR '(SELECT *


2 FROM TABLE ( t . A t 2 ) ) At2 FROM Tab5 t;
ATI AT2

10 CURSOR STATEMENT :
CURSOR STATEMENT
ATI AT2

1 A
2 В

Листинг 257. Доступ к вложенной таблице с помощью


вложенных курсоров

Вложенные таблицы и массивы являются объектными


типами и имеют методы. Некоторые из них уже были исполь-
зованы при иллюстрации работы с наборами. В таблице 37
приведен полный список методов и выполняемых ими дейст-
вий. Методы используются при разработке программ PL/SQL,
более подробно ознакомиться с их назначением и примерами
можно в документации Oracle Application Developer's Guide.

477

• •
Раздел 8

Таблица 37. Методы наборов

Метод Описание
EXISTS Определяет, существует ли
некоторый элемент набора.
COUNT Возвращает число элементов набора.
LIMIT Возвращает максимальное число
элементов набора.
FIRST/LAST Возвращает первый/последний
элемент набора.
NEXT/PRIOR Возвращает элемент набора,
следующий/предыдущий по
отношению к данному элементу.
EXTEND Добавляет элементы к набору.
TRIM Удаляет элементы, начиная с конца
набора.
DELETE Удаляет указанные элементы из
набора.

Спецификации доступа
Спецификации доступа — это директивы компилятора,
запрещающие указанному методу доступ к объектам базы
данных. Их назначение аналогично назначению так называе-
мых "уровней чистоты" для пакетных функций PL/SQL, кото-
рые можно использовать в SQL-запросах (подробно об этом
рассказывается в разделе "PL/SQL — процедурное расшире-
ние языка SQL"). Спецификации доступа перечислены в таб-
лице 38.
Таблица 38. Спецификации доступа

Директива Ограничения
WNDS Данному методу запрещена
модификация данных в таблицах
(представлениях) базы данных.
478
Объектные расширения в OracleS

WNPS Данному методу запрещена


модификация пакетных переменных.
RNDS Данному методу запрещено чтение
данных из таблиц и представлений
базы данных.
RNPS Данному методу запрещено чтение
" значений переменных, хранимых в
пакетах.

Указание спецификаций доступа при определении заго-


ловка объектного типа позволяет потом не заботиться о том,
что при определении тел методов в них будут совершены дей-
ствия, которые не являются необходимыми при работе этих
методов. Помимо некоторых моментов, связанных с реализа-
цией механизма методов объектов в сервере Oracle, это важно
по следующим причинам.
Определять заголовок объектного типа и тела его мето-
дов могут разные пользователи. При определении специфи-
каций доступа не будет возможности осуществлять действия,
создающие угрозу безопасности данным. Все запросы, испол-
нение которых производится во время работы метода, испол-
няются с привилегиями пользователя, создавшего тип, или
пользователя, использовавшего данный тип (при применении
динамического SQL). В дальнейшем Oracle планирует пре-
доставить возможность указания привилегий конкретного
пользователя (создавшего метод или его вызвавшего).
В листинге 258 приведен пример попытки создания тела
объектного типа с двумя методами, обладающими различны-
ми спецификациями доступа, функция fl не должна модифи-
цировать информацию из базы данных, а функция f2 не
должна читать данные из таблиц и представлений. Как следу-
ет из примера, на этапе компиляции обнаруживается, что
функция f2 не соответствует своим ограничениям (осуществ-
ляет выборку данных из таблицы dual).

479
Раздел 8

SQL> CREATE OR REPLACE TYPE Ot7 AS OBJECT


2 (Atl NUMBER,
3 At2 DATE,
4 At3 DATE,
5 MEMBER FUNCTION fl RETURN NUMBER,
6 MEMBER FUNCTION f2 (pi IN NUMBER) RETURN
VARCHAR2,
7 PRAGMA RESTRICT_REFERENCES (fl,WNDS),
8 PRAGMA RESTRICT_REFERENCES (f2, RNDS) -) ;
9 ./
Type created.

, SQL> CREATE OR REPLACE TYPE BODY Ot7 IS


2 MEMBER FUNCTION f1 RETURN NUMBER AS
3 BEGIN
4 RETURN TRUNC(At3-At2);
5 END;
6
7 MEMBER FUNCTION f2 (pi IN NUMBER) RETURN
VARCHAR2 AS
8 1 NUMBER;
9 BEGIN
10 SELECT COUNT(1) INTO 1 FROM dual;
11 END;
12 END;
/
Warning: Type Body created with compilation er-
rors .

SQL> show errors


Errors for TYPE BODY OT7:
1
LINE/COL ERROR

7/8 PLS-00452: Subprogram 'f2' violates its


associated pragma

Листинг 258. Пример попытки создания тела объект-


ного типа, одна из функций которого наруша-
ет свою спецификацию доступа

480
,

'.
Объектные расширения в OracleS

Объектные представления
Объектные представления позволяют обращаться к дан-
ным из реляционных таблиц. Обычно они используются, если
приложение не допускает изменения структуры таблиц и не-
обходимо организовать поддержку объектов в базе данных.
При создании объектного представления с помощью конст-
рукции WITH OBJECT OID указывается идентификатор объ-
екта. В следующем примере данные хранятся в реляционной
таблице ТаЬб, а объектное представление Ovl содержит
один столбец предварительно созданного типа Ot5.

SQL> CREATE OR REPLACE TYPE Ot5 AS OBJECT


2 (Atl NUMBER,
3 At2 VARCHAR2(40));
4 /
Type created.

SQL> CREATE TABLE Tab6


2 (Atl NUMBER,
3 At2 VARCHAR2(40));
Table created.

SQL> CREATE OR REPLACE VIEW Ovl OF Ot5


2 WITH OBJECT OID(Atl)
3 AS SELECT Atl,At2 FROM Tab6;
View created.

SQL> INSERT INTO ТаЬб VALUES (1,'A1);


1 row created.

SQL> SELECT VALUE(v) FROM Ovl v;

VALUE(V)(ATI, At2)

OT5(1, 'A')
Листинг 259. Пример, иллюстрирующий создание объ-
ектного представления, над реляционной таб-
лицей и выборку объектов из него.
481
Раздел 8

Важной особенностью OracleS является появление нового


типа триггеров. Наряду с триггерами BEFORE и AFTER для
реляционных таблиц, новый тип триггеров INSTEAD OF
предназначен специально для объектных представлений. Этот
триггер срабатывает при попытке модификации данных с ис-
пользованием объектного представления. В листинге 260
представлен сценарий создания такого триггера и его сраба-
тывания при применении операторов модификации данных к
объектному представлению Ovl.

SQL> CREATE OR REPLACE TRIGGER Tr2.


2 INSTEAD OF INSERT ON Ovl
3 BEGIN
4 INSERT INTO ТаЬб VALUES(:NEW.Atl,:NEW.At2);
5 END;
6 /
Trigger created.

SQL> INSERT INTO Ovl VALUES ( 2 , ' B 1 ) ;


1 row created.

Листинг 260. Пример, иллюстрирующий создание объ-


ектного представления и выборку объектов из
него.

Триггер Тг2 срабатывает в момент вставки новой записи


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

482
Oracle 9i
Как и любая фирма, разрабатывающая программное
обеспечение, Oracle выпускает исправления (патчи) для те-
кущих релизов сервера баз данных и других продуктов и вре-
мя от времени (обычно с интервалом в несколько лет)
представляет новые версии программ. В первой половине
2001 г. (официальное объявление широкой публике
произошло в Англии в декабре 2000 г.) на рынке появилась
версия Oracle 9i. Это событие можно рассматривать гораздо
шире чем обычно, ведь изменениям подвергся не один
конкретный продукт, а все семейство. За словами Oracle 9i
стоят две ключевые технологии: Oracle 9i Application Server и
Oracle 9i Database.
Настоящая книга посвящена технологии баз данных
Oracle и не включает описание инструментальных средств
разработки, сервера приложений, комплексов анализа данных
и т. п. Поэтому остановимся кратко на основных особенно-
стях Oracle 9i Database.
В основном они связываются с хранилищами данных и
аналитической обработкой информации. В состав Oracle 9i
Database включены средства добычи данных (data mining), a
так же средства извлечения, преобразования и загрузки (ETL)
для хранилищ данных. Средства ETL предназначены для
прямого обращения к внешним данным, например к тексто-
вым файлам с помощью обычных SQL-операторов.
Предполагаются и новшества другого порядка. Так, в
Oracle 9i Database должна быть встроена поддержка
возможности персонализации в реальном времени.
Назначение этой возможности связано с позиционированием
сервера баз данных как платформы для электронной
коммерции. Персонализация посетителей Web-узла позволит
выдавать им рекомендации, основываясь на индивидуальных
профилях, хранимых в базе данных, и текущем поведении
пользователей.
483
Нововведения затронули и языковые средства Oracle.
SQL в Oracle 9i соответствует требованиям стандарта ANSI
SQL99. В язык введено много новых синтаксических конст-
рукций. В SQL также появились новые типы данных, напри-
мер, тип TimeStamp дает возможность хранить в базе данных
даты с точностью до долей секунды. Для аналитической об-
работки введены новые статистические функции, позволяю-
щие выполнять операции, ранее специфичные для OLAP-
приложений, например, вычислять параметры тренда или вы-
являть зависимость двух выборок значений случайных вели-
чин.
Изменения появились и в PL/SQL. В основном они кос-
нулись внутренней среды, обеспечивающей эффективное ис-
пользование ресурсов сервера для работы PL/SQL-программ,
но появились и новые операторы, предназначенные, в частно-
сти, для работы с наследованием.
Сервер баз данных стал значительно интеллектуальнее.
Многие рутинные операции администрирования и конфигу-
рирования теперь выполняются автоматически или макси-
мально автоматизированы.
Применение Oracle 9i Database в электронной коммерции
предъявляет повышенные требования к системе безопасно-
сти. Для демонстрации защищенности web-узла, построенно-
го на основе Oracle 9i, корпорация специально провела акцию
"Неуязвимый Oracle", предложив всем,желающим атаковать
свой сайт. Система виртуальных частных баз данных и про-
верка безопасности в контексте приложений предназначены
для активно развивающейся бизнес-схемы сдачи приложений
в аренду.
В завершение краткого изложения в духе "выше, дальше,
быстрее" следует отметить, что основные положения техно-
ло^гий Oracle, представленные в книге, останутся актуальны-
ми и для 91 и для следующих релизов. Дело даже не в том, что
авторам хочется, чтобы их книга была востребованной в те-
чении как можно большего времени, а в том, что уровень
языковых средств и механизмов сервера более чем за 20 лет
484
эксплуатации достиг в некотором смысле совершенства и
вряд ли будет заметно меняться в дальнейшем. Например,
вряд ли для генерации уникальных значений можно приду-
мать механизм, работающий удобнее последовательностей
(sequence). Кроме того, существует огромное количество при-
ложений и баз данных, работающих под управлением млад-
ших версий Oracle, для которых в силу каких-либо причин не
планируется переход на другие версии.
Также хочется отметить, что конкуренция на рынке кор-
поративных СУБД довольно велика и это обстоятельство
иногда заставляет производителей в целях захвата новых сег-
ментов рынка, продвижения новых технологий и т. п. выпус-
кать не до конца доведенные версии программных продуктов.
Первый релиз сервера баз' данных Oracle 9i содержит'серьез-
ные ошибки (например, включение поддержки ANSI-
синтаксиса для внешних соединений привело к тому, что лю-
бой пользователь получает возможность просмотра данных из
любой таблицы). Поэтому, как и для всего нового, требуется
некоторое время для широкомасштабной обкатки Oracle 9i
Database.
Всего же для подробного описания новых возможностей
Oracle 9i потребуется несколько книг. Поэтому специалистам,
желающим системно овладеть этими новыми, стремительно
развивающимися технологиями в области баз данных, можно
порекомендовать прослушать специально построенный набор
курсов в каком-либо авторизованном центре обучения Oracle
в соответствии с выбранной для себя специализацией. В на-
стоящее время в этих центрах существуют программы подго-
товки администраторов, разработчиков приложений, проек-
тировщиков и аналитиков. Вместе с тем хочется отметить,
что все без исключения наборы включают в себя подготовку
по SQL, PL/SQL, разграничению доступа и архитектуре сер-
вера баз данных Oracle. Надеемся, что в изучении этой обяза-
тельной части вам поможет наша книга.

•: , .
485
ЯМ

-
Заключение
Перевернута последняя страница последнего раздела этой
книги. Настала пора подвести некоторые итоги. Прежде все-
го, есть смысл оценить степень усвоения материала книги,
проведя анализ степени достижения целей каждого раздела.
Основная задача, решаемая в первом разделе, — дать об-
щее представление об архитектурах и компонентах распреде-
ленной системы обработки данных. Цель данного раздела
достигнута, если у читателя сформировано четкое представ-
ление об архитектуре сервера Oracle, его основных возмож-
ностях, различных архитектурах информационных систем,
организации локальных сетей, рассматриваемых как основа
распределенных систем обработки данных, общих принципах
конфигурирования сетевых средств Oracle, организации дос-
тупа к серверу базы данных.
Основная цель второго раздела — систематическое изло-
жение языка SQL. Читателя, успешно усвоившего темы вто-
рого раздела, характеризует умение создавать и изменять ос-
новные объекты Oracle и управлять данными.
Читателя, овладевшего материалом третьего раздела, от-
личает умение создавать и отлаживать прикладные програм-
мы на языке PL/SQL. Для эффективной разработки программ
читатель получил сведения о стандартных пакетах, входящих
в комплект поставки сервера.
Полученные в первых трех разделах теоретические пред-
ставления и навыки активно используются при обсуждении
методов и средств разграничения доступа и аудита Oracle,
рассмотренных в четвертом разделе.
• Итогом изучения пятого раздела должно стать умение
написать и интегрировать в систему обработки данных при-
кладную программу на языке Java и построить приложение-
апплет для обеспечения доступа к серверу баз данных на ос-
нове универсального клиента.

486
Шестой раздел должен сформировать понимание концеп-
ции и основных методов обеспечения целостности базы дан-
ных в условиях многопользовательского доступа и умение
использовать соответствующие средства и утилиты Oracle.
Для углубления полученных знаний предназначен седь-
мой раздел о способах, повышающих скорость доступа к дан-
ным. Он должен предоставить знания, необходимые для эф-
фективного применения изученных языковых средств для ра-
боты с большими и сверхбольшими базами данных.
Читатель, изучивший восьмой раздел, ознакомился с ос-
новным направлением развития современных технологий баз
данных. Объектные расширения предлагаются практически
всеми крупными поставщиками решений в этой области и
Oracle не исключение.
Что же делать дальше?
Во-первых, продолжать изучение литературы. В послед-
нее время вышло большое количество книг о современных
технологиях обработки данных в системах промышленного
уровня. Ряд издательств выпускает серии книг, предназна-
ченных для профессиональных разработчиков, проектиров-
щиков, администраторов, других специалистов, работающих
с Oracle. Специальные серии ориентированы на начинающих
пользователей. Издательство "Гелиос" также планирует про-
должить публикации учебных материалов по технологиям и
продуктам Oracle.
Во-вторых, использовать для пополнения и совершенст-
вования своих знаний практически неограниченные инфор-
мационные ресурсы Internet. В настоящее время количество
Web-серверов, содержащих информацию о технологиях и
продуктах Oracle, постоянно увеличивается. Выходят элек-
тронные версии специализированных журналов. В различных
конференциях и форумах можно задать интересующие вопро-
сы или найти готовые решения. Адреса некоторых Web-
ресурсов приведены ниже.
В-третьих, (в перечислении, но не по значимости) посто-
янно практиковаться в решении конкретных задач. Решение
487
бесконечно многообразных и постоянно возникающих задач
обработки информации есть не только способ зарабатывать
на жизнь, но и источник самосовершенствования. Изящное
решение сложных задач, которых множество в сфере обра-
ботки данных, может принести и приносит незабываемое эс-
тетическое наслаждение.
Нам же остается пожелать Вам успехов в освоении и по-
строении систем распределенной обработки информации на
базе технологий Oracle.
Литература
1. Бобровски С. OracleS. Архитектура. — М.: ЛОРИ, 1999.
2. Пейдж Б., ХьюзН., Остин Д. Использование OracleS. —
К.; М.; СПб.: Вильяме, 1998.
3. Баженова И. Ю. Oracle 8/8i. Уроки программирования.
— М.: Диалог-МИФИ, 2000.
4. Урман С. OracleS. Программирование на языке PL/SQL.
— М.: Изд-во ЛОРИ, 1999. .
5. Эбби М., Кори М. OraeleS: Первое знакомство. — М.:
ЛОРИ, 1998.
6. Энсор Д., Стивенсон И. Oracle. Проектирование баз
данных. — К.: BHV, 1999.
7. Koch G., Loney К, OracleS; The complete Reference. —
Osborne/McGraw-Hill, 1997.
8. Theriault M., Heney W. Oracle Security. —
O'Reilly&Associates, Inc., 1998.
Адреса основных Web- серверов Internet, содержащих ин-
формацию о технологиях, продуктах Oracle и опыте их ис-
пользования.
Адрес в сети Internet Описание Web-сервера
www.oracle.com Web-сервер корпорации
Oracle
www.oracle.com/ru/oramag Web-сервер журнала Oracle
Magazine (RE)
www.oracle.ru Web-сервер представительст-
ва корпорации Oracle в РФ
www.fors.ru Web-сервер фирмы ФОРС
(Москва)
www.interface.ru Web-сервер фирмы Interface
Ltd. (Москва)
www.rdtex.ru Web-сервер фирмы RDTeX
(Москва)
Содержание
Азбука Oracle 3
Предисловие ко второму изданию 8
Благодарности ..12
Раздел 1. Архитектура распределенных систем обработки
данных 13
Средства обработки данных: эволюция идей и систем 13
Эволюция реляционных СУБД на фоне истории Oracle 18
OracleS. Основные возможности.. : 20
Архитектуры обработки данных 27
Локальные вычислительные сети как среда передачи данных 33
Эталонная модель взаимодействия открытых систем 35
Компоненты распределенной системы и ЭМВОС..; 41
Конфигурирование сетевых компонент Oracle. 43
Архитектура сервера Oracle 48
Использование инструментального средства SQL*Plus 54
Информация о результатах операции 60
Поддержка мультиязычности в Oracle 62
Соглашения, принятые для описания команд.. 65
Раздел 2. SQL — язык обработки данных Oracle 66
Основные объекты Oracle 67
Средства манипулирования данными языка SQL , 73
Структура запроса 74
Простейшие запросы: 74
Формирование критерия отбора, ..77
Базовые средства определения критерия отбора , 79
Язык описания данных Oracle 81
Типы данных Oracle 82
Строки символов 82
Числовые типы 84
TnnROWID 86
Битовые строки 87
Дата и время 88
LOB-объекты 90
Таблицы. Представления. Пользователи 91
Создание и удаление таблиц в Oracle 91
Средства определения и уничтожения представлений 97
Средства регистрации и исключения пользователей 103
4.91
Операция вставки строк... 107
Операция удаления строк 109
Операция модификации строк ! ; 111
Специальные предикаты SQL 112
Предикат IN 113
Предикат BETWEEN 114
Предикат LIKE 116
Предикат IS NULL 118
Предикат EXISTS 120
Предикаты с кванторами ALL, ANY и SOME 121
Теоретико-множественные операции 122
Внешнее объединение 125
Сортировка 128
Иерархии 130
Группирование и агрегатные функции 133
Синтаксис языка запросов 139
Связи с удаленными базами данных. Снимки данных 143
Создание связей с удаленной базой данных Oracle 143
Средства определения и уничтожения снимков 146
Последовательности. Синонимы 151
Создание последовательностей 151
Создание синонимов в Oracle 157
Работа с табличными областями в Oracle 161
Раздел 3. PL/SQL — процедурное расширение языка SQL..... 165
Структура программы на PL/SQL 166
Переменные, константы и типы„ 167
Управление выполнением программы 169
Оператор ветвления 170
Операторы цикла 171
Оператор GOTO .....174
Курсоры 174
Обработка исключительных ситуаций *... 182
Процедуры, функции и пакеты 188
SQL-функции Oracle 189
Функции, устанавливающие соответствие числовых кодов и
символов 189
Функции преобразования символов подстрок 190
Символьные функции усечения и дополнения строк 192
Символьные функции преобразования строк 194

492
Функции, связанные с выделением подстрок 195
Числовые функции, связанные с возведением в степень и
логарифмированием 197
Тригонометрические функции 198
Числовые функции, связанные с округлениями 200
Числовые функции, связанные со знаком числа 201
Числовые функции, связанные с модулярной арифметикой....202
Функции, оперирующие с датами 203
Функции преобразования типов данных 205
Функции замены аргументов 208
Справочные функции 211
Создание пользовательских процедур и функций 213
Пакеты .-. ; 220
Триггеры базы данных : ....228
Стандартные пакеты Oracle 238
Динамический SQL. , 238
Файловый ввод-вывод ,....: .....245
Управление заданиями 248
Управление LOB-объектами '. 252
Управление многопользовательским доступом 258
Использование функций PL/SQL в SQL-выражениях 262
Раздел 4. Средства разграничения доступа в Oracle 264
Анализ включающей инфраструктуры 266
Идентификация пользователей.. 270
Базовое понятие системы разграничения доступа—
привилегии 272
Предоставление системных привилегий 274
Системные привилегии, определяющие права по работе с
таблицами и представлениями 275
Системные привилегии, определяющие права по работе с
процедурами и триггерами. 279
Системные привилегии, определяющие права по работе с
пользователями 282
Системные привилегии, определяющие права по работе с
табличными областями 283
Системные привилегии, определяющие права по работе с
последовательностями... 285
Системные привилегии, определяющие права по работе с
синонимами 286
' 493
Системные привилегии, определяющие права по
выполнению глобальных действий в системе 288
Системные привилегии, определяющие права по
выполнению действий с остальными объектами БД... 288
Использование конструкции PUBLIC и параметра WITH
ADMIN OPTION , .292
Предоставление привилегий доступа к объекту 295
Управление привилегиями с помощью ролей 300
Системные привилегии, определяющие права по работе с
ролями 301
Предопределенные роли в Oracle 302
Создание ролей и предоставление им привилегий 304
Управление допустимостью использования ролей 305
Отмена привилегий 308
Отмена системных привилегий и ролей 308
Отмена привилегий доступа к объекту, 309
Использование представлений для разграничения доступа 310
Хранимые процедуры как средство разграничения доступа 312
Использование триггеров для повышения защиты системы 314
Средства аудита 319
Аудит системных событий 320
Аудит событий, связанных с доступом к объекту .....327
Прекращение регистрации событий 330
Обработка данных аудита 332
Профили пользователя как средство повышения
защищенности системы 337
Дополнительные сведения....: 340
Раздел 5. Создание приложений на языке Java ..342
Средства построения приложений и организации доступа к
базам данных 342
Создание приложений на языке Java 344
Простейшее приложение на Java 345
Простейший апплет 349
Выполнение SQL-операторов создания таблиц, ввода и
модификации данных ^ 353
Простая выборка данных 357
Параметрические запросы 362
Хранимые процедуры на языке Java 366

494
Раздел 6. Средства обеспечения целостности данных 376
Определение транзакции и ее роль в СУБД , ....378
Начало и окончание транзакции ...379
Предложения SQL, управляющие транзакциями 380
Предложение COMMIT WORK 381
Использование предложения SAVEPOINT ...383
Предложение ROLLBACK WORK 383
Непротиворечивость и параллельная обработка 385
Типы блокировок 391
Ограничения целостности ..393
Массовая загрузка данных 403
Экспорт/импорт данных 409
Раздел 7. Методы повышения производительности 417
Оптимизатор ,..., 418
Ранжирование методов доступа 420
Анализ запросов с целью повышения скорости их выполнения ...423
Задание режима оптимизации 424
Обзор индексов Oracle .......427
Эффективное кодирование SQL-выражений 433
Изменение плана выполнения запроса 437
Секционирование таблиц 445
Секционирование индексов 449
Операции с секциями.... 451
Индекс-таблицы,.... 453
Раздел 8. Объектные расширения в OracleS 455
Объектные типы 456
Объекты в базе данных 461
Ссылки на объекты.. 466
Массивы 470
Вложенные таблицы 474
Спецификации доступа 478
Объектные представления 481
Oracle 9i.. '. , 483
Заключение ....'. 486
Литература 489
Содержание 491

495

Учебное издание
Смирнов Сергей Николаевич, Задворьев Иван Сергеевич
Работаем с Oracle

Корректор £ Н. Клитина
ЛР № 066255 от 29.12.98. Издательство «Гелиос АРВ». www.gelios-arv.ru
107014, Москва, Верхняя Красносельская, 16. Тел. (095)264-44-39, e-mail: info@gelios-arv.ru.
Формат 84x108/32. Бумага газетная. 15,5 п. л. Тираж 3 000 экз. Заказ № 1628.
Отпечатано с готовых диапозитивов в РГУП «Чебоксарская типография № 1».
Адрес типографии: 428019, г. Чебоксары, пр. И. Яковлева, 15.

Вам также может понравиться