Вы находитесь на странице: 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