Работаем с ORACLE

advertisement
С. Н. Смирнов, И. С. Задворьев
Учебное пособие
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
АРХИТЕКТУРА
РАСПРЕДЕЛЕННЫХ
СИСТЕМ ОБРАБОТКИ
ДАННЫХ
Средства обработки данных:
эволюция идей и систем
Эффективное управление сложными организационными
системами требует использования современных средств автоматизации. Успешное решение задач возможно только тогда, когда для каждого контингента пользователей автоматизированных систем обработки информации создана отвечающая их потребностям среда обработки данных. Основная цель
всякой системы обработки информации — полное и своевременное удовлетворение информационных потребностей пользователей. Пользователь формулирует свои потребности на
каком-либо доступном ему языке. Существующие технические средства в состоянии воспринять только язык детальных
инструкций, поэтому необходима некоторая компонента системы обработки информации, которая обеспечит взаимодействие с пользователем на приемлемом языковом уровне. Помимо этого необходимы средства, обеспечивающие для разработчика системы приемлемый языковый уровень описания
технологических процессов обработки данных.
'i
'13
Раздел 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 — International 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.
,0.5.0.0 - Production
OracleS Enterprise Edition
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>
SQL>
2
3
4
set serveroutput on
BEGIN
DBMSJDUTPUT.PUT_LINE(SYSDATE);
END;
/
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'
G
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
Ul
DFORT
SELECT
4
UD
PLUS80W
Листинг 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:
ORA-01017:
IMP-00005:
IMP-00000:
ORACLE error 1017 encountered
invalid username/password;logon denied
all allowable logon attempts failed
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
INSERT
INSERT
INSERT
74
TABLE Tab! (Atl CHAR(3),At2 NUMBER);
INTO Tabl VALUES('A', 1);
INTO Tabl VALUES('B', 2);
INTO Tabl VALUES('С', 2);
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
2
2
A •
В
С
Листинг 15. Запрос, выводящий данные столбцов At2
и Atl таблицы ТаЫ в указанном порядке
Дополнительно пользователь может указать в списке вывода выражения, зависящие от значений столбца и заголовок,
который будет выведен на соответствующей позиции.
Ниже приведен пример запроса, выполняющего выборку
значений столбца At2/10 с соответствующим заголовком и
значения столбца Atl с присоединенной строкой:
SQL>SELECT At2/10 "At2/lQ",
2 'ATI = Ч |Atl "Header Atl" FROMVTabl;
At2/10 Header Atl
.1
.2
.2
ATI = A
ATI = В
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
FALSE AND UNKNOWN
UNKNOWN AND UNKNOWN
TRUE OR UNKNOWN
FALSE OR UNKNOWN
UNKNOWN OR UNKNOWN
NOT UNKNOWN
Результат
UNKNOWN
FALSE
UNKNOWN
TRUE
UNKNOWN
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
NUMBER(7,1)
NUMBER(5,2)
NUMBER(8,3)
NUMBER(7,-2)
Представление
при выполнении действий
123456
123456.7
ошибка в данных
123456.789
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 ТаЬЗ
Table created.
(Atl DATE, At2 NUMBER);
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
2
AAA
BBB
SQL> UPDATE Tabl SET At2 = 'CCC' WHERE Atl = 1;
1 row updated.
SQL> SELECT * FROM Tabl;
ATI
AT2
1
2
CCC
BBB
SQL> UPDATE Tabl SET Atl = Atl*1.5
2 WHERE At2 LIKE 'B%';
1 row updated.
SQL> SELECT * FROM Tabl;
ATI
AT2
1
3
.
CCC
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
INSERT
INSERT
INSERT
TABLE Tab! (Atl C H A R ( 3 ) , At2 NUMBER);
INTO Tabl V A L U E S ( ' A 1 , 1);
INTO Tabl V A L U E S ( ' B ' , 2 ) ;
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
INSERT
INSERT
INSERT
TABLE Tab! (Atl DATE, At2 NUMBER);
INTO Tabl VALUES(TOJ3ATE('01-01-2002'),1);
INTO Tabl V A L U E S ( T O _ D A T E ( ' 0 1 - 0 7 - 2 0 0 2 ' ) , 3 ) ;
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
01-01-2002
AT2
SYSDATE
1
11-04-2002-
SQL> SELECT * FROM Tabl
2 WHERE SIN(At2) BETWEEN 0 AND 1;
ATI
01-01-2002
AT2
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
INSERT
INSERT
INSERT
INSERT
INSERT
TABLE Tabl (Atl VARCHAR2(3));
INTO Tabl VALUES('AB');
INTO Tabl VALUES('ABC');
INTO Tabl VALUES('ACB1);
INTO Tabl VALUES('ADC');
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.
NULL
Примеры использования
предиката
IS
Предикат 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
CREATE
INSERT
INSERT
INSERT
INSERT
'INSERT
INSERT
TABLE Tab! (Atl NUMBER);
TABLE Tab2 (Atl NUMBER);
INTO Tabl VALUES (1);
INTO Tabl VALUES (2);
INTO Tabl VALUES (3);
INTO Tab2 VALUES (1);
INTO Tab2 VALUES (3);
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
1A
2В
3С
1 A
2 В
3 С
1 A
2 В
3С
9 rows selected.
ATI AT2
l a
l
l
3
3
3
a
a
b
b
b
5 с
5 с
. 5 с
SQL> SELECT * FROM Tabl,Tab2
2 WHERE Tabl.Atl=Tab2.Atl;
ATI AT2
1 A
3 С
ATI AT2
l a
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
2
3
A
В
С
l
a
3
b
SQL> SELECT * FROM Tabl,Tab2
2 WHERE Tabl.Atl(+) = Tab2.Atl;
ATI
1
з•
A
ATI
A
А
С
1
3
5
а
b
с
-
Листинг 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
INSERT
INSERT
INSERT
INSERT
INSERT
TABLE Tab! (Atl NUMBER, At2 VARCHAR2(1));
INTO Tabl VALUES (1, NULL);
INTO Tabl VALUES (1, 'A1);
INTO Tabl VALUES (2, 'B');
INTO Tabl VALUES (3, 'C');
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
20
30
30
A
В
С
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
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
TABLE Tab! (Atl NUMBER, At2 NUMBER);
INTO Tabl VALUES (1, 2)
INTO Tabl VALUES (1, 3)
INTO Tabl VALUES (2, 4)
INTO Tabl VALUES (3, 5)
INTO Tabl VALUES (4, 6)
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
LEVEL
1
2
3
1
2
3
START WITH Atl = 1;
ATI
AT2
1
2
4
1
3
5
2
4
6
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
3
1
7
2
3
5
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
INSERT
INSERT
INSERT
INSERT
TABLE Tabl (Atl NUMBER, At2 NUMBER);
INTO Tabl VALUES(1, 1);
INTO Tabl VALUES(1, 2);
INTO Tabl VALUES(2, 3);
INTO Tabl VALUES(2, 4);
Следующие запросы демонстрируют использования
группирования без дополнительных условий и с дополнительными условиями.
SQL> SELECT Atl, AVG(At2) "Среднее At2"
2 FROM Tabl GROUP BY Atl;
ATI
1
2
Среднее At2
1.5
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
1
2
Среднее At2
«•
2
2.5
Листинг 53. Примеры формирования условий, определяющих группу для групповой функции
Групповые функции возвращают результаты, вычисленные по группе строк, которые сформированы запросом с
предложением GROUP BY оператора SELECT.
При выполнении вычислений для групповых функций по
умолчанию используется ключевое слово ALL, которое указывает, что результат включает все значения атрибута, в том
числе и дублирующие. Если в запросе использовано ключевое
слово DISTINCT, то групповые функции рассматривают
только отличающиеся значения атрибутов или выражений.
Все групповые функции, кроме COUNT(*), не учитывают в
вычислениях атрибутов, имеющих неопределенное значения
(NULL). Для замены неопределенного значения числовых
135
Раздел 2
атрибутов на 0 обычно используют встроенную функцию
NVL.
Все примеры использования групповых функций базируются на таблице, созданной и заполненной предложениями:
CREATE
INSERT
INSERT
INSERT
INSERT
TABLE Tabl (Atl NUMBER);
INTO Tabl V A L U E S ( 1 ) ;
INTO Tabl V A L U E S ( 1 ) ;
INTO Tabl V A L U E S ( 2 ) ;
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 DATABASE 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
4
i
Листинг 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
2
SQL> SELECT Seql.NEXTVAL FROM dual;
NEXTVAL
3
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
2
SQL> SELECT Seq2.NEXTVAL FROM dual;
NEXTVAL
3
SQL> SELECT Seq2.NEXTVAL FROM dual;
NEXTVAL
1
Листинг 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
8
9
BEGIN
I := 0;
Arg := 1;
10
11
12
LOOP
EXIT WHEN ARG > Limit;
Arg := A r g * ( I + D ;
14
END LOOP;
13
I := I + 1;
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>
2
3
4
5
6
7
8
9
10
DECLARE
Arg NUMBER:= 1;— Перем. для выч. факториала
Limit NUMBER := 20;.— Граница
Textl VARCHAR2(30) := 'Факториал числа 20=';
— Исполнительный блок
BEGIN
FOR I IN 1..Limit LOOP
Arg := Arg*I;
END LOOP;
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
INSERT
INSERT
INSERT
TABLE ТаЫ (Atl NUMBER, At2 V A R C H A R 2 ( 1 ) } ;
INTO ТаЫ VALUES (1, ' A 1 ) ;
INTO Tabl VALUES (2, r B ' ) ;
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 requested 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
3
4
5
6
vl V A R C H A R 2 ( 4 0 0 0 ) ;
BEGIN
FOR rec IN (SELECT Atl,At2 FROM Tabl) LOOP
vl:=LTRIM(vl||' '||rec.At2);
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
Символическое имя
предопределенной
исключительной
ситуации
LOGIN_DENIED
NOT_LOGGED_ON
INVALID_CURSOR
NO_DATA_FOUND ,
DUP_VAL_ON_INDEX
TOO_MANY_ROWS
VALUE_ERROR
исключи-
Описание
предопределенной
исключительной ситуации
i
Неуспешное подключение к серверу (например, введен ошибочный пароль)
Попытка выполнить действие без
подключения к серверу Oracle
Ссылка на недопустимый курсор
или недопустимая операция с
курсором .
Не найдены данные, соответствующие оператору SELECT INTO
Попытка вставить в столбец с
ограничением на уникальность
значения значение-дубликат
Оператор SELECT INTO возвращает более одной строки
Арифметическая ошибка, ошибка преобразования или усечения
Рассмотрим пример программы с обработкой исключительных ситуаций. В тексте программы пропущен оператор
открытия курсора. Поэтому при обращении к методу
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
20
DBMSJDUTPUT.PUT_LINE('Ошибка приложения');
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>
2
3
DECLARE
vl DATE;
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
5
SQL> SELECT INSTR('барабан','ба') "Функция INSTR"
FROM dual;
Функция INSTR
1
Листинг 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
1
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)
2 FROM dual;
"Функция TRUNC"
Функция 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)
1
1
SIGN(2)
. I
SIGN{-2)
--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
YY
MONTH
MON
MM
W
ODD
DD
J
DAY
DY
D
HH
Тип округления
Преобразование до года. Округление в
большую сторону происходит с 1 июля.
Преобразование до месяца. Округление в
большую сторону происходит с 16 числа.
Преобразование до того же дня недели, что
первый день месяца.
Преобразование до дня.
Преобразование до начального дня недели.
Преобразование до часа.
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;
S
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
ЕЕЕЕ
G
Вид выводимого результата
Выводится цифра. Лидирующий ноль заменяется пробелом.
Выводится цифра. Лидирующий 0 выводится.
Результат выводится в экспоненциальной
нотации.
Выводится символ-разделитель (обычно,
запятая).
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 "Функция
TO_NUMBER" FROM dual;
4
Функция ТО 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;
D
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
ul
UID
5
ENTRYID
TERMINAL
LANG
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>
2
3
4
5
SELECT chksum('Текст номер 1') chk FROM dual
UNION ALL
SELECT chksum('Текст номер 2') FROM dual
UNION ALL
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
4
END;/
PL/SQL procedure successfully completed.
SQL> SELECT * FROM Tabl;
ARG1
120
ARC 2
04-05-2002
Листинг 118. Протокол изменений в базе
выполняемых созданной процедурой
данных,
.
В большинстве случаев первая попытка скомпилировать
программу на PL/SQL (процедуру, функцию, пакет или триггер) приводит к получению сообщения о наличии в программе ошибок. Чтобы уточнить выявленные в процессе синтаксического анализа ошибки, можно воспользоваться командой
SQL*Plus SHOW ERRORS. Эта команда показывает ошибки,
обнаруженные в процессе выполнения CREATE PROCEDURE, CREATE FUNCTION, CREATE TYPE BODY, CREATE 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
5
6
7
Coeff CONSTANT NUMBER := 0.5;
BEGIN
Argl := Argl + 234;
INSERT INTO Tabl VALUES(Coeff*Argl,SYSDATE);
8
END;
Warning:
rors.
Procedure created with compilation er-
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(SYSDATE1/2, SYSDATE+1/2));
3
4
END;
/
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
1
AT2
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
6
7
8
StatStd NUMBER;
StatN NUMBER;
Special_case EXCEPTION;
BEGIN
9
SELECT COUNT(Atl),SUM(Atl),STDDEV(Atl)
10
INTO StatN, StatAvg, StatStd FROM Tabl;
. 11
IF (ABS(StatAvgStatN*(: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, trigger/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
5
INDEX BY BINARY_INTEGER;
At2_table Tabl_At2_type;
235
Раздел 3
6
7
8
9
10
11
12
13
14
15.
At2_ind BINARY_INTEGER;
PROCEDURE clear_count IS
BEGIN
At2_ind:=0;
END;
PROCEDURE add_At2(p_At2 IN INTEGER) IS
BEGIN
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
ATI
.* FROM Tabl;
AT2
2
Листинг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
CREATE
INSERT
INSERT
240
TABLE Tab!(At1 INTEGER, At2 DATE);
TABLE Tab2(Atl INTEGER, At2 DATE);
INTO Tabl VALUES(1,SYSDATE);
INTO Tabl VALUES(2,SYSDATE-10) ;
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
END IF;
' 21
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>
2
3
4
BEGIN
copy (' Tabl', ' Tab2'') ;
END;
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
CLOSE_CURSOR
COLUMNJVALUE
DEFINE_COLUMN
PARSE
EXECUTE
FETCH_ROWS
EXECUTE AND
FETCH
ISJ3PEN
LAST ERROR
POSITION
LAST_ROW
COUNT
244
вида IN или IN OUT, то связываемое
значение должно быть того же типа.
Закрывает открытый курсор, освобождая выделенную под него память.
Получает значение атрибута записи
курсора для текущей записи данного
курсора.
Определяет поле записи, которая
должна быть выбрана из курсора.
Разбор SQL-предложения для курсора. Если разбираемое предложение
является DDL-предложением, то процедура выполняет это предложение.
Выполняет предложение, разобранное в курсоре, и возвращает число
обработанных в процессе выполнения
строк (для операторов INSERT,
UPDATE и DELETE ).
Извлекает строку из курсора в локальный буфер. Чтобы затем прочитать значения в извлеченной строке,
надо
использовать
процедуру
column value.
Выполняет предложение, разобранное в курсоре, и извлекает первую
строку^ из курсора.
Проверяет, открыт ли курсор.
Если имеет место ошибка во время
выполнения операции, разобранной в
курсоре, то функция возвращает относительную позицию в курсорном
предложении, которая послужила
причиной ошибки.
Возвращает число строк, извлеченных до момента ее вызова из курсора.
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 table_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 ТаЫ
2 At3 BFILE);
Table created.
(Atl NUMBER,At2 BLOB,
SQL> INSERT INTO Tab! VALUES(1,NULL,NULL);
1 row created.
SQL> INSERT INTO Tabl VALUES (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
WRITE
COMPARE
GETLENGTH
INSTR
READ
SUBSTR
FILECLOSE
FILECLOSEALL
FILEEXISTS
FILEGETNAME
FILEISOPEN
FILEOPEN
процедур и функций пакета
Описание
Приписывает к одному LOB-объекту
другой:
Записывает данные в LOB-объект.
Сравнивает два LOB-объекта одного
типа
Возвращает длину LOB-объекта.
Возвращает позицию n-ого вхождения строки в LOB-объект.
Считывает часть LOB-объекта.
Возвращает часть LOB-объекта начиная с заданного смещения.
Закрывает файл по указателю BFILE.
Закрывает все файлы по имеющимся
указателям BFILE.
Проверяет фактическое наличие файла по указателю.
Выдает имя директории и имя файла
для заданного указателя BFILE.
Проверяет, открыт ли файл по BFILEуказателю.
Открывает файл для заданного
255
Раздел 3
COPY
ERASE
TRIM
BFILE-y казателя .
Копирует LOB-объекты.
Удаляет объект полностью или частично.
Обрезает 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
4.
BEGIN
END;
/
-*
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 - Production
(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 - Production
( 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
TABLE
COMMENT
ANY
TABLE
схемы базы данных.
Разрешает пользователю модифицировать
любые строки в любой таблице или представлении любой схемы базы данных.
Разрешает пользователю удалять любые
строки в любой таблице или представлении
любой схемы базы данных.
Разрешает пользователю выполнять произвольную выборку из любой таблицы, представления или снимка любой схемы базы
данных.
Разрешает пользователю выполнять блокировку любой таблицы любой схемы базы
данных.
Разрешает пользователю применять утилиту Export в инкрементальном режиме для
таблиц из любой схемы базы данных.
Разрешает пользователю вносить комментарии в словарь данных для любого столбца любой таблицы в любой схеме базы данных.
Рассмотрим пример. Пусть пользователю 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 privileges
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 privileges
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 declared '
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>
2
3
4
BEGIN
Ul.InsRec(lll);
END;
/ •
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
SESSION
ALTER SYSTEM
ANALYZE ANY
FORCE ANY
TRANSACTION
FORCE
TRANSACTION
Разрешает пользователю создавать каталоги в любой схеме.
Разрешает пользователю создавать связи
с удаленными базами данных.
Разрешает пользователю создавать общедоступные связи с удаленными базами данных.
Разрешает пользователю уничтожать
общедоступные связи с удаленными базами данных.
Разрешает пользователю изменять стоимость использования ресурсов системы.
Разрешает пользователю изменять состояние базы данных с помощью оператора ALTER DATABASE.
Разрешает пользователю изменять состояние сессии с помощью оператора
ALTER SESSION.
Разрешает пользователю изменять состояние системы с помощью оператора
ALTER SYSTEM.
Разрешает пользователю производить
сбор статистики для таблиц, кластеров и
индексов в любой схеме.
Разрешает пользователю производить
принудительную фиксацию или откат
любой сомнительной распределенной
транзакции.
Разрешает пользователю производить
принудительную фиксацию или откат
сомнительной распределенной транзакции.
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
2
Листинг 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 *
ATI
AT2
345
123
FROM U2.Tabl;
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
RESOURCE
DBA
Разрешенные роли
системные привилегии
ALTER SESSION
CREATE CLASTER
CREATE DATABASE LINK
CREATE SEQUENCE
CREATE SESSION
CREATE SYNONYM
CREATE TABLE
CREATE VIEW
CREATE CLASTER
CREATE PROCEDURE
CREATE SEQUENCE
CREATE TABLE
CREATE TRIGGER
Все системные привилегии с
параметром WITH ADMIN
OPTION
EXP_FULL_DATABASE
IMP FULL DATABASE
303
Раздел 4
EXP_FULL_DATABASE
IMP FULL DATABASE
SELECT ANY TABLE
BACKUP ANY TABLE
INSERT,UPDATE,DELETE доя
системных таблиц
sys.lncexp
sys.incvid
sys.incfil.
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, REFERENCES, 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
INSERT
INSERT
INSERT
INSERT
TABLE Tab!(Atl NUMBER, At2 VARCHAR2(3));
INTO TAB1 VALUES(1,'A');
INTO TAB1 VALUES(1,'В');
INTO TAB1 VALUES(2,'A');
INTO TAB1 VALUES(1,'A');
Пользователь Ul создает представление VI, в котором
для таблицы Tab! вычисляется сумма в столбцах Atl, сгруп311
Раздел 4
пированная по значениям столбца At2. Пользователю U2 предоставляется право выборки из представления, но не из базовой таблицы. Протокол иллюстрирующего примера приведен
в листинге 166.
SQL>
2
3
View
CREATE OR REPLACE VIEW VI (VAT1) AS
SELECT SUM(ATI)
FROM Tabl GROUP BY ATI;
created.
SQL> GRANT SELECT ON VI TO U2;
Grant succeeded.
SQL> CONNECT U2/U2PSW;
Connected.
SQL> SELECT * FROM U1.V1;
VAT1
3
2
SQL> 'SELECT * FROM Ul.Tabl;
SELECT '* FROM Ul.Tabl
*
ERROR at line 1:
ORA-00942: table or view does not exist
/
Листинг 166. Протокол создания представления для
доступа к агрегированным данным
Хранимые процедуры как
средство разграничения доступа
Хранимые процедуры и функции Oracle дают еще один
мощный и гибкий способ ограничить множество действий,
которые пользователь может производить с базой данных.
312
Средства разграничения доступа в Oracle
Хранимая процедура или функция — это множество объединенных общим замыслом предложений языка PL/SQL,
которые хранятся на сервере в откомпилированной форме и
исполняются по запросу клиентского предложения. Процедуры или функции создаются для выполнения некоторой конкретной работы пользователем. При этом пользователю достаточно предоставить привилегию на исполнение процедуры,
созданной для поддержки его деятельности. Важным фактом
является то, что пользователю не требуется предоставления
прав доступа к данным, обрабатываемым данной процедурой.
Наличие такого механизма позволяет исключить обработку
данных пользователем, не предусмотренную разработчиком
системы или администратором безопасности.
Рассмотрим конкретный пример. Пользователь U1 создает процедуру выборки данных из таблицы ТаЬ2 и предоставляет право на ее исполнение пользователю Ш. Пользователь
U2, выполняя процедуру, может получить результат выборки
из U1 .ТаЬ2, но попытка явного выполнения выборки отвергается системой. Ясно, что в процедуре при определении курсора могло быть задано любое ограничение, характеризующее данные, необходимые для работы приложения. В листинге 167 приведен протокол исполнения предложенного примера.
SQL> CONNECT U1/U1PSW0EDUC;
Connected.
SQL> CREATE OR REPLACE PROCEDURE getdata AS
2 CURSOR cursel IS
3 SELECT * FROM Tab2;.
4 currec Tab2%ROWTYPE;
5 BEGIN
6 FOR currec IN cursel LOOP
1 DBMS_OUTPUT.PUT_LINE(TO_CHAR(currec.Atl)| Г
'} |TO_CHAR(currec.At2));
8 END LOOP;
9 END getdata;
313
Раздел 4
10 /
Procedure created.
SQL> -GRANT EXECUTE ON getdata TO U2;
Grant succeeded.
SQL> CONNECT . U2/U2PSW@EDUC;
Connected.
SQL> SELECT * FROM Ul.Tab2;
SELECT * FROM Ul.Tab2
*
ERROR at line 1:
ORA-01031: insufficient privileges
SQL> BEGIN
2
Ul.getdata;
3 END;
4 /
1 2
3 4
PL/SQL procedure successfully completed.
Листинг 167. Протокол примера разграничения доступа средствами хранимой процедуры
Использование триггеров
для повышения защиты системы
Триггер — это совокупность предложений языка PL/SQL,
автоматически запускаемая при регистрации сервером определенных событий в системе. Триггеры выполняются системой автоматически до или после возникновения предопределенных событий, таких, как выполнения операций INSERT,
UPDATE, DELETE в некоторой таблице. Способы использование триггеров для повышения защищенности системы подобны использованию хранимых процедур. Особенностью
триггеров является реализуемая возможность выполнить не314
Средства разграничения доступа в Oracle
обходимые проверки полномочий перед выполнением операции над таблицами. Дополнительно отметим, что на одном
множестве таблиц может быть определено несколько триггеров. Комбинации триггеров, выполняемых до и после операций, позволяют создавать изощренные механизмы проверки
допустимости тех или иных действий в базе данных.
Рассмотрим пример применения триггеров для выполнения функций разграничения доступа и фискальных действий.
Пусть пользователь SYSTEM является владельцем таблицы
Tab! с одним столбцом Ail, в который предполагается запись
данных уполномоченными пользователями. Список уполномоченных пользователей размещается в таблице AuthTab.
Процесс ввода данных в таблицу Tab! контролируется триггером TRIG_BFR, который автоматически выполняется до
выполнения операции вставки строк в таблицу Tab! (конструкция BEFORE INSERT). Наличие полномочий у пользователя на выполнение операции вставки проверяется вызовом
функции FuncAuth. Для регистрации действий уполномоченных пользователей создана таблица TabAud. В данном примере в таблице TabAud регистрируется вводимое в таблицу
Tab! значение атрибута и дата вставки записи. Регистрация
действий осуществляется после выполнения вставки строки в
таблицу ТаЫ. В листинге 168 представлены протоколы создания таблиц AuthTab и TabAud, функции FuncAuth, выполняющей проверку полномочий и синонима для таблицы
TabAud:
CONNECT SYSTEM/MANAGER8EDOC
Connected.
SQL> CREATE TABLE AuthTab
Table created.
(Atl V A R C H A R ( 3 0 ) ) ;
SQL> INSERT INTO AuthTab VALUES
1 row created.
('SYSTEM');
315
Раздел 4
SQL> INSERT INTO AuthTab VALUES ('Ul');
1 row created.
SQL> CREATE OR REPLACE FUNCTION FuncAuth
2 RETURN NUMBER
.3 AS
4 varl NUMBER;
.5 BEGIN
6 SELECT COUNT(*) INTO varl FROM AUTHTAB
7 WHERE Atl IN (USER);
8 RETURN varl-;
9 END;
10 /
Function created.
SQL> CREATE PUBLIC SYN.ONYM FUNCAUTH
2 FOR SYSTEM.FuncAuth;
Synonym created.
SQL> GRANT EXECUTE ON'FuncAuth TO PUBLIC;
Grant succeeded.
SQL> CREATE TABLE TabAud (Atl NUMBER, At2 DATE);
Table created.
SQL> CREATE PUBLIC 'SYNONYM TabAud
2 FOR SYSTEM.TabAud;
Synonym created.
SQL> GRANT INSERT ON TabAud TO -PUBLIC;
Grant succeeded.
Листинг 168. Протокол создания таблиц, функции и
синонима примера
Протоколы создания триггеров представлены в листинге
169. Триггер TRIG_BFR автоматически запускается до выполнения операции вставки строк в таблицу ТаЫ, а триггер
TRIG AFT — после.
SQL> CREATE OR REPLACE TRIGGER TRIG_BFR
2 BEFORE INSERT ON Tabl
316
Средства разграничения доступа в Oracle
3 FOR EACH ROW
4 BEGIN
5 IF FuncAuth = 0
6 THEN
7 RAISE_APPLICATION_ERROR(-20011, 'Неавторизованная операция');
8 END IF;
9 END;
10 /
'Trigger created.
SQL> CREATE OR REPLACE TRIGGER TRIG_AFT
2 AFTER INSERT OR UPDATE ON Tabl
3 FOR EACH ROW
4 BEGIN
5 INSERT INTO TabAud VALUES(:new.At1, SYSDATE);
6 END;
7 /
Trigger created.
Листинг1 169. Протокол создания триггеров примера
Протокол создания пользователей U1 и U2 приведен в
листинге 170. Пользователь U1 уполномочен выполнять
вставку строк в таблицу Tabl (см. строки таблицы AuthTab в
листинге 168), а пользователь U2 — нет. С позиций системы
пользователи наделяются одинаковыми привилегиями.
SQL> CREATE USER Ul IDENTIFIED BY U1PSW;
User created.
SQL> GRANT CONNECT TO Ul;
Grant succeeded.
SQL> GRANT INSERT ANY TABLE TO Ul;
Grant succeeded.
SQL> CREATE USER U2 IDENTIFIED BY U2PSW;
User created.
317
Раздел '4
SQL> GRANT CONNECT TO U2;
Grant succeeded.
SQL> GRANT INSERT ANY TABLE TO U2;
Grant succeeded.
Листинг 170. Протокол создания пользователей примера
В листинге 171 приведен протокол демонстрации работы
модельной системы разграничения доступа, построенной е
использованием триггеров. Для пользователя U1 операция
вставки строк выполняется успешно. Для пользователя U2 —
автоматически запускается триггер, который генерирует исключительную ситуацию по нарушению условий авторизации
доступа.
SQL> CONNECT U1/U1PSW0EDUC;
Connected
SQL> INSERT INTO SYSTEM.Tabl VALUES(111);
1 row created.
SQL> CONNECT U2/U2PSW0EDUC;
Connected.
SQL> INSERT INTO SYSTEM.Tabl VALUES(222);
INSERT INTO SYSTEM.TAB1 VALUES(222)
*
ERROR at line 1:
ORA-20011: Неавторизованная операция
'ORA-06512: at "SYSTEM.TRIG_BFR", line 4
ORA-04088: error during execution of trigger
1
SYSTEM.TRIG_BFR'
SQL> CONNECT SYSTEM/MANAGER0EDUC;.
Connected.
318
Средства разграничения доступа в Oracle
SQL> SELECT * FROM Tabl; '
ATI
111
SQL> SELECT * FROM TabAud;
ATI
AT2
111
10-04-2002
Листинг1 171. Пример, демонстрирующий использование триггеров для - разграничения доступа
пользователей к данным системы
Средства аудита
Полноценная система обеспечения безопасности должна
обладать развитыми средствами аудита, то есть автоматического ведения протоколов действий пользователей системы.
Таблицы для записей аудита обычно являются частью словаря данных. В Oracle основной таблицей для записей аудита
является таблица SYS.AUD$. В данной таблице 28 столбцов,
что позволяет вести достаточно детальный аудит событий в
системе.
Для каждой контролируемой операции фиксируется информация о пользователе, выдавшем запрос на операцию, типе операции, об объектах базы данных, на которые воздействовала операция, дате и времени выполнения операции. На
базе таблицы SYS.AUD$ построено несколько представлений, информация из которых обычно и обрабатывается администраторами системы и возможно пользователями. Наиболее
часто используются представления: DBA_AUDIT_TRAIL,
USER_AUDIT_TRAIL, USER_AUDIT_OBJECT, а также
USER_AUDIT_SESSION,USER_AUDIT_STATEMENT.
Для того чтобы началась автоматическая фиксация событий в системе при помощи включения соответствующих за319
Раздел 4
писей в таблицу аудита, необходимо активизировать службу
аудита и определить перечень фиксируемых событий. Для
активизации службы аудита необходимо включить в файл
параметров базы данных параметр audit_trail = true (при использовании стандартного файла инициализации данный параметр присутствует, но закомментирован) и перезапустить
сервер для того, чтобы измененное значение параметра привело к включению службы аудита.
Определение перечня фиксируемых событий может быть
модифицировано в любое время пользователем, имеющим
привилегию AUDIT SYSTEM (для аудита системных событий) или AUDIT ANY (для аудита событий, связанных с доступом к объекту системы). Заметим, что модификация перечня фиксируемых событий может быть выполнена и в период, когда служба аудита не активизирована. Естественно,
что записи о событиях перечня начнут появляться только после активизации службы.
Аудит системных событий
Оператор определения перечня фиксируемых системных
событий Oracle использует следующий синтаксис:
AUDIT {имя_группы_событии \ системная_привилегия}
[ { , имя_группы_событий\системная_привилегия } . . . ]
[BY пользователь { [ , пользователь] . . . } ]
[BY { SESSION I ACCESS }]
[WHENEVER [NOT] SUCCESSFUL]
Список значений, которые может принимать параметр
имя_группы_событш, приведен в представленных ниже таблицах. Системные привилегии сгруппированы по объектам.
Список не является исчерпывающим, полный список может
быть взят из документа Oracle Server SQL Reference. Список
значений, которые может принимать параметр систем-
320
Средства разграничения доступа в Oracle
ноя_привилегия, приведен в разделе, посвященном предоставлению системных привилегий.
Конструкция BY пользователь указывает на то, что фиксируются только определенные данным предложением действия конкретного пользователя или перечисленных в списке
пользователей. Если конструкция BY пользователь не указана, фиксируются действия всех пользователей.
Конструкция BY SESSION указывает на то, что в таблицу
аудита заносится единственная запись о фиксируемом действии для каждого сеанса пользователя. Значение используется
по умолчанию.
Конструкция BY ACCESS указывает на то, что для каждого выполнения действия пользователем в таблицу аудита
заносится запись о фиксируемом действии. Заметим, что в
случае, если в предложении определена фиксация действий с
системными привилегиями, или выполнение предложений
подъязыка определения данных, то независимо от указанного
значения параметра BY { SESSION | ACCESS} принудительно выполняются действия, опеределяемые конструкцией BY
ACCESS.
Конструкция WHENEVER SUCCESSFUL указывает на
то, что в таблицу аудита заносится запись о фиксируемом
действии только в случае успешного выполнения операции.
Конструкция WHENEVER NOT SUCCESSFUL указывает
на то, что в таблицу аудита заносится запись о фиксируемом
действии только в случае неуспешного выполнения операции.
Если конструкция WHENEVER ... не указана, то аудиторская запись вносится независимо от успешности выполнения операции. Значения, которые может принимать параметр
имя_группы_событий, приведены в таблицах 25 и 26.
321
-И. Заказ Мо 1628.
Раздел 4
Таблица 25. Обозначение и сущность основных системных событий Oracle, фиксирование которых
определяется параметром имя_группы_событий
команды AUDIT
Имя группы '
событий
SESSION
Фиксируемые действия
Фиксирует вхождения пользователей
в систему.
CREATE USER
USER
DROP USER
ALTER USER
AUDIT
SYSTEM AUDIT
NOAUDIT
SYSTEM GRANT
GRANT (системные привилегии и
привилегии доступа к объекту)
REVOKE (системные привилегии и
привилегии доступа к объекту)
NOT EXIST
Фиксирует неуспешную попытку выполнить любое SQL-предложение,
если причина невозможности выполнить операцию в том, что объект базы
данных не существует.
CREATE FUNCTION
PROCEDURE
CREATE PACKAGE
CREATE PACKAGE BODY
.
CREATE PROCEDURE
DROP FUNCTION
DROP PACKAGE
DROP PROCEDURE
TABLE
CREATE TABLE
DROP TABLE
TRUNCATE TABLE
VIEW
CREATE VIEW
DROP VIEW
PUBLIC SYNONYM CREATE PUBLIC SYNONYM
DROP PUBLIC SYNONYM
322
Средства разграничения доступа в Oracle
SYNONYM
ROLE
N.
SEQUENCE
TABLESPACE
CREATE SYNONYM
DROP SYNONYM
CREATE ROLE
ALTER ROLE
DROP ROLE
SET ROLE
CREATE SEQUENCE
DROP SEQUENCE
CREATE TABLESPACE
DROP TABLESPACE
ALTER TABLESPACE
Рассмотрим пример использования автоматического аудита процесса регистрации пользователей в системе. Представленный в листинге 172 протокол демонстрирует включение и выключение службы автоматической регистрации соединений пользователей с сервером Oracle.
В данном случае запуск аудита выполняется пользователем SYSTEM, который обладает необходимыми привилегиями.
SQL> AUDIT CONNECT;
Audit succeeded.
SQL> CONNECT U1/U1PSW
Connected.
SQL> CONNECT U2/U2PSW
Connected.
SQL> CONNECT UNKNOWN/ABC
ERROR: ORA-01017: invalid username/password;
logon denied
Warning: You are no longer connected to ORACLE.
SQL> CONNECT SYSTEM/MANAGER
Connected.
323
11*
Раздел 4
SQL> NOAUDIT CONNECT.;
Noaudit succeeded.
Листинг 172. Пример активизации и завершения процесса автоматической регистрации подключения пользователей к серверу Oracle
Результаты автоматической регистрации процессов подключения пользователей к серверу Oracle просматриваются с
использованием представления DBA_AUDIT_TRAIL, созданного на базе системной таблицы SYS.AUD$. В листинге 173
представлена выборка данных с результатами аудита системы, инициированного действиями, описанными в листинге
172.
SQL> SELECT USERNAME, TIMESTAMP,
2 RETURNCODE FROM DBA_AUDIT_TRAIL;
USERNAME
Ul
U2
UNKNOWN
SYSTEM
TIMESTAMP
11-04-2002
11-04-2002
11-04-2002
11-04-2002
RETURNCODE
0
0
1017
0
Листинг 173. Результат выборки данных, собранных
согласно листингу 172
Дополнительные значения, которые может принимать
параметр имя_группы_событий, приведены в таблице 26.
324
Средства разграничения доступа в Oracle
Таблица 26. Обозначение дополнительных системных
событий, фиксирование которых определяет
имя_грулпы_ событий
Имя группы_
событий
GRANT TABLE
INSERT TABLE
DELETE TABLE
UPDATE TABLE
SELECT TABLE
ALTER TABLE
EXECUTE
PROCEDURE
GRANT PROCEDURE
GRANT SEQUENCE
Фиксируемые действия
Передача привилегий с использованием, предложения GRANT на
объекты: таблица, представление,
снимок. Отзыв привилегий с использованием REVOKE на объекты: таблица, представление, снимок.
Операции вставки строк в таблицы
и представления.
Операции удаления строк из таблиц и представлений.
Операции изменения строк в таблицах и представлениях.
Операции выборки из таблиц,
представлений и снимков.
Операции модификации определений таблиц ALTER TABLE.
Выполнение любой процедуры
или функции или доступ к элементу спецификации произвольного
пакета.
Передача привилегий с использованием предложения GRANT на
объекты: процедура, функция или
пакет. Отзыв привилегий с использованием предложения REVOKE
на объекты: процедура, функция
или пакет.
Передача привилегий с использованием предложения GRANT на
325
Раздел 4
SELECT SEQUENCE
последовательность. Отзыв привилегий с использованием предложения REVOKE на последовательность.
Выполнение выборки элементов
произвольной последовательности
использованием CURRVAL или
NEXTVAL
В Oracle предусмотрено использование обобщенных
имен групп событий для фиксации более широких множеств
событий, чем те, что приведены в таблицах 25 и 26. Отметим,
что поддержка обобщенных имен групп событий в будущих
версиях Oracle не гарантируется.
Таблица 27. Таблица обобщенных имен групп событий
Oracle
Имя группы
событий
CONNECT
RESOURCE
DBA
326
Фиксируемые действия
CREATE SESSION
CREATE TABLE
CREATE VIEW
CREATE PROCEDURE
CREATE SEQUENCE
CREATE SYNONYM
ALTER SYSTEM
CREATE DATABASE LINK
CREATE TABLESPACE
Все привилегии, задаваемые
предложением SYSTEM GRANT, a
также CREATE USER
CREATE ROLE
AUDIT SYSTEM
CREATE PUBLIC DATABASE LINK
CREATE PUBLIC SYNONYM
Средства разграничения доступа в Oracle
ALL
ALL PRIVILEGES
Все привилегии, перечисленные в
таблице 25 (но не в таблице 26).
Все системные привилегии.
Аудит событий, связанных
с доступом к объекту
Для регистрации событий, связанных с доступом к конкретному объекту Oracle, пользователь должен иметь привилегию AUDIT ANY. Модификация перечня фиксируемых событий, связанных с доступом к объекту, может быть выполнена и в период, когда служба аудита не активизирована. При
этом, естественно, записи о регистрируемых событиях начнут
появляться только после активизации службы.
Оператор определения перечня регистрируемых событий,
связанных с доступом к объекту Oracle, использует следующий синтаксис:
AUDIT {имя^регистрируемого_действия]
[ {, {имя_регистрируемого_действия } . . . ]
ON { [ с х е м а . ] о б ъ е к т \ DEFAULT}
[BY { SESSION | ACCESS }]
[WHENEVER [NOT] SUCCESSFUL]
Параметр шля регистрируемого Действия может принимать значения, приведенные в таблице 28 и зависящие от типа
объекта.
Конструкция BY SESSION указывает на то, что в таблицу
аудита заносится единственная запись о регистрируемом действии для каждого сеанса пользователя. Значение используется по умолчанию.
Конструкция BY ACCESS указывает на то, что для каждого выполнения действия пользователем в таблицу аудита
заносится запись о фиксируемом действии. Заметим, что в
случае, если в предложении определена фиксация выполнения предложений подъязыка определения данных, то незави327
Раздел 4
симо от указанного значения параметра BY {SESSION |
ACCESS} принудительно выполняются действия, определяемые конструкцией BY ACCESS.
Конструкция WHENEVER SUCCESSFUL указывает на
то,'что в таблицу аудита заносится запись о фиксируемом
действии только в случае успешного выполнения операции.
Конструкция WHENEVER NOT SUCCESSFUL указывает
на то, что в таблицу аудита заносится запись о фиксируемом
действии только в случае неуспешного выполнения операции.
Если конструкция WHENEVER ... не указана, то аудиторская запись вносится независимо от успешности выполнения операции. Действие команды аудита доступа к объекту
начинается немедленно после ее выполнения, то есть в текущей сессии.
Таблица 28. Таблица значений параметра имя_регистрируемого_действия, применимого к объектам
Oracle
Имя действия
SELECT
INSERT
UPDATE
DELETE
EXECUTE
GRANT
AUDIT
ALTER
RENAME
328
Допустимые объекты Oracle
Таблица, представление, снимок, последовательность.
Таблица, представление, снимок.
Таблица, представление, снимок.
Таблица, представление, снимок.
Процедура, функция, пакет.
Таблица, представление, снимок, последовательность, процедура, пакет,
функция.
Таблица, представление, снимок, последовательность, процедура, функция,
пакет.
Таблица, снимок, последовательность.
Таблица, представление, снимок, процедура, функция, пакет.
Средства разграничения доступа в Oracle
Рассмотрим пример аудита неуспешных попыток записи
в таблицу Tabl, владельцем которой является пользователь
SYSTEM. Заметим, что в листингах 168—171 представлен
метод, который не допускает выполнения такой операции. В
листинге 174 представлен метод, в котором запрещение операции обеспечивается системными средствами, а попытка
выполнить запрещенную операцию регистрируется средствами системного аудита.
SQL> CONNECT SYSTEM/MANAGER@EDUC
Connected.
SQL> AUDIT INSERT ON TAB1
2 WHENEVER NOT SUCCESSFUL;
Audit succeeded.
SQL> CONNECT U1/U1PSW@EDUC
Connected.
SQL> INSERT INTO SYSTEM.TAB1 VALUES(111);
INSERT INTO SYSTEM.TAB! VALUES(111)
*
ERROR at line 1:
ORA-00942:. table or view does not exist
SQL> CONNECT SYSTEM/MANAGER@EDUC
Connected.
SQL> NOAUDIT INSERT ON TAB1;
Noaudit succeeded.
SQL> SELECT USERNAME, ACTION,
2 TIMESTAMP FROM USER_AUDIT_TRAIL;
USERNAME-
ACTION
TIMESTAMP
Ul
103
12-04-2002
SQL> SELECT USERNAME, SES_ACTIONS
2 FROM USER_AUDIT_TRAIL;
329
Раздел 4
USERNAME
Ul
SES_ACTIONS
.
F
Листинг1 174. Протокол регистрации неуспешных попыток вставки строк в таблицу ТаЫ
Прекращение регистрации событий
Прекращение регистрации системных событий может
быть выполнено в любое время пользователем, имеющим
привилегию AUDIT SYSTEM.
Оператор прекращения регистрации определенных системных событий Oracle использует следующий синтаксис:
NOAUDIT.
{имя_группы_событий \ системная_привилегия]
[{,имя_группы_событий |системная_привилегия }...]
[BY пользователь {[, пользователь} ...}]
[WHENEVER [NOT] SUCCESSFUL]
Список значений, которые может принимать параметр
имя_группы_событий, приведен в таблицах 25 и 26. Список
не является исчерпывающим, полный дписок можно получить
из документа Oracle Server SQL Reference.
Список значений, которые может принимать параметр
системная_привилегия, приведен в разделе, посвященном
предоставлению системных привилегий.
Конструкция BY пользователь указывает на то, что прекращается регистрация только действий конкретного пользователя, определенных данным предложением. Если она не
указана, прекращается регистрация действий всех пользователей.
Конструкция WHENEVER SUCCESSFUL указывает на
то, что в таблицу аудита заносится запись о фиксируемом
действии только в случае успешного выполнения операции.
330
Средства разграничения доступа в Oracle
Конструкция WHENEVER NOT SUCCESSFUL указывает
на то, что в таблицу аудита заносится запись о фиксируемом
действии только в случае неуспешного выполнения операции.
Если конструкция WHENEVER ... не указана, то аудиторская запись вносится независимо от успешное.™ выполнения операции.
Отметим, что команда отмены системного аудита избирательна, то есть отменяет соответствующую команду начала
регистрации событий. Поясним замечание примером. Пусть
сначала выполнено предложение начала аудита по выборке
пользователем U1, а потом выполнено предложение по тотальному аудиту по выборке. Если администратор отменяет
тотальный аудит по выборке, то действия пользователя U2
перестают фиксироваться, а регистрация действий пользователя U1 продолжается.
Прекращение регистрации событий, связанных с доступом к объекту Oracle, может быть выполнено пользователем,
имеющим привилегию AUDIT ANY.
Оператор прекращения регистрации определенных событий, связанных с доступом к объекту Oracle, использует следующий синтаксис:
NOAUDIT
имя_регистрируемого_действия
[, имя_регистрируемого_действия ...]
ON [схема].объект
[WHENEVER [NOT] SUCCESSFUL]
Параметр имя регистрируемого Действия может принимать значения, приведенные в таблице 28 и зависящие от типа
объекта.
Конструкция WHENEVER SUCCESSFUL указывает на
то, что в таблице аудита прекращается регистрация только
успешно завершенных действий с объектами.
Конструкция WHENEVER NOT SUCCESSFUL указывает
на то, что прекращается фиксация действий, приведших к
возникновению ошибки.
331
Раздел 4
Если конструкция WHENEVER ... не указана, то прекращается запись обо всех определенных в команде операциях, независимо от успешности выполнения операции.
Действие команды аудита доступа к объекту начинается
немедленно после ее выполнения.
Обработка данных аудита
Для обработки данных, накопленных в ходе аудита,
обычно используются представления USER_AUDIT_TRAIL,
USER_AUDIT_OBJECT, USER_AUDIT_SESSION, а также
USER_AUDIT_STATEMENT.
Наиболее полную информацию об аудите содержит представление USER_AUDIT_TRAIL. В таблице 29 перечислены
имена атрибутов и их содержательные описания.
Таблица 29. Имена атрибутов и их содержательное
описание для представления USER_AUDIT_TRAIL
Имя атрибута
Тип данных
OSJJSERNAME
VARCHAR2(255)
USERNAME
VARCHAR2(30)
USERHOST
V ARCH AR2( 128)
332
Описание
атрибута
Имя пользователя, под которым он зарегистрировался в
операционной
системе.
Имя пользователя, под тсоторым он зарегистрировался в
СУБД.
Идентификатор
экземпляра базы данных, с
Средства разграничения доступа в Oracle
TERMINAL
VARCHAR2(255)
.
-
TIMESTAMP
DATE
OWNER
VARCHAR2(30)
>-'..'""*
OBJ_NAME
VARCHAR2(128)
-,
ACTION
NUMBER
ACTION_NAME
VARCHAR2(27)
NEW OWNER
VARCHAR2(30)
которым работает
пользователь.
Идентификатор
клиентского
терминала
пользователя.
Дата и время
создания регистрационной
записи.
Владелец объекта,
с
которым взаимодействует
пользователь
(для
аудита
объектов
Oracle).
Имя объекта, с
которым взаимодействует
пользователь
(для
аудита
объектов
Oracle).
Числовой код
регистрируемого
действия
пользователя.
Название регистрируемого
действия пользователя.
Владелец пере-
333
Раздел 4
NEW_NAME
VARCHAR2(128)
OBJ_PRIVILEGE
VARCHAR2(16)
SYS_PRIVILEGE
VARCHAR2(40)
ADMINJDPTION
VARCHAR2(1)
s
.
e
GRANTEE
VARCHAR2(30)
AUDIT_OPTION
VARCHAR2(40)
334
именованного
объекта.
Новое имя переименованного объекта.
Привилегии
доступа к объекту, которые
были
предоставлены или
отозваны.
Системные
привилегии,
которые были
предоставлены
или отозваны.
Индикатор
предоставления привилегий с параметром
WITH
ADMIN
OPTION (принимает значения Y и N)
Имя пользователя, у которого
изменены
привилегии командами
GRANT
или
REVOKE.
Параметры команды AUDIT.
Средства разграничения доступа в Oracle
SES_ACTIONS
VARCHAR2(19)
LOGOFF_TIME
DATE
LOGOFF_LREAD
NUMBER
LOGOFF_PREAD
NUMBER
LOGOFF LWRITE
NUMBER
LOGOFF DLOCK
VARCHAR2(40)
SESSIONJD
NUMBER
Строка символов,
описывающая
успешное
или
неуспешное
выполнение
команды.
Дата и время
завершения
сессии пользователем.
Число операций логического чтения, выполненных за
сессию.
Число операций
физического чтения,
выполненных
за сессию.
Число операций логической
записи, выполненных за сессию.
Число тупиковых ситуаций,
зафиксированных в течение
сессии.
Числовой
идентификатор
сессий.
335
Раздел 4
ENTRYJD
NUMBER
STATEMENTID
NUMBER
RETURNCODE
NUMBER
PRIVJJSED
VARCHAR2(40)
OBJECT_LABEL
RAW MLSLABEL
SESSION_LABEL
RAW MLSLABEL
Числовой
идентификатор
регистрационной записи.
Числовой
идентификатор
каждой
выполняемой команды.
Код
возврата
для
каждой
выполняемой
команды.
Системные
привилегии,
используемые
для исполнения
регистрируемой команды.
Метка объекта
(только
для
Trusted Oracle
Server).
Метка сессии
(только
для
Trusted Oracle
Server.)
Представление USER_AUDIT_OBJECT предназначено
для доступа к информации о регистрируемых событиях, связанных с конкретными объектами.
Представление USER_AUDIT_SESSION предназначено
для доступа к информации о регистрируемых сессиях.
336
Средства разграничения доступа в Oracle
Представление USER_AUDIT_STATEMENT предназначено для доступа к информации о предоставлении и отзыве
привилегий, выполнении команд AUDIT, NOAUDJT и ALTER
SYSTEM пользователем.
Для всех перечисленных выше представлений в словаре
данных присутствуют также соответствующие представления
с префиксом DBA_. В этих представлениях аккумулируется
соответствующая сущности представления информация по
всем пользователям системы.
Профили пользователя как
средство повышения
защищенности системы
В качестве дополнительного средства повышения защищенности системы можно рассматривать поддержку в системе Oracle профилей пользователя.
Профиль пользователя — это поименованный набор ограничений на ресурсы системы. Ограничивая такие критические ресурсы как процессорное время, число операций вводавывода за сеанс и т. п., администратор может лишить потенциального злоумышленника возможности ухудшать характеристики системы путем ее загрузки бессмысленной работой.
Ограничивая время пребывания клиента в неактивном состоянии, администратор может защитить систему от нарушителя, получившего доступ к терминалу, оставленному законным пользователем на долгое время.
Для создания профиля, который позднее может быть назначен тому или иному пользователю, необходимо обладать
системной привилегией CREATE PROFILE. Профиль не является объектом какой-либо схемы.
Оператор создания профиля Oracle использует следующий синтаксис:
337
Раздел 4
CREATE PROFILE {имя_профиля_пользователя} LIMIT{имя_параметра_рграничения}
{значение_параметра_ограничения} [.., .]
Параметр имя_парометра_ограничения может принимать
значения, приведенные в таблице 30. Список не является исчерпывающим, полный список может быть взят из документа
Oracle Server SQL Reference.
Таблица 30.
Значения
параметра
имя_параметра_ограничения для команды создания профиля
пользователя
Имя параметра
SESSION PER USER
CPU PER SESSION
CPU PER CALL
CONNECT TIME
IDLE TIME
338
Описание
Максимальное число одновременных сессий для данного
пользователя.
Максимальное
суммарное
время процессора (в сотых долях секунды), выделяемое для
одной сессии данному пользователю.
Максимальное время процессора на операцию (в сотых долях секунды),
выделяемое
данному пользователю.
Максимальное
суммарное
время на период сессии (в минутах), выделяемое данному
пользователю.
Максимальное время непрерывного неактивного состояния пользователя в минутах
(время исполнения длительных операторов не считается
неактивным).
Средства разграничения доступа в Oracle
LOGICAL_READS_PER_SE
SSION
LOGICAL_READS_PER
CALL
Максимальное
суммарное
число блоков данных, считанных за период сессии, выделяемое данному пользователю.
Максимальное
суммарное
число
блоков
данных,
считанных за время выполнения одного предложения
SQL, выделяемое данному
пользователю.
Параметр значение_параметра_ограниченш может принимать одно из трех значений:
— целое_число
— UNLIMITED
— DEFAULT.
Как правило, изначально в системе существует один профиль DEFAULT, у которого отсутствуют ограничения на используемые ресурсы. Обычно этот профиль назначается всем
пользователям по умолчанию. Для введения ограничений на
ресурсы его требуется изменить или создать новые профили и
назначить их пользователям. Для включения системы ограничения использования ресурсов необходимо выполнить команду ALTER SYSTEM SET RESOURCEJJMIT = TRUE или
изменить значение соответствующего параметра в файле параметров базы данных.
В примере, представленном в листинге 175, создается
профиль с ограничением на время соединения.
SQL> CONNECT SYSTEM/MANAGER0EDUC
Connected.
339
Раздел 4
SQL> ALTER SYSTEM SET RESOURCE_LIMIT = TRUE;
System altered.
SQL> CREATE PROFILE pfl LIMIT
2 CONNECTJTIME 1;
Profile created.
SQL> ALTER USER ul PROFILE pfl;
User altered.
SQL> CONNECT ul/ulpsw@EDUC
Connected.
-- ожидаем
SQL> SELECT . * FROM dual;
SELECT * FROM dual
*
ERROR at line 1:
ORA-02399: exceeded maximum connect time, you are
being logged off
Листинг 175, Пример создания и назначения пользователю ограничения на используемые ресурсы
Дополнительные сведения
Для большой корпоративной системы ведение разграничения доступа может оказаться затрудненным. Причиной может оказаться большое число объектов, пользователей, ролей,
привилегий (системных и доступа к объектам). В этом случае
проблема состоит не в том, что невозможно предоставить все
необходимые привилегии, а в том, что в результате операций
взаимно назначаемых привилегий, ролей и т. д. пользователь
может получить несанкционированный доступ к данным. Для
преодоления проблемы рекомендуется использовать специальные программные продукты третьих фирм, которые позволяют по словарю данных сформировать подробные отчеты
по актуальным привилегиям. Также существуют специальные
утилиты анализа таблиц аудита.
340
Средства разграничения доступа в Oracle
Дополнительно отметим, что, наряду со стандартными
мерами по недопущению компрометации паролей для компьютерных систем, в Oracle рекомендуется избегать сохранения паролей в открытом виде, например, в командных и
управляющих файлах экспорта/импорта и загрузки данных
(параметры USERID, USER и т. п.).
Кроме того, в базе данных Oracle существует объект
DATABASE LINK, при создании которого указываются все
необходимые сведения для подключения к удаленной базе
данных, Эти сведения сохраняются в словаре данных и пользователь, обладающий необходимыми привилегиями, может
их узнать.
Также необходимо отметить, что при установке различных дополнительных картриджей, программ и утилит создается большое число пользователей с известными паролями
(например, картридж WebDB при установке создает пользователя WEBDB с паролем WEBDB и т. д.). Если администратор по какой-то причине не изменил назначаемые по умолчанию пароли этих пользователей, то возникает серьезная угроза безопасности системы, так как обычно эти пользователи
обладают многими системными привилегиями.
341
Раздел 5
Создание приложений на
языке Java
Стандартным интерфейсом для взаимодействия приложений, написанных на языке Java, с OracIeS, является JDBC
(Java DataBase Connectivity). Спецификации интерфейса
JDBC определяются организацией JavaSoft и поддерживаются
всеми основными производителями СУБД.
JDBC построен на идеологии объектно-ориентированного
подхода и естественно интегрируется в язык Java. Возможна
интеграция вызовов JDBC как в программы, написанные на
Java, так и в апплеты, интерпретируемые Java-машинами
браузеров. Наличие апплетов, поддерживающих обращение к
базе данных через интерфейс JDBC, позволяет создавать универсальные приложения, не требующие никакого специализированного программного обеспечения на клиентских рабочих станциях.
Средства построения
приложений и организации
доступа к базам данных
Широкое распространение Всемирной паутины (WWW)
и систем обработки данных, построенных на Webтехнологиях, привело к тому, что все производители СУБД
342
Создание приложений на языке Java
промышленного уровня одновременно являются производителями "сопутствующих" средств разработки приложений и
их интеграции с серверами баз данных. Современная модель
информационных технологий обычно включает тонкого клиента на основе браузера, сервер баз данных и набор компонент промежуточного уровня, использующие технологии
распределенной обработке данных.
Клиентские приложения обычно проектируются так, чтобы обеспечить доступ тс данным независимо от их расположения и формата и обеспечить анализ и преобразования данных
в осмысленную информацию, которая может быть доставлена
потребителю в форме, определяемой его интерфейсом.
Традиционный подход к построению систем обработки
данных состоит в том, что клиент присоединяется к некоторому серверу. При этом программное обеспечение клиента
или коммуникационного интерфейса обычно поставляет фирма-производитель программного обеспечения сервера баз
данных. Web-технология опирается на новую модель, когда
клиент менее функционален и более широко использует
службы (сервисы) сервера баз данных или сервера приложений.
Тонкий клиент, характерный для Web-технологий, является только средством просмотра информации, подготовленной и отправленной в среду доставки соответствующими серверами.
Задачей, характерной для Web-технологий, является разделение процессов, выполняемых на клиенте и сервере. Разделение процессов является способом эффективной организации распределенной обработки данных. Оптимальный уровень производительности достигается на любой конфигурации аппаратных средств за счет адекватного разделения ресурсов.
Каким же образом это обеспечивается? По определению
тонкий клиент обладает минимальным набором программных
и аппаратных ресурсов, обеспечивающих только поддержку
сетевого транспорта и интерпретацию данных, получаемых от
343
Раздел 5
Web-приложений. По сути, тонкий клиент должен поддерживать HTTP протокол, интерпретатор языка HTML и виртуальную Java-машину. Клиент может быть реализован не только на традиционном персональном компьютере, но и на карманном компьютере или даже на сотовом телефоне.
. Расширение функциональности тонкого клиента возможно с помощью использования апплетов на языке Java. Апплет
— это прикладная программа, хранимая в универсальном коде и загружаемая тонким клиентом для последующей интерпретации. Интерпретация кода осуществляется виртуальной
Java-машиной, встроенной в программное обеспечение тонкого клиента.
Одной из наиболее простых и распространенных Webтехнологий является CGI (Common Gateway Interface). Эта
технология обеспечивает тонкому клиенту возможность формировать запросы на доступ к требуемой информации через
Web-сервер. После получения запроса посредством CGI, исполняемый модуль возвращает ответ в форме HTML-текста.
Создание приложений
на языке Java
Объектно-ориентированным интерфейсом прикладного
программирования (API), обеспечивающим взаимодействие с
Oracle приложений, написанных на языке Java, является
JDBC. Интерфейс JDBC определяет классы объектов Java,
характерных для выполнения операций с базами данных: соединение, подготовка и выполнение SQL-операций, доступ к
результатам, доступ к метаданным и т. п.
Набор классов, реализующий интерфейс JDBC для
Oracle, стандартно размещается в файле classeslll.zip или
classesl 12.zip (в зависимости от версии JDK), который обычно располагается в каталоге ORACLE_HOME\JDBC\LIB. Для
разрешения соответствующей ссылки нужно указать место
344
Создание приложений на языке Java
размещения библиотеки, задав соответствующим образом
переменную CLASSPATH.
Для операционных систем Windows значение переменной
CLASSPATH может быть определено явно в файле
autoexec.bat.. Для UNIX-систем дополнительно должны быть
определены пути доступа к необходимым библиотекам.
Для создания приложений, использующих интерфейс
JDBC, важно уяснить назначение и методы классов Connect,
Statement и ResultSet. Прежде чем обращаться к соответствующим методам, необходимо загрузить драйвер JDBC.
Простейшее приложение
на Java
Класс Connect обеспечивает инициализацию сессии
взаимодействия пользователя с сервером Oracle, включая аутентификацию и авторизацию, установку параметров сессии
(режим выполнения транзакций и т. п.).
Сессия открывается вызовом метода getConnection, параметрами которого являются универсальный локатор ресурса
сервера баз данных, имя пользователя и пароль.
Метод getMetaDataQ обеспечивает получение метаданных из словаря базы данных. Метаданные возвращаются в
форме специального объекта типа DatabaseMetaData.
Рассмотрим пример приложения на языке Java, которое
инициализирует сессию взаимодействия с сервером Oracle.
Считаем, что информация, необходимая для установления
связи с сервером, каталогизирована, а имя пользователя (ul) и
пароль (ulpsw) определены соответствующими переменными.
// Пример программы установления соединения с
/ / Oracle
345
Раздел 5
//
import Java . sql . *;.
public class TestCon
// Шаг 1: Зарегистрировать JDBC драйвер Oracle
//
Класс драйвера должен быть загружен до
//
выполнения операций с объектами
//
static
{
try
{
DriverManager . registerDriver (new oracle . j dbc . driver . OracleDriver ( ) ) ;
}
catch (Exceptipn e)
{
System. out .println ( "Ошибка регистрации
драйвера JDBC");
e .printStackTrace ( ) ;
public static void main(String args,[] )
{
try
"
// Шаг 2: Создание объекта соединения
ft
String Connectstring =
" j dbc: oracle: thin: @ora_server: 1521 :ORCL";
String UserlD = "Ul";
String Psw = "U1PSW";
Connection con = DriverManager .getConnection (Connectstring, UserlD, Psw);
//
// Шаг З: Показать информацию о соединении,
//
используя метод DatabaseMetaData
//
346
Создание приложений на языке Java
DatabaseMetaData dma =' con.getMetaData ( ) ;
System. out .println ("ConnectString : " +
dma.getURLO ) ;
System. out .println ("UserlD : " +
dma . getUserName ( ) ) ;
System. out .println ( "Oracle Version : " +
dma. getDatabaseProductVersion ( ) ) ;
//
// Шаг 4: Закрыть соединение
//
con. close { ) ;
catch (SQLException e)
{
// Шаг Х: Универсальный обработчик
// исключительных ситуаций
//
System/out .println ("Хотели как лучше.
System. out. println ("SQLState: " +
e.getSQLState() ) ;
System. out. println ("SQLCODE: " +
e . getMessage ( ) ) ;
Листинг 176. Текст приложения, инициализирующего
сессию и выводящего информацию о параметрах
сервера баз данных
Предположим, что компиляция приложения осуществляется в каталоге C:\WORK, а текст приложения, представленного в листинге 176, сохранен в файле TestCon.java. Компиляция приложения выполняется командой:
C:\WORK> Javac TestCon.java
347
Раздел 5
После успешной компиляции в текущем каталоге должен
появиться файл с именем TestCon.class. Выполнение осуществляется командой:
C:\WORK> Java TestCon
При отсутствии сбоев в работе приложения на терминал
выводятся сообщения, представленные в листинге 177.
C:\WORK> Java TestCon
ConnectString : jdbc:oracle:thin:@
ora server:1521:ORCL
UserID : Ul
Oracle Version : OracleS Enterprise Edition Release 8 . 0 . 5 . 0 . 0 - Production With the Objects option
PL/SQL Release 8 . 0 . 5 . 1 . 0 - Production
Листинг 177. Протокол штатного режима'работы приложения
Когда установить соединение с сервером невозможно,
выводятся сообщения об ошибках. Если, например, экземпляр
сервера не запущен, то на терминал выводятся сообщения,
представленные в листинге 178.
C:\WORK> Java TestCon
Хотели как лучше...
SQLState: null
SQLCODE:
Connection refused(DESCRIPTION(TMP=)(VSNNUM=
134238208)(ERR=12500)(ERROR_STACK=(ERROR=
(CODE=12500)(EMFI=4))(ERROR=(CODE=12560)(EMFI=4))
(ERROR=(CODE=530)(EMFI=4))(ERROR=(BDF=T'))))
Листинг 178. Протокол регистрации ошибки при ус
тановлении соединения
348
Создание приложений на языке Java
Если, в приложении указано неправильные имя пользователя или пароль, то на терминал выводятся сообщения, представленные в листинге 179:
C:\WORK>java TestCon
Хотели как лучше...
SQLState: 72000
SQLCODE: ORA-01017: invalid username/password;
logon denied
Листинг 179. Протокол регистрации ошибки при установлении соединения
Простейший апплет
Отличие апплета от представленных программ состоит в
том, что апплет всегда является расширением специального
класса, описание которого хранится в библиотеке java.applet,
и апплет запускается из некоторой HTML-страницы. Рассмотрим пример апплета, который обеспечивает инициализацию сессии взаимодействия пользователя с сервером Oracle,
включая аутентификацию пользователя и вывод информации
о параметрах сессии, то есть полный аналог функций приложения, представленного в листинге 176. Текст примера апплета приведен в листинге 180.
Отличие состоит в описании основного класса (являющегося расширением класса Applet) и использовании класса
paint для вывода данных.
// Апплет TestACon. Java: Апплет выполняет
// соединение с Oracle
import j ava . sql . * ;
, 349
Раздел 5
import java.awt.*;
import Java. applet .*;
public class TestACon extends Applet
// Шаг 1: Зарегистрировать JDBC драйвер Oracle
//
Класс драйвера должен быть загружен до
//
выполнения операций с объектами
//
public void init ( )
{•
try
{
DriverManager . registerDriver (new oracle. jdbc. driver .OracleDriver ( ) ) ;
}
catch (Exception' e)
- . {
System . out . println ( "Ошибка регистрации
драйвера JDBC");
e.printStackTrace ( ) ;
// Метод paint ( ) обеспечивает вывод
//
public void paint (Graphics g)
{
try
// Шаг 2: Создание объекта соединения
(Connection)
g. drawString ("Готовим доступ", 10, 10) ;
String ConnectString =
"jdbc : oracle : thin : @ora_server : 1 521 : ORCL" ;
String UserlD = "Ul";
String Psw = "U1PSW";
350
Создание приложений на языке Java
Т
Connection con = DriverManager.getConnection(ConnectString,UserlD,Psw);
// Шаг З: Показать информацию о соединении,
//
используя метод DatabaseMetaData
DatabaseMetaData dma = con.getMetaData ( ) ;
30);
g. drawstring ("URL : " + dma. getURL { } , 10,
g. drawstring {"Пользователь : " +
dma.getUserName () , 10, 50);
g. drawstring ( "Database Version : " +
dma. get Database Product Version ( ) , 10, 70) ;
//
// Шаг 4: Закрыть соединение
//
con. close ( ) ;
}
catch (SQLException e)
{
// Шаг Х: Универсальный обработчик
// исключительных ситуаций
//
g. drawString ("Хотели как лучше.,.", 10,30);
g. drawstring ("SQLState: " +
e.getSQLStateO ,10, 50);
д. drawString {"SQLCQDE: " +
e.getMessage ( ) , 10, 70);
Листинг 180. Текст апплета, выполняющего соедине_
ние
с
сервером
баз
данных
_
Пусть, как и ранее, компиляция апплета осуществляется в
каталоге C:\WORK. Текст апплета, представленного в листинге 180, должен быть записан в файле TestACon.java, то
351
Раздел 5
есть совпадать с именем класса. Компиляция приложения выполняется командой:
C:\WORK> Javac TestACon.Java
Для запуска апплета, обеспечивающего инициализацию
сессии взаимодействия пользователя с сервером Oracle, необходимо подготовить соответствующую HTML-страницу. Вариант текста страницы, из которой выполняется запуск апплета, приведен в листинге 181. Предполагается, что байт-код
апплета получен в результате, приведенной выше команды и
располагается в том же каталоге, что и текст
HTMLстраницы (параметр code тэга applet). Размер окна для вывода данных в примере определен 400 на 200 пикселов.
<html>
<title>3arc^oBOK апплета
<body>
<Ы>Тест соединения с Oracle </hl>
<applet code="TestACon. class" width=400
height=200>
</applet>
</body>
</html>
Листинг 181. Текст простейшей HTML-страницы,
которой, запускается апплет .соединения
сервером Oracle
в
с
Сохраним представленный в листинге 181 текст HTMLстраницы, например, в файле TestACon.html. После этого
можно открывать этот файл в окне браузера и получать при
различных условиях результаты, аналогичные результатам,
представленным в листингах 177,178 и 179.
Перейдем к обсуждению программ, осуществляющих обработку данных.
352
' '
Создание приложений на языке Java
Выполнение SQL-операторов
создания таблиц,
ввода и модификации данных
Выполнение предложений на языке SQL, не содержащих
подставляемых параметров, осуществляется в два этапа: сначала с помощью метода createStatementQ класса Connect создается объект — предложение SQL, а потом оно выполняется
вызовом соответствующего метода класса Statement.
Основным методом, предназначенным для выполнения
SQL-предложений, осуществляющих создание и уничтожение
объектов, является метод executeUpdate (String).
Рассмотрим пример приложения на языке Java, которое
создает таблицу с заранее определенным именем и атрибутами. Инициализация сессии взаимодействия с сервером Oracle
осуществляется по технологии, представленной выше и проиллюстрированной в листинге 176.
Пусть создается таблица с именем ТаЫ, включающая два
столбца: Atl, содержащий строки переменной длины не более
5 символов и At2, содержащий числа.
// Пример приложения, создающего таблицу
/1
import j a v a . s q l . * ;
'public class TestCre
// Шаг 1: Зарегистрировать JDBC драйвер Oracle
//
static
try
,353
12. Заказ № 1628.
Раздел 5
DriverManager . registerDriver (new oracle. jdbc .driver .OracleDriver ( ) ) ;
}
catch (Exception' e)
{
System. out .println ( "Ошибка регистрации
драйвера JDBC" ) ;
e.printStackTrace ( ) ;
}
},
•
public static void main (String args [ ] )
{
try
{
//
// Шаг 2: Создание объекта соединения
//
String ConnectString =
" j dbc : oracle : thin : @ora_server : 1521 : ORCL" ;
String UserlD = "Ul";
String Psw = "U1PSW";
Connection con = DriverMan- . *
ager . getConnection (ConnectString, UserlD, Psw) ;
// Шаг З: Подготовить предложение создания
//
таблицы, используя метод
//
createStatement
//
String CreTab = "CREATE TABLE Tabl (Atl
varchar(S), At 2 Integer)";
Statement cS = con. createStatement ();
// Шаг 4: Выполнить операцию, •
//
используя метод executeUpdate
//
cS. executeUpdate (CreTab) ;
System. out .println ( "Таблица создана . " ) ;
//
// Шаг 5: Освободить ресурсы
//
354
Создание приложений на языке Java
cS. close ( ) ;
con. close ( )';
}
catch (SQLException e)
// Шаг Х: Универсальный обработчик исключительных ситуаций
//
System. out .println ( "Хотели как лучше...");
System. out. println ("SQLState: " +
e.getSQLStateO ) ;
System. out .println ( "SQLCODE: " +
e . getMessage ( ) ) ;
Листинг 182. Текст 'приложения, создающего таблицу
в базе данных
Текст приложения, представленного в листинге 1 82, должен быть сохранен в файле TestCre.java. После успешной
компиляции в текущем каталоге должен появиться файл с
именем TestCre.class.
В нормальном варианте работы приложения на терминал
выводятся сообщения, представленные в листинге 183.
C:\WORK> Java TestCre
Таблица создана.
Листинг 183. Протокол штатного режима работы приложения, создающего таблицу
В том случае, когда таблица с именем Tab! уже существует в базе данных (например, при втором запуске приложения), выводится сообщение об ошибке.
355
12*
Раздел 5
C:\WORK> Java TestCon
Хотели, как лучше...
SQLState: 4 2 0 0 0
SQLCODE: ORA-00955: name is already used by an
existing object
Листинг 184. Протокол регистрации ошибки при попытке создания таблицы с именем, совпадающим 'с уже существующим
Для выполнения вставки, удаления и модификации строк
таблиц используется метод executeUpdate (String).
Например, для вставки строки в таблицу, созданную приложением, представленном в листинге 182, выполним следующие изменения. Строку
String CreTab =
"CREATE TABLE Tabl (Atl varchar(S), At2 Integer)";
необходимо заменить на строку
String InsTab = "INSERT INTO TABLE Tabl VALUES
ГаЬс' ,10)";
строки
cS.executeUpdate(CreTab);
System.out.println("Таблица создана.");
заменить на строки
-rf
V_ . . . " . : • - - . : •
cS.executeUpdate(Crelns);
System.out.println("Строка вставлена.");
356
Создание приложений на языке Java
После выполнения этих действий можно откомпилировать и выполнить новое приложение, осуществляющее вставку данных.
Простая выборка данных
Основным методом, предназначенным для выполнения
запросов, является метод executeQuery(String). Этот метод
возвращает экземпляр объекта ResultSet, представляющий
собой результат выполнения запроса.
Класс ResultSet используется для отображения результатов выполнения запроса. С каждым экземпляром класса ассоциируется положение курсора.
Для перемещения курсора по экземпляру класса используется метод nextQ класса ResultSet. Применение этого метода приводит к перемещению курсора к следующей строке.
После выполнения запроса курсор находится перед первой
строкой результата.
Извлечение данных, полученных в результате выполнения запроса, обеспечивается специальным методом. Для каждого типа данных языка Java используется ассоциированный
метод get. To есть для типа данных STRING используется метод getString, для типа данных INTEGER используется метод
getlnteger и т.п.
Рассмотрим пример приложения на языке Java, которое
осуществляет выборку данных из таблицы, созданной приложением, представленным в листинге 182. Предполагается, что
предварительно выполнена вставка строки ('abc', 10) как указано выше.
//
•
// Пример приложения, осуществляющего выборку
//
import java.sql.*;
public class TestSel
357
Раздел 5
{
//
// Шаг 1: Зарегистрировать JDBC драйвер Oracle
//
static
{
try
{
DriverManager.registerDriver(new oracle, j dbc. driver. OracleDriver () ) ;
}
catch (Exception e)
{
System.out.println("Ошибка регистрации
драйвера JDBC");
e.printStackTrace{) ;
•}
}
public static void main(String args[])
{
try
{
//
// Шаг 2: Создание объекта соединения
//
String ConnectString =
"j dbc:oracle:thin:@ora_server:1521:ORCL";
String UserlD = "Ul";."
String Psw = "U1PSW";
Connection con = DriverManager.getConnection(ConnectString,UserlD,Psw);
//
// Шаг З: Подготовить предложение
//
выборки из таблицы, используя
//
метод createStatement
//
String SelTab = "SELECT * FROM Tabl";
Statement cS = con. createStatement ();
//
// Шаг 4: Выполнить операцию,
//
используя метод executeQuery
358
Создание приложений на языке Java
//
ResultSet RS = cS . executeQuery (SelTab) ;
' System, out. printing Atl " + " At2 ") ;
System. out. println (" ----------- ---- ") ;
while (RS.nextO)
{
System. out .print In (RS. get String (1) +
RS.getString(2) } ;
// Шаг 5: Освободить ресурсы
//
cS. close ( ) ;
con. close ( ) ;
}
catch ( SQLException e )
{
// Шаг Х: Универсальный обработчик исключительных ситуаций
//
System. out. println( "Хотели как лучше. . . "') ;
System. out. println ("SQLState: " +
e.getSQLStateO ) ;
System. out. println ("SQLCODE: " +
e . getMessage ( ) ) ;
Листинг 185. Текст приложения,
выборку из таблицы Tab!
осуществляющего
В нормальном варианте работы приложения, когда база
данных ORCL доступна и в ней существует таблица с именем
ТаЫ, на терминал выводятся сообщения, представленные в
листинге 186.
C:\WORK\> Java TestSel
359
Раздел 5
Atl
At2
abc
10
Листинг 186. Протокол штатного режима работы
приложения, осуществляющего простую выборку
Приложение, представленное в листинге 185, имеет существенное функциональное ограничение в том смысле, что
информация о структуре таблицы Tab! жестко встроена в
приложение. Если структура таблицы Tab! изменится, то
текст приложения нужно будет изменить, а приложение перекомпилировать.
•Более гибким будет решение, основанное на извлечении
метаданных о структуре таблицы и именах столбцов из словаря данных. Изменим фрагмент текста шага 4 приложения,
представленного в листинге 185, на фрагмент, представленный в листинге 187, и назовем новое приложение TestSell
(сохранив его в файле TestSell.Java).
// Шаг 4: Выполнить операцию,
//
используя метод executeQuery
//
ResultSet RS = cS.executeQuery(SelTab);
int i;
//
// Получить доступ к метаданным
//
ResultSetMetaData RSMD = RS.getMetaData();
//
/У Определить число столбцов таблицы
//
int numCols = RSMD.getColumnCount();
//
// Вывести имена столбцов
//
for (i = 1; i <= numCols;
{
360
Создание приложений на языке Java
if (i > 1) System. out. print (" ");
System. out .print (RSMD. getColumnLabel (i) ) ;
}
System, out .print In ( "\n ------ - ------- -- — ") ;
//
// Вывести содержимое таблицы
//
while (RS.next.O)
{
for (i = 1; i <= numCols;
if i > 1) System. out. print (" ");
System. out .print (RS. get String (i) ) ;
}
System. out .print In ( "\n") ;
Листинг 187. Изменения, связанные с получением
метаданных о структуре таблицы и именах
столбцов при осуществлении простой выборки
(
Запуск модифицированного приложения приводит к тем
же результатам (представленным в листинге 1 86).
Пусть таблица с именем Tab! модифицирована так, что
она теперь включает три столбца: Atl — содержащий строки
переменной длины не более 5 символов, At2 — содержащий
числа и At3 — содержащий даты. Предположим, что дополнительно введена строка ('bed', 20, SYSDATE).
Несмотря на достаточно радикальное изменение таблицы,
модифицированное приложение осталось работоспособным!
При этом в нормальном режиме работы приложения, модифицированного в соответствии с листингом 1 87, будут выведены сообщения, представленные в листинге 188.
C:\WORK> Java TestSell
ATI
AT2
abc
10
'АТЗ
null
361
Раздел 5
bed
20
2002-03-21
Листинг 188. Протокол штатного режима работы модифицированного приложения, выполняющего
выборку с использованием метаданных
Параметрические запросы
SQL-предложение может содержать подставляемые параметры. Такое предложение готовится вызовом метода
prepareStatement().
Для подстановки параметров в предложение, подготовленное методом prepareStatement, используются специальные
связывающие методы. Каждому типу данных Java соответствует некоторый связующий метод.
Например, для осуществления подстановки символьного
параметра используется метод setString, для осуществления
подстановки целочисленного параметра — метод setlnt. При
вызове метода, осуществляющего подстановку, первый параметр метода указывает относительный номер параметра исходного запроса. Например, setString(l, "Abe") приведет к
подстановке строки "Abe" на место первого параметра.
Рассмотрим пример, когда критерий запроса содержит
параметр. Пусть запрос формулируется как SELECT * FROM
Tabl WHERE At2 > X, где значение параметра X вводится
пользователем с терминала. По сути изменения коснулись
только шага 3 базового приложения. Текст приложения, выполняющего подстановку вводимого значения в параметрический запрос, приведен в листинге 189.
// Пример приложения, выполняющего
// параметрический запрос
import java.sql.*;
'import j ava. io. *;
362
Создание приложений на языке Java
public class TestSel2
{
//
// Шаг 1: Зарегистрировать JDBC драйвер Oracle
//
static
<
try
{
DriverManager.registerDriver(new oracle .j dbc.driver.OracleDriver() ) ;
1
catch (Exception e)
{
System.out.println("Ошибка регистрации
драйвера JDBC");
e.printStackTrace();
}
}
public static void main(String args[])
{
try
{
//
J/ Шаг 2: Создание объекта соединения
.
//
String Connectstring =
"j dbc:oracle:thin:@ora_server:1521:ORCL";
String UserlD = "Ul";
String Psw = "U1PSW";
Connection con - DriverManager. getConnection(Connectstring,UserlD,Psw);
//
// Шаг З: Подготовить предложение создания
//
таблицы, используя метод
//
prepareStatement
//
String SelTab = "SELECT * FROM Tabl WHERE
At2 > ? ";
PreparedStatement pS =,
con.preparestatement(SelTab);
//
363
Раздел 5
//
Шаг 3.1 Ввести значение порога
//
InputStreamReader isr = new InputStreamReader (System.in);
BufferedReader br = new BufferedReader(isr);
String st;
System.out.println("Введите пороговое значение ") ;
st = br.readLine() ;
//
//
Шаг 3.2 Выполнить подстановку
//
pS.setString(1,st);
//
// Шаг 4: Выполнить операцию,
//
используя метод executeQuery
ResultSet RS = pS.executeQuery();
//
// Получить доступ к метаданным
//
ResultSetMetaData RSMD = RS.getMetaData();
//
// Определить число столбцов таблицы
//
int numCols = RSMD.getColumnCount();
//
// Вывести имена столбцов
//
int i;
for (i = 1; i <= numCols; i++)
{
if (i > 1) System.out.print(" ");
System.out.print
(RSMD..getColumnLabel (i) ) ;
}
System.out.println("\n
—") ;
//
// Вывести содержимое таблицы
//
while (RS.nextO)
{
for (i' = 1; i <= numCols;
{
364
Создание приложений на языке Java
if (i > 1) System. out .print (" ");
System. out .print {RS . getString (i) ) ;
}
System. out .print ("\n") ;
// Шаг 5: Освободить ресурсы
//
pS. close ( ) ;
con. close ( ) ;
}
catch (SQLException e).
{
// Шаг Х: Универсальный обработчик исключительных ситуаций
//
System. out .println ( "Хотели как лучше. . .") ;
System. out. println ("SQLState: " +
e.getSQLStateO ) ;
System. out. println ("SQLCODE: " .,+
e . getMessage ( } ) ;
}
catch (lOException ioe)
{
ioe.printStackTrace () ;
Листинг 189. Приложение, осуществляющее параметрический запрос, значение параметра для которого вводится пользователем
В нормальном режиме работы приложения, представленного листингом 1 89, на терминал будут выведены следующие
сообщения.
C:\WORK> Java TestSel2
Введите пороговое значение
12
365
Раздел 5
ATI
AT2
bed
20
АТЗ
2002-03-21
Листинг 190. Протокол штатного режима работы приложения, выполняющего параметрический запрос
Хранимые процедуры
на языке Java
Поддержка языка Java встроена также в ядро сервера
OracleS (наличие поддержки зависит от версии сервера и
комплекта поставки). В настоящее время активно обсуждается использование Java для написания хранимых программ в
качестве альтернативы PL/SQL. К преимуществам Java перед
PL/SQL относятся, в частности, большое количество готовых
библиотек, динамическая загрузка классов, расширенные
возможности для работы в сети. К преимуществам PL/SQL
следует отнести его изначальную ориентированность на работу внутри базы данных, огромное количество строк PL/SQLкода различных приложений, сопровождаемого большим
числом программистов.
Компонент, который осуществляет поддержку Java в ядре
СУБД, называется JServer. JServer осуществляет загрузку
классов Java в базу данных, компиляцию Java-кода, специальным образом поддерживает безопасность выполнения. В
его состав входит виртуальная Java-машина (JVM), которая
запускается для каждой сессии при первом обращении к программе на языке Java. При этом начинается Java-сессия. При
окончании Java-сессии виртуальная машина уничтожается.
Окончание Java-сессии происходит при окончании сессии в
базе данных, при истечении тайм-аута или при вызове специальной инструкции.пользовательским приложением.
Каждому пользователю базы данных могут быть предоставлены привилегии на выполнение определенных действий в
366
Создание приложений на языке Java
Java-приложениях. Для этого используется два метода: назначение специальной роли или прямое предоставление привилегий. Приведем список основных ролей для работы с Java:
— JAVA__ADMIN — все привилегии;
— JAVAUSERPRIV — ограниченный набор привилегий;
— JAVASYSPRIV — расширенный набор привилегий.
С помощью конкретных привилегий можно предоставить
возможность чтения/записи в-указанный файл или каталог,
изменения свойств JVM, чтения свойств класса и т. д. Управлять этими ролями и привилегиями можно двумя способами:
с помощью SQL-предложений и с помощью инструкций Java.
Для первого способа используется специальный пакет
DBMSJAVA.
Приведем пример предоставления пользователю U1 привилегий на чтение/запись для каталога C:\DATA2.
SQL>
2 3
4
5
6
BEGIN'
DBMS_JAVA.GRANT_PERMISSION('Ul',
'java.io.FilePermission','C:\DATA2',
'read,write');
END;
/
PL/SQL procedure successfully completed.
SQL> COMMIT;
Commit complete.
Листинг 191. Предоставление привилегий с помощью
пакета DBMS JAVA
После предоставления/отмены привилегий необходимо
выполнить фиксацию транзакций, так как все изменения отражаются в специальной таблице SYS.JAVA$POLICY$ (там
можно посмотреть назначенные привилегии, однако прямое
изменение данных в таблице не рекомендуется). Обратите
367
Раздел 5
внимание при работе с привилегиями с помощью операторов
GRANT и REVOKE фиксация транзакций производится автоматически.
Для разграничения доступа также можно использовать
Java-класс oracle.aurora.rdbms.security.PolicyTableManager с
аналогичными методами.
Создание хранимой программы с использованием Java
включает в себя несколько этапов:
— создание Java-кода;
—- помещение Java-кода в базу данных;
— предоставление доступа к Java-программе.
В процессе программирования создается исходный текст
Java-класса. Этот класс должен содержать минимум один статический метод. Для создания функции необходимо, чтобы
метод класса возвращал объект Java-типа, имеющего аналог в
SQL.
Помещение этого кода в базу данных может производиться несколькими способами:
— с использованием специальных операторов SQL;
— с использованием загрузчика loadjava (с предварительной компиляцией (загружается .class) или без (загружается .Java)).
Для первого способа применяется
SQL-оператор
CREATE JAVA. Для работы с ним необходимо иметь системные привилегии CREATE PROCEDURE и CREATE TABLE.
Существует три типа команды CREATE JAVA (CLASS,
SOURCE, RESOURCE) для создания соответственно класса,
исходного Java-кода и Java-ресурса (рисунка, файла свойств и
т.п.) из значения типа LOB или текста самой команды. Для
создания .кода хранимой процедуры можно использовать
CREATE JAVA SOURCE (загружается и компилируется исходный код) или CREATE JAVA CLASS (загружается откомпилированный класс из значения типа BFILE). Пример создания кода хранимой процедуры представлен в листинге 192.
368
V
Создание приложений на языке Java
SQL>
2
•3
4
5
6
Java
CREATE OR REPLACE JAVA SOURCE NAMED "jsl"
as public class jcl{
public static String Say(){
return "Hello from Oracle Java Support ";
}}
/
created.
Листинг 192. Пример загрузки в базу данных Javaкода с помощью оператора CREATE JAVA SOURCE
Для загрузки кода с помощью утилиты loadjava требуется
те же привилегии, что и для применения оператора CREATE
JAVA, а также привилегии для операций с записями в таблице JAVA$CLASS$MD5$TABL'E, в которой хранятся сведения
о классах. Эти сведения используются для контроля изменений в классах, чтобы при необходимости перекомпилировать
классы или заново не загружать старую версию при повторной загрузке.
Утилита loadjava имеет такие же параметры, что и оператор CREATE JAVA. К дополнительным "параметрам относятся: строка соединения с базой данных; используемый при
этом драйвер; логические параметры: загружать все указанные файлы или только обновленные; создавать ли общедоступные синонимы для загружаемых объектов и т. п. Пример
использования утилиты loadjava приведен в листинге 193.
D:\ORANT\BINMoadjava.bat -user ul/ul@educ verbose cl.class
arguments: '-user' ' u l / u l ' '-verbose' ' e l l . c l a s s '
created
:JAVA$CLASS$MD5$TABLE
creating : class ell
369
Раздел 5
created
loading
:CREATE$JAVA$LOB$TABLE
: class ell
Листинг 193. Загрузка•откомпилированного класса с
помощью утилиты loadjava
Данная команда указывает утилите loadjava соединиться
с базой данных, используя учетную запись пользователя U1, и
загрузить в его схему класс ell. Параметр VERBOSE специфицирует вывод на экран протокола загрузки.
Следует отметить, что возможно создание и компиляция
Java объектов в других схемах. Таким образом, можно использовать библиотечные классы, загруженные в какую-либо
схему. При этом для их использования надо будет либо создать синонимы, либо разрешить их при компиляции.
Удаление объектов Java из базы данных производится
оператором DROP JAVA (CLASS, SOURCE, RESOURCE) или
утилитой dropjava. Пример удаления Java-объектов приведен
в листинге 194.
SQL> DROP JAVA SOURCE "jsl";
Java dropped.
SQL> DROP JAVA CLASS "ell";
Java dropped.
Листинг 194.
данных
Пример удаления
Java-кода из
базы
За этапом загрузки следует этап публикации, который
представляет собой создание хранимой программы, ссылающейся на статический метод загруженного класса. Эта программа может представлять собой хранимую процедуру или
функцию, процедуру или функцию в пакете или метод объекта. Синтаксис команд создания Java-процедур такой же, как и
при создании обычной хранимой процедуры, отличается
370
Создание приложений на языке Java
только описание тела процедуры. В листинге 195 представлена публикация метода Say() класса j c l . После публикации ее
можно использовать как обычную хранимую функцию. Компиляция класса будет произведена автоматически при первом
обращении к нему.
SQL>CREATE OR REPLACE FUNCTION f l RETURN VARCHAR2
2
AS LANGUAGE JAVA NAME
3
' j c l . S a y ( ) return j a v a . l a n g . S t r i n g ' ;
4 /
Function created.
SQL> SELECT fl FROM dual;
Fl
Hello from Oracle Java Support
Листинг 195. Публикация'и использование Java-кода
Приведем пример создания хранимой процедуры с передаваемыми и возвращаемыми параметрами. Пусть таблица
Tab! создана предложением:
CREATE TABLE Tab!(Atl VARCHAR2(100));
SQL> CREATE OR REPLACE JAVA SOURCE NAMED
"test_stored_proc" AS
2 import java.sql.*;
3 public class store_proc{
4
private static String query = "";
5
public static void selectData(String
query,String[] answer){
6
try{
7
store_proc.query = query;
8
Connection conn =
9 DriverManager.getConnection("jdbc:default:connection:") ;
371
Раздел 5
10
Statement stmt = conn.createStatement();
11
ResultSet rset = stmt.executeQuery(query);
12
if (rset.next ()){
. 13
answerfO] = rset.getString(1);
14.
}
15 else {
16
answer-[0] = "empty";
17
}
18
stmt = conn.createStatement();
19
stmt.executeUpdate("INSERT INTO Tabl VALUES (' "+answer [0] +"' ) ") ;
20
}
21
catch(Exception e){
22
System.out.println("Error:
"+e.toString().) ;
23
} •
24 }
25
26 public static void selectData(){
27 store_proc.selectData(store_proc.query,new
String[1])T
28 }
29
30 }
31 /
Java created.
Листинг 196. Загрузка Java-кода класса store_proc
В классе store_proc содержится два статических метода и
статическое поле, в котором будут храниться данные между
вызовами второго и первого методов. Первый метод сохраняет запрос в статическом поле, выполняет его, записывает значение из первого столбца первой строки результата запроса в
таблицу Tabl и возвращает его. Второй метод вызывает первый метод, но ничего не возвращает. Для работы с таблицами
базы данных в примере используется соединение по умолчанию "jdbc:default:connection:", которое является внутренним
каналом базы данных.
372.
Создание приложений на языке Java
Для публикации этого класса выполним следующие действия:
SQL> CREATE OR REPLACE PROCEDURE
2 selDataQuery(query IN varchar2,
3 answer IN OUT varchar2)
4 as language .Java name 'store_proc.selectData
5 (Java.lang.String,Java.lang.String[])';
6 /
Procedure created.
SQL>CREATE OR REPLACE PROCEDURE selData AS
2 LANGUAGE JAVA NAME store_proc. selectData (•)';
3 /
Procedure created.
Листинг 197. Публикация класса store_proc
Проверим функционирование опубликованного класса.
Результаты работы его методов представлены в листинге 198.
SQL> DECLARE
2
str VARCHAR2(200);
3 BEGIN
4
selDataQuery('SELECT TO_CHAR(SYSDATE) FROM
dual',str); '
. 5
selData();
6 END;
7 /
PL/SQL procedure successfully completed.
SQL> SELECT * FROM Tabl;
ATI
•-•••'
12-03-2002
12-03-2002
Листинг 198. Результат
store_proc
работы
методов
класса
373
Раздел 5
В заключение рассмотрим использование в Javaпрограммах статических операторов SQL (т.н. "Embedded
SQL in Java" или SQLJ). Для того чтобы запись SQLвыражений в Java-коде была так же естественна, как и в программах на PL/SQL, применяется следующая технология:
операторы SQL внутри кода Java записываются по определенным правилам, затем транслируются в "чистый" код Java
(один или несколько классов) и только после этого компилируются в байт-код.
Пусть таблица ТаЬ2 создана и заполнена следующими
предложениями:
CREATE TABLE Tab2
(Atl VARCHAR2(10), At2 VARCHAR2(10));
INSERT INTO Tab2 VALUES ('A^'B');
INSERT INTO Tab2 VALUES ('C','D');
В листинге 199 представлена программа, с помощью которой выводятся все записи из таблицы ТаЬ2 с использованием технологии SQLJ.
SQL> CREATE OR REPLACE JAVA SOURCE NAMED
"test_sqlj_source" AS
2
public class test_sqlj{
3
#sql public static iterator objec- .
tlter(String,String);
4
public static String giveAll()
5
throws Java.sql.SQLException{'
6
objectlter oi=null;
String answer = "";
8
String Atl = "";
9
String At2 = "";
10
#sql oi = {select Atl,At2 from Tab2} ;
11
while (true) {#sql{ FETCH -:oi INTO
:Atl,:At2 };
12
if (oi.endFetchO ) break;
13
answer+= Atl+" - "+At2+"; ";}
14
return answer;}
15
}
'374
Создание приложений на языке Java
16 /
Java created.
SQL> CREATE FUNCTION giveList RETURN VARCHAR2
2
AS LANGUAGE JAVA NAME ' t e s t _ s q l j . g i v e A l l ( )
3
return J a v a . l a n g . S t r i n g ' ;
4 /
Function created.
SQL>
SELECT giveList FROM dual;
GIVELIST
A - В; С - D;
Листинг 199. Использование технологии SQLJ
375
Раздел 6
Средства обеспечения
целостности данных
Современный уровень развития распределенной обработки данных характеризуется размещением логически единой
информационной базы в сетевой среде и асинхронной многопользовательской обработкой с развитыми средствами обеспечения целостности данных. Наличие единой информационной базы и асинхронной обработки данных ставит сложную
задачу поддержки согласованности данных независимо от
вносимых изменений различными пользователями в различное время.
Средства обеспечения целостности данных обеспечивают
защиту от непреднамеренного искажения или уничтожения.
Источниками соответствующих угроз являются:
— нарушения нормального режима функционирования
аппаратуры;
— ошибки, связанные с необходимостью обеспечить параллельное проведение операций с единой информационной
базой;
— ошибки, присутствующие в программном обеспечении;
— ошибки администраторов, осуществляющих штатные
операции с базами данных;
— ошибки пользователей при выполнении операций
ввода и модификации данных.
376
Средства обеспечения целостности данных в Oracle
Защита данных от проблем, вызванных нарушениями
нормальной работы аппаратуры, обычно обеспечивается
осуществлением процедур резервного копирования баз данных. Для создания резервных копий баз данных используются
две основные технологии: оперативное копирование файлов
(или содержимого псевдоустройств для UNIX-систем) и экспорт баз данных.
Экспорт баз данных обычно осуществляется в некоторый
специальный формат данных, независимый от особенностей
используемой операционной системы и аппаратной платформы. Экспорт требует большего времени, но обеспечивает более универсальный результат.
Физическое копирование файлов выполняется быстрее,
но доступ к копии требует воссоздания операционной среды:
необходимо наличие соответствующей условиям копирования операционной системы и файловой структуры. Кроме того, в условиях необходимости постоянной эксплуатации баз
данных этот способ трудно применим.
Проблемы, связанные с необходимостью обеспечить параллельное проведение операций с единой информационной
базой, решаются за счет блокировок и других механизмов
управления многопользовательским доступом к данным.
Для защиты от ошибок администраторов и пользователей
баз данных применяются ограничения целостности. Ограничения целостности — это задаваемые разработчиком правила,
которые проверяются при вставке, изменении или удалении
данных.
Ограничения целостности могут быть сформулированы в
статической (декларативной) или динамической форме. Способы описания ограничений в статической форме определены
в стандарте SQL92 и более поздних стандартах в области обработки данных.
Описание ограничений целостности в динамическом виде
обычно осуществляется в форме создания триггеров. Триггер
—- это программа, автоматически запускаемая сервером баз
данных при наступлении некоторых событий.
377
-
•
Раздел 6
Рассмотрим проблемы, связанные с распараллеливанием
операций с единой информационной базой, обрабатываемой в
режиме многопользовательского доступа.
Определение транзакции
и ее роль в СУБД
Транзакция — это последовательность операторов обработки данных, которые рассматриваются как логически неделимая единица работы с базой данных. В дальнейшем будем
считать, что в роли операторов обработки данных выступают
SQL-предложения, при проведении которых база данных переводится из одного допустимого состояния в другое. Под
допустимым состоянием понимается такое состояние базы
данных, при котором выполняются ограничения целостности.
Система гарантирует невозможность фиксации некоторой
части действий из транзакции в базе данных. Например, пусть
модификация строк некоторой таблицы оформлена в виде
транзакции. Тогда система гарантирует, что пользователь,
выполняющий выборку из таблицы, будет получать либо
только "старые" данные, либо только "новые". То есть, невозможна ситуация, когда в результате запроса возвращается
часть "старых" и часть "новых" данных.
Oracle гарантирует согласованность данных на транзакции. Именно для транзакции данные либо сохраняются в базе
данных в том виде, который доступен всем пользователям,
либо откатываются в состояние, предшествующее началу
транзакции. Если в процессе выполнения транзакции произошел сбой операционной системы или прикладной программы, после ликвидации последствий сбоя, данные в базе
автоматически восстанавливаются в состояние, предшествующее началу выполнения транзакции.
До тех пор пока транзакция не зафиксирована, ее можно
"откатить" (ROLLBACK), то есть отменить все сделанные
операторами из транзакции изменения в базе данных. Обра378
Средства обеспечения целостности данных в Oracle
тите внимание, что смысл фразы "SQL-операторы транзакции
успешно завершены" отличается от смысла фразы "транзакция зафиксирована" (COMMITTED). Успешное выполнение
SQL-операторов означает, что операторы проанализированы,
интерпретированы как правильные, а затем безошибочно исполнены. "Зафиксировать транзакцию" :— означает сделать
изменения, выполненные данной транзакцией в базе данных,
постоянными. Пока транзакция не зафиксирована, результат
ни одного из ее действий не виден другим пользователям.
Например, пусть регистрируется переход работника из
одного подразделения в другое оформленный в виде транзакции, изменения в базе данных организации либо будут проведены в совокупности, либо будут отменены, если в процессе
их проведения будет зафиксирована ошибка. То есть такой
ситуации, когда сотрудник.будет зарегистрирован в двух подразделениях сразу (обычно этому соответствует две записи),
не может быть, если удаление "старой" и вставка "новой" записей представлено как транзакция. Отметим, что для систем
типа dBase, изначально ориентированных на ведение локальных баз данных, проблема согласованности данных, даже в
сетевой среде, либо не возникает вообще, либо решается с
помощью средств операционной системы.
Начало и окончание транзакции
Транзакция начинается при поступлении первого SQLоператора и завершается при появлении одного из следующих событий:
— выдана команда COMMIT или ROLLBACK;
'— выдана одна из таких команд языка описания данных
(DDL), как CREATE или DROP (при этом фиксируется предыдущая транзакция);
— завершился оператор DDL (транзакция, содержащая
оператор языка описания данных, автоматически фиксируется);
379
Раздел 6
-—пользователь завершил сеанс (последняя транзакция
автоматически фиксируется);
— процесс пользователя аварийно завершен (транзакция
автоматически откатывается).
}
.
-
Как только транзакция завершена, следующий SQLоператор начинает новую транзакцию. Если в конце транзакции отсутствуют операторы COMMIT или ROLLBACK, то
нормальное завершение программы приведет к фиксации
транзакции, а аварийное завершение (вызванное, например,
разрывом связи в локальной сети) вызовет откат транзакции.
Если произошел сбой на стороне сервера, то откат транзакции
с использованием сведений из журналов транзакций будет
автоматически выполнен при запуске экземпляра после восстановления нормального режима работы сервера.
Предложения SQL,
управляющие транз акциями
Для фиксации или отката транзакции в языке SQL используются предложения COMMIT WORK, SAVEPOINT и
ROLLBACK WORK.
Предложение COMMIT фиксирует транзакцию. Предложение SAVEPOINT сохраняет промежуточную копию состояния задействованных в транзакции объектов базы данных
для того, чтобы впоследствии, при необходимости, можно
было вернуться к состоянию в точке сохранения. Предложение ROLLBACK выполняет откат транзакции, то есть отменяет изменения, выполненные данной транзакцией в базе данных. Откат транзакции обычно выполняется в том случае,
когда произошла ошибка в приложении, обнаружено нарушение ограничений целостности или обнаружен клинч системных ресурсов. Для иллюстрации понятия клинча системных
ресурсов рассмотрим пример.
380
Средства обеспечения целостности данных в Oracle
Пусть процесс А в момент времени ti запросил в монопольное использование ресурс X. Ресурс X был предоставлен
процессу А. В момент времени t2 > ti процесс В запросил в
монопольное использование ресурс Y. Ресурс Y был предоставлен процессу В. В момент времени tj > i? процесс А запросил в монопольное использование ресурс Y. Поскольку ресурс Y находится в монопольном использовании процесса В,
то процесс А переводится в состояние ожидания. В момент
времени ti > t2 процесс В запрашивает в монопольное использование ресурс X. Поскольку ресурс X находится в монопольном использовании процесса А, то процесс В переводится в состояние ожидания. В результате — клинч. Оба процесса могут находиться в состоянии ожидания сколь угодно долго.
Предложенный Н. Виртом формальный алгоритм разрешения таких конфликтов не всегда приемлем, так как требует
единовременного запроса на все монопольно используемые
ресурсы. Для СУБД такой подход мог бы привести к потере
эффективности обработки данных. Альтернативный подход
состоит в том, что пользовательские приложения должны сами определять ситуацию клинча и выполнять откат транзакции.
Предложение COMMIT WORK
Предложение COMMIT WORK имеет следующий синтаксис:
COMMIT [WORK]
Ключевое слово WORK может быть опущено. Предложение COMMIT WORK обеспечивает выполнение следующих
действий:
— фиксируются все изменения в базе данных, сделанные
в текущей транзакции;
— завершается транзакция;
381
Раздел 6
— уничтожаются все точки сохранения для данной
транзакции;
— освобождаются объекты, заблокированные в процессе
выполнения транзакции.
Хорошим стилем разработки кода прикладных программ
является явное завершение транзакций. Рекомендуется выдавать предложение COMMIT WORK и перед завершением сеанса. Использование такой практики обеспечит автоматический откат неуспешной транзакции с прогнозируемым результатом при аварийном завершении прикладного процесса,
вызванного программным или аппаратным сбоем.
В процессе выполнения транзакции, в которой содержатся операторы изменения данных, происходит выполнение
следующих действий:
— создается копия данных в сегментах отката;
— выполняется формирование соответствующих записей
в журнальный файл;
— производятся изменения в буферах базы данных.
Когда транзакция явно или неявно завершается, выполняется следующий набор операций:
-— транзакция помечается как зафиксированная;
— если записи из журнального файла еще не записаны в
файлы базы данных, то выполняется запись в долговременную память;
— заблокированные объекты системы освобождаются.
Команда COMMIT также позволяет указывать значение
параметра COMMENT для комментирования подтверждаемой транзакции.
382
Средства обеспечения целостности данных в Oracle
Использование предложения SAVEPOINT
Точки сохранения (SAVEPOINT) используются для разделения длительной транзакции на более мелкие элементы. В
длительной транзакции, выполняющей значительные изменения в базе данных, целесообразно сохранять частичные изменения в определенных точках, чтобы при возникновении
ошибки или клинча системных ресурсов выполнять откат не к
точке старта транзакции, а к последней успешно выполненной точке сохранения.
Предложение SAVEPOINT имеет следующий синтаксис:
SAVEPOINT
имя_^точки_сохранения
Параметр шля_точки_сохранения содержит идентификатор точки сохранения. Если значение параметра пмя_ точки _сохраненш совпадает с ранее использованным значением,
информация о предыдущей точке сохранения теряется.
Предложение ROLLBACK WORK
Это предложение служит для отката транзакции к исходному состоянию или точке сохранения и имеет следующий
синтаксис:
ROLLBACK [WORK] TO имя_точки_сохранения
Использование ключевого слова WORK необязательно.
Использование предложения ROLLBACK приводит к следующим действиям:
— завершению выполнения транзакции;
— отмене всех изменений в текущей транзакции;
— отмене всех блокировок транзакции.
Проиллюстрируем назначение команд SAVEPOINT и,
ROLLBACK следующими примерами.
383
Раздел б
Пример 1
SQL> INSERT INTO Tab!
VALUES(1,1,1);
1 row created.
ч
Пример 2
SQL> INSERT INTO
Tabl VALUES(1,1,1) ;
1 row created.
SQL> ROLLBACK;
Rollback complete.
SQL> SAVEPOINT si;
Savepoint created.
SQL> SELECT * FROM
TAB1;
no rows selected
SQL> INSERT INTO
Tabl VALUES(1,1,1);
1 row created.
SQL> SELECT COUNT (*)
FROM Tabl;
COUNT(*)
2
SQL> ROLLBACK TO si;
Rollback complete.
SQL> SELECT COUNT(*)
FROM Tabl;
COUNT(*)
1
Все отмеченные выше технические детали приведены
только для того, чтобы еще раз проиллюстрировать принципиальное различие между работой СУБД промышленного
уровня и персональной СУБД типа Microsoft Access. Более
сложные механизмы проведения и синхронизации операций в
многопользовательском варианте работы СУБД обеспечивают высокую отказоустойчивость, способность к восстановлению и требуемую степень согласованности данных.
384
Средства обеспечения целостности данных в Oracle
Непротиворечивость
и параллельная обработка
Отличительной особенностью СУБД промышленного
уровня является поддержка параллельной работы многих
пользователей. Пользователи формируют запросы на доступ и
изменение информации в базе данных асинхронно, то есть в
произвольные моменты времени, без взаимной согласованности действий. Одно из базовых требований к СУБД — поддержка целостности данных, то есть такого состояния, когда
в произвольный момент времени данные адекватно отображают состояние моделируемых объектов.
Суть проблемы состоит в том, что в процессе управления
параллельной работой СУБД данные могут быть изменены
или модифицированы не в надлежащей последовательности,
что может привести к потере их целостности.
Перечислим некоторые ситуации, которые могут возникнуть из-за асинхронного выполнения действий пользователя с
базой данных:
— "проблема пропавшего обновления" (два пользователя
запрашивают из базы одни и те же данные и используют их
для каких-либо расчетов, а затем пытаются обновить эти данные);
— "проблема промежуточных данных" (пользователь в
ходе выполнения своей работы имел доступ к промежуточным данным, внесенным другим пользователем и на их основе произвел ошибочное обновление);
— "проблема строк-фантомов" (один и тот же запрос,
.выполненный пользователем дважды в течение одной транзакции, возвращает два различных результата).
Подобные ситуации подробно описаны в стандартах SQL
и имеют собственные названия.
Очевидным решением проблемы согласованного изменения базы данных является формирование очереди пользо385
13. Заказ № 1628.
4
•
•
'
•
'
"
•
Раздел 6
вателей к каждому ресурсу системы (таблице, представлению, индексу и т. п.)- Недостатком этого решения является
резкое снижение производительности. Если количество пользователей исчисляется десятками или сотнями, то блокировка^
дефицитного ресурса приведет к очень большому времени
ожидания.
Сервер Oracle использует иной метод решения сформулированной проблемы — многоверсионную модель, при которой в системе может одновременно существовать несколько различающихся версий данных. Механизм версионности
реализован в Oracle через сегменты отката, в которых хранятся старые версии данных. В случае когда оператор пытается
прочитать данные, модифицированные другими пользователями за время его работы, старые версии данных на момент
начала запроса считываются из сегментов отката. При этом
Oracle не обеспечивает гарантированного чтения предыдущих
версий данных из-за возможного их затирания в сегментах
отката. В случае затирания в сегментах отката старых версий
данных выдается ошибка "ORA-1555 Snapshot too old, rollback
segment too small". Эта ситуация характерна для выполняющихся длительное время сложных запросов в динамично изменяющейся базе данных. Чем дольше выполняется оператор,
тем больше вероятность затирания старых версий данных.
Oracle обеспечивает непротиворечивость данных на уровне оператора и на уровне транзакции. Оператор выборки
SELECT всегда считывает непротиворечивые данные — по
спецификации оператора и разработчик не должен беспокоиться об этом. Для транзакций используются более сложные
схемы поддержки непротиворечивости в условиях необходимости обеспечить требуемый уровень производительности.
Во многих случаях внутренние механизмы СУБД могут
значительно сократить накладные расходы системы поддержания непротиворечивости данных, если пользователь явно
укажет, какие действия будут выполняться во время транзакции. Для явного указания технологии использования данных
введено понятие задаваемого пользователем уровня изоляции.
386
Средства обеспечения целостности данных в Oracle
Уровень изоляции позволяет найти некоторый компромисс
между степенью изоляции и эффективностью работы. В спецификации стандарта SQL это понятие формализовано и расширено. По мере уменьшения уровня изоляции сокращается
число проблем, от которых OracleS защищает пользователя.
Всего существует четыре уровня изоляции: SERIALIZABLE;
REPEATABLE READ; READ COMMITTED; READ UNCOMMITTED.
При использовании сериализованных транзакций Oracle
гарантирует, что результаты параллельного выполнения транзакций будут точно такими же, как если бы эти транзакции
выполнялись последовательно. Если приложению во время
транзакции требуется дважды выполнить один и тот же за7
прос и при этом необходимо гарантировать, что результаты
будут идентичными независимо от параллельно выполняемых
в базе данных транзакций, то следует установить уровень
изоляции SERIALIZABLE.
Уровень изоляции "повторяемое чтение" (REPEATABLE
READ) является вторым по степени изоляции после уровня
SERIALIZABLE. На этом уровне транзакция не имеет доступа
к промежуточным или окончательным результатам других
транзакций, выполняющих обновления данных. Однако во
время транзакции можно увидеть строку, добавленную в базу
данных другой транзакцией. Поэтому один и тот же запрос к
нескольким строкам, выполненный дважды в течение одной
транзакции, может возвратить различные результаты.
Уровень "завершенное чтение" (READ COMMITTED) является третьим по степени изоляции. На этом уровне транзакция не имеет доступа к промежуточным результатам других
транзакций. Однако окончательные результаты других параллельно выполняемых транзакций могут быть доступны. В течение транзакции дважды можно выполнить запрос и обнаружить, что некоторая строка была изменена другим приложением.
Уровень изоляции "незавершенное чтение" (READ
UNCOMMITTED) является наиболее низким уровнем изоля387
13*
Раздел 6
ции. В этом режиме на выполнение транзакции могут повлиять как окончательные, так и промежуточные результаты других транзакций. В общем случае этот уровень подходит только для некоторых приложений со специальными запросами,
где пользователь может позволить, чтобы результаты запросов содержали "грязные" данные. Если важно, чтобы результаты запроса предоставляли только ту информацию, которая
является окончательной на текущий момент для базы данных,
то не следует использовать этот режим.
В инструкции SET TRANSACTION можно указать, операции какого типа осуществляет транзакция: выполняет ли
она только запросы на выборку данных (атрибут READ
ONLY) или может выполнять как выборку, так и изменение
(атрибут READ WRITE). Сервер использует эту информацию
наряду со сведениями об уровне изоляции для оптимизации
работы базы данных.
Oracle поддерживает следующие типы транзакций: Транзакция, читающая зафиксированные другими транзакциями
данные во время ее работы. Пользователь может явно начать
такую
транзакцию
при
помощи
оператора
SET
TRANSACTION READ WRITE. Транзакция по умолчанию
(от начала сеанса до первой команды COMMIT/ROLLBACK,
от команды COMMIT/ROLLBACK до следующей команды
COMMIT/ROLLBACK, или до конца сеанса) является транзакцией этого типа. Перед началом любой транзакции по
умолчанию
неявно
выполняется
оператор
SET
TRANSACTION READ WRITE. Если два оператора SELECT
в разных частях транзакции этого типа обращаются к одним и
тем же строкам в таблице, то возможно получение противоречивых результатов. Противоречие возникнет в том случае,
если какой-либо пользователь модифицировал и зафиксировал изменения этих строк на интервале времени между двумя
вышеупомянутыми операторами SELECT. To есть в рамках
одной транзакции возможно чтение данных, модифицированных зафиксировавшим изменения другим пользователем.
Пример таких транзакций приведен ниже.
388
Средства обеспечения целостности данных в .Oracle
SQL> SET TRANSACTION
READ WRITE;
SQL> CREATE TABLE
Tabl(Atl NUMBER, At2 VARCHAR2 (200) );
Table, created. '
SQL> SELECT * FROM Tabl;
no rows selected.
SQL> INSERT INTO
Tabl VALUES (1, 'a') ;
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM Tabl;
1
a
Транзакция "только для чтения". Внутри такой транзакции допустимы только запросы, другие операторы языка
DML недопустимы. При обращении операторов SELECT из
различных частей транзакции к одним и тем же строкам данных Oracle выдает либо одинаковые непротиворечивые данные, находившиеся в базе данных на момент начала транзакции, либо ошибку ORA-1555. Пользователь может начать такую транзакцию при помощи оператора SET TRANSACTION
READ ONLY и закончить оператором COMNUT/ROLLBACK.
SQL> SET TRANSACTION
READ ONLY;
SQL> CREATE TABLE
Tabl ( At 1 NUMBER, At2
VARCHAR2(200) ) ;
Table created.
SQL> SELECT * FROM Tabl;
no rows selected.
SQL> INSERT INTO
Tabl VALUES (1, 'a') ;
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM Tabl;
no rows selected.
389
Раздел б
.
Сериалюуемая транзакция. Такие транзакции предназначены для сериализации обновлений при конкурентной работе нескольких пользователей с одними и теми же данными.
Способ выполнения набора транзакций называется сериальным, если результат совместного выполнения транзакций эквивалентен результату некоторого последовательного выполнения этих же транзакций. При помощи этих транзакций, одновременно выполняемых разными, пользователями, результат модификации данных в базе таков, как если бы соблюдалась очередность, то есть сначала один пользователь начал и
закончил транзакцию, после него второй провел свою транзакцию, потом третий и т. д. Вообще говоря, процесс сериализации транзакций очень сложен, и не всегда возможно сериализовать одновременно проводимые несколькими пользователями транзакции. Сериализуемые транзакции всегда
непротиворечивы, то есть все выборки получают данные из
"снимка" базы, сделанного на момент выдачи оператора SET
TRANSACTION ISOLATION LEVEL SERIALIZABLE. При
условии, что запись осуществляется только в таблицы данного пользователя, можно трактовать сериализуемые транзакции как транзакции только для чтения (READ ONLY) с возможностями выдачи операторов DML. Сериализуемая транзакция начинается оператором
SET TRANSACTION
ISOLATION LEVEL SERIALIZABLE.
Проведенные примеры иллюстрируют еще одно принципиальное различие настольных СУБД и систем промышленного уровня. Конечно, реальная проблема гораздо сложнее и
многограннее, но ее серьезное обсуждение выходит за рамки
этой книги. Практический же вывод из сказанного состоит в
том, что производительность системы обработки данных, работающей с большим количеством пользователей, зависит в
том числе и от правильной настройки работы механизмов параллельной обработки, в частности рационального выбора
типов транзакций.
В большинстве случаев автоматически используемые
Oracle механизмы поддержки параллельной работы вполне
390
Средства обеспечения целостности данных в Oracle
достаточны для решения практических задач. Тем не менее
сервер поддерживает развитую систему пользовательского
управления блокировками. Наличие системы управления типами блокировок является еще одной чертой, характерной
для СУБД промышленного уровня.
Типы блокировок
Блокировка — это механизм, предназначенный для предотвращения некорректного изменения данных при параллельной и асинхронной работе пользователей распределенной
системы. Блокировка используется:
— для обеспечения гарантированной неизменности данных другими пользователями в рамках транзакции;
—*- для обеспечения естественного временного порядка
изменений, проводимых в базе данных.
В большинстве стандартных ситуаций сервер Oracle
обеспечивает необходимые блокировки автоматически и не
требует дополнительных действий пользовательского процесса. Однако иногда может потребоваться явное управление
. блокировками для настройки производительности или выполнения специальных требований к прикладной системе.
Чаще всего пользователи блокируют определенные строки таблиц, используя оператор SELECT ... FOR UPDATE,
или полностью таблицы, используя оператор LOCK TABLE.
Блокировка данных может иметь различный тип. Тип
блокировки определяет, какие действия можно выполнять с
заблокированным ресурсом другим пользователям. Например, если один процесс получил исключительную блокировку
некоторой таблицы, никакой другой процесс не сможет изменять строки в этой таблице. Основные типы блокировки приведены в таблице 31.
Использовать блокировки следует в зависимости от логики приложения. Например, программа пакетного обновления,
391
Раздел 6
которая обращается к каждой строке таблицы, в процессе работы будет блокировать таблицу по частям. Для более быстрого выполнения программе следует явно заблокировать всю
таблицу с помощью команды LOCK TABLE, выполнить все
необходимые обновления, а затем разблокировать ее. Блокировка всей таблицы имеет два преимущества:
— устраняются затраты, связанные с блокировкой строк;
— исключается возможность того, что другая транзакция
заблокирует часть таблицы, вынуждая программу пакетного
обновления находиться в состоянии ожидания.
У блокировки таблицы есть недостаток, состоящий в том,
что все остальные транзакции, которые пытаются модифицировать данные в таблице, должны ждать. Но, поскольку транзакция, выполняющая пакетное обновление, обычно работает
быстрее остальных, общая производительность при явной
блокировке таблицы может даже увеличиться.
•Синтаксис оператора .блокировки выглядит следующим
образом:
LOCK TABLE [имя_схемы.]имя_таблицы
IN { тип_блокировки } MODE
Таблица 31. Основные
Oracle
Тип блокировки
Exclusive (X)
(исключительная)
Share (S)
(разделяемая)
Row Share (RS)
(разделение строк)
392
типы
блокировок
ресурсов
Содержательный смысл
Исключительные блокировки разрешают выполнять запросы для заблокированных объектов, но запрещают любые другие действия.
Разделяемые блокировки разрешают
запросы, но запрещают изменения в
таблицах.
Блокировка типа разделения строк
разрешает параллельный доступ к
Средства обеспечения целостности данных в Oracle
Row Exclusive (RX)
(исключительная
для строк)
Share Row
Exclusive (SRX)
(исключительное
разделение строк)
таблице. Этот тип запрещает другим
пользователям блокировать таблицу
в исключительном режиме.
Исключительные для строк блокировки аналогичны блокировкам типа разделения строк, но, кроме того,
запрещают блокировку в разделяемом режиме. Эта блокировка применяется при изменении, удалении
и вставке строк.
Блокировки типа исключительного
разделения строк используются для
просмотра всей таблицы для выборочных изменений и позволяют
другим пользователям просматривать строки в этой таблице, но не
позволяют блокировать таблицу с
разделяемом типом или с типом для
обновления строк.
.
Примеры блокировки данных для изменения в условиях
многопользовательского доступа приведены в .специальной
части раздела "PL/SQL — процедурное расширение языка
SQL".
Ограничения 'целостности
Средства обеспечения целостности баз данных включают
автоматическую поддержку некоторой системы правил, описывающих допустимость и достоверность хранимых и вводимых значений. Реляционная модель включает некоторые характерные правила, вытекающие из существа модели: ограничения домена и ограничения таблицы.
Целостность домена предполагает, что допустимое множество значений каждого атрибута является формально
393
Раздел 6
определенным. То есть существуют формальные способы
проверки того, что конкретное значение атрибута в базе данных является допустимым. Строка не будет вставлена в таблицу, пока каждое из значений ее столбцов не будет находиться в соответствующем домене (множестве допустимых
значений).
Целостность таблицы означает, что каждая строка в
таблице должна быть уникальной. Хотя не все СУБД промышленного уровня требуют выполнения такого ограничения, возможность уникальной идентификации каждой строки
представляется необходимой для большинства реальных приложений.
Ограничения целостности позволяют гарантировать, что
требования к данным будут соблюдаться независимо от способа их загрузки или изменения. Рассмотрим предусмотренные в OracleS типы статических ограничений целостности:
— ограничение на определенность значения атрибута
(NOT NULL);
— ограничение на уникальность значения атрибутов
(UNIQUE);
— ограничение — первичный ключ;
— ограничение —- внешний ключ;
— ограничение целостности, задаваемое предикатом.
Ограничения связываются с конкретной таблицей либо в
момент ее создания, либо создаются оператором ALTER
TABLE. Ограничения целостности могут быть поименованы с
помощью ключевого слова CONSTRAINT. Именование ограничений обычно используется для локализации нарушенного
ограничения в большой системе. Система всегда присваивает
некоторое имя каждому ограничению целостности, но рекомендуется явно назначать унифицированные имена ограничениям, скажем, первичные ключи именовать РК_имя_таблицы.
Пример имени, сформированного по умолчанию, представлен в листинге 201 (U1.SYS_C005873). Пример более осмыс394
Средства обеспечения целостности данных в Oracle
ленного именования ограничений целостности приведен в
листинге 202 (PKJTAB1,).
Наличие ограничения NOT NULL для некоторого атрибута приводит к автоматическому запрещению изменений или
вставок строк, содержащих неопределенные значения этого
атрибута. В листинге 200 представлен пример ограничения на
определенность значения атрибута:
SQL> CREATE TABLE Tabl- (Atl VARCHAR2(3) NOT NULL,
2 At2 INTEGER) ;
Table created.
S,QL> INSERT INTO Tabl VALUES ( ' A ' , I)
I row created.
;
SQL> INSERT INTO Tabl VALUES (NULL, 1 ) ;
INSERT INTO Tabl VALUES (NULL, 1)
*
ERROR at line 1:
ORA-01400: cannot insert NULL into
Листинг 200. Пример ограничения на определенность
_
значения
атрибута
_
Если множество атрибутов (или атрибут) описаны, как
уникальные, сервер автоматически запретит выполнение операции по вставке строки, содержащей значение атрибутов,
совпадающие с ранее введенными.
Для создания ограничений целостности UNIQUE и
PRIMARY KEY требуется, чтобы владелец таблицы имел либо квоту для табличного пространства, в котором должен
быть создан ассоциированный индекс, либо системную привилегию UNLIMITED TABLESPACE.
В листинге 201 представлен пример ограничения на уникальность значения атрибута.
395
Раздел 6
SQL> CREATE TABLE Tab! (Atl VARCHAR2(3),
2 At2 INTEGER UNIQUE);
Table created.
SQL> INSERT INTO Tabl VALUES('A1, 1);
1 row created.
SQL> INSERT INTO Tabl VALUES{'A1, 1);
INSERT INTO Tabl VALUES('A', 1)
*
ERROR at line 1:
ORA-00001: unique constraint (Ul.SYS_C005873)
violated
Листинг 201. Пример проверки ограничения на уникальность значения атрибута
Ограничение — первичный ключ описывает совокупность атрибутов или атрибут, который для данной таблицы
выбран в качестве первичного ключа. Отметим, что в таблице
может быть только один первичный ключ. Первичный ключ
может состоять как из одного столбца, так и из нескольких,
т.е. быть составным. Для OracleS первичный ключ может содержать не более 16 столбцов.
Рекомендуется избегать составных первичных ключей.
Их использование менее удобно. В частности, значения составных первичных ключей не могут назначаться с помощью
последовательностей.
При выполнении вставки новой записи или модификации
атрибутов, входящих в состав первичного ключа, автоматически проверяется уникальность набора их значений (для этого
служит ассоциированный индекс) и отсутствие неопределенных (NULL) значений атрибутов, входящих в состав первичного ключа.
Рассмотрим пример автоматической проверки ограничений, связанных с выбором атрибута в качестве первичного
ключа. Попытка создать еще один первичный ключ отверга-
396
Средства обеспечения целостности данных в Oracle
ется системой. Попытка изменить значение атрибута At2 так,
чтобы значения первичных ключей совпадали, также отвергается системой. Протокол взаимодействия с системой представлен в листинге 202.
SQL>
2
3
Table
CREATE TABLE Tab! (Atl VARCHAR2(3),
At2 INTEGER,
CONSTRAINT pk_tabl PRIMARY KEY (At2));
created.
SQL> ALTER TABLE Tabl
2 ADD PRIMARY KEY (Atl);
ADD PRIMARY KEY (Atl)
*ERROR at line 2:
ORA-02260: table can have only 6ne primary key
SQL> INSERT INTO Tabl VALUES ('A.1, 1).;
1 row created.
SQL> INSERT INTO Tabl VALUES('В', 2);
1 row created.
SQL> UPDATE Tabl SET At2=2 WHERE At2=l;
UPDATE Tabl SET At2=2 WHERE At2=l
*
ERROR at line 1:
ORA-00001: unrque constraint (U1.PK_TAB1) violated
Листинг 202. Пример ограничения, связанного с выбором первичного ключа
Ограничение — внешний ключ связывает значения наборов атрибутов двух таблиц: базовой (PARENT TABLE) и производной (CHILD TABLE). В частном случае одна таблица
может быть и базовой и производной одновременно. Ограничения, определяемые внешними ключами, обычно называют
поддержкой ссылочной целостности.
397
Раздел 6
Ссылочная целостность определяет соотношения между
различными столбцами, когда значения в одном наборе
столбцов должны соответствовать значениям другого набора
столбцов. Если некоторый набор атрибутов производной таблицы объявлен внешним ключом (FOREIGN KEY), то для
каждого его значения должна найтись запись родительской
таблицы с тем же значением ключа.
Например, если в некоторой базе данных, с помощью которой осуществляется учет населения, есть таблица с паспортными данными, то при занесении сведений о новом паспорте будет автоматически проверяться существование в таблице со сведениями о физических лицах записи с идентификатором лица, которому принадлежит паспорт.
Рассмотрим пример. Определим таблицу ТаЬ2, у которой
значение атрибута At4 является внешним ключом по отношению к первичному ключу таблицы Tab!. Ввод данных со значением внешнего ключа, совпадающим с одним из значений
первичного ключа таблицы Tabl, выполняется успешно. Попытка ввести строку в таблицу ТаЬ2 со значением атрибута
At4, которому не соответствует ни одно значение первичного
ключа таблицы ТаЫ, приводит к сообщению об ошибке. Протокол взаимодействия с системой представлен в листинге 203.
SQL> CREATE TABLE ТаЫ (Atl VARCHAR2(3) NOT NULL,
2 At2 INTEGER,
3 CONSTRAINT pk_tabl PRIMARY KEY (At2));
Table created.
SQL> CREATE TABLE Tab2 (At3 VARCHAR2 (3)",
2 At4 CONSTRAINT fk_tab2 REFERENCES Tabl(At2));
Table created.
SQL> INSERT INTO Tab2 VALUES('B', 10);
INSERT INTO Tab2 VALUES('B', 10)
*
ERROR at line 1:
398
Средства обеспечения целостности данных в Oracle
ORA-02291: integrity constraint (U1.FKJTAB2) violated - parent key not found
Листинг 203. Пример проверки ограничения — внешнего ключа •
Ограничение ссылочной целостности не только определяет допустимые значения во внешнем ; ключе производной
таблицы, но и действие при операции с первичным ключом
базовой таблицы.
Например, ссылочное действие каскадного удаления ограничения — внешнего ключа определяет, что при удалении
строки базовой таблицы должны удаляться все зависящие от
нее строки производной таблицы. Рассмотрим пример, иллюстрирующий каскадное удаление. Определим соответствующую модификацию таблицы ТаЬ2. Тогда удаление строки в
базовой таблице приводит к автоматическому удалению
строк в производной таблице. Пример использования ограничения внешнего ключа с опцией каскадного удаления представлен в листинге 204.
SQL> DROP TABLE Tab2;
Table dropped.
SQL> CREATE TABLE Tab2 (At3 VARCHAR2(3) ,"
2 At4 CONSTRAINT fk_tab2
3 REFERENCES t a b l ( a t 2 ) ON DELETE CASCADE);
Table created.
SQL> INSERT_INTO Tabl V A L U E S ( ' A 1 , 1);
1 row created.
SQL> INSERT INTO Tab2 V A L U E S ( ' B ' ,
1 row created.
1);
SQL> SELECT * FROM Tab2;
399
Раздел 6
АТЗ
В
АТ4
1
SQL> DELETE FROM Tab! WHERE At2=l;
1 row deleted.
SQL> SELECT * FROM Tab2;
no rows selected
Листинг 204.
Пример использования ограничения
внешнего ключа с опцией каскадного удаления
Если по внешнему ключу не определены никакие дополнительные ограничения, то любое количество строк в подчиненной таблице может ссылаться на одно и то же значение
первичного ключа. В этом случае устанавливается отношение
"один ко многим". Когда по внешнему ключу определено ограничение UNIQUE, лишь одна строка в подчиненной таблице может ссылаться на данное значение первичного ключа.
Таким образом устанавливается связь "один к одному" между
.первичным и внешним ключами. Для удаления таблицы, на
строки которой ссылаются строки другой таблицы, требуется
указание конструкции CASCADE CONSTRAINTS. Пример
удаления таблицы, для которой существует зависимая таблица, представлен в листинге 205.
SQL> DROP TABLE tabl;
DROP TABLE tabl ~.
*
ERROR at line 1:
ORA-02449: unique/primary keys in table referenced by foreign keys
SQL> DROP TABLE tabl CASCADE CONSTRAINTS;
Table dropped.
Листинг 205. Пример удаления таблицы, для которой
существует зависимая таблица
400
Средства обеспечения целостности данных в Oracle
Ограничение целостности, задаваемое предикатом, позволяет при вводе или модификации данных проверить принадлежность значения атрибута таблицы множеству допустимых значений или выполнение иного условия, задаваемого
предикатом. Синтаксис ограничения целостности, задаваемого предикатом, выглядит следующим образом:
CHECK (предикат)
Параметр предикат может быть любым предикатом,
определенным на множестве атрибутов таблицы.
Ограничение CHECK имеет следующие ограничения: оно
должно быть выражением, вычисляемым над значениями
вставляемой или обновляемой строки, не должно содержать
подзапросов и ссылаться на последовательности.
В листинге 206 представлен пример добавления ограничения целостности в таблицу ТаЫ. Попытка ввести данные,
не удовлетворяющие ограничению целостности, отвергается
системой. Ввод данных, для значений которых предикат принимает истинное значение, выполняется.
SQL> ALTER TABLE ТаЫ
2 ADD CONSTRAINT Atl_check CHECK ( A t l O ' W , 1 ) ;
Table -altered.
SQL> INSERT INTO Tab! VALUES ( ' W , 1) ;
INSERT INTO Tabl VALUES ( ' W , 1)
*
~\
ERROR.at line 1:
ORA-02290: check constraint (U1.AT1_CHECK) violated
SQL> INSERT INTO Tabl VALUES(NULL, 1);
1 row created.
Листинг 206. Пример использования ограничения целостности, заданного предикатом
-
401
Раздел б
По умолчанию проверка ограничений целостности происходит непосредственно при выполнении действий над данными. Однако в OracleS допускается так называемая отложенная проверка ограничений, которая предусматривает проверку при фиксации транзакции. Пример выполнения отложенной проверки ограничений целостности приведен в листинге 207.
SQL> CREATE TABLE Tabl (Atl INT UNIQUE
2 INITIALLY DEFERRED DEFERRABLE);
Table created.
SQL> INSERT INTO Tabl VALUES(1);
1 row created.
SQL> INSERT INTO Tabl VALUES(1);
1 row created.
SQL> COMMIT;
COMMIT
*
ERROR at line 1:
ORA-02091:' transaction rolled back
ORA-00001: unique constraint (Ul.SYS_C005885)
violated
Листинг 207. Пример выполнения отложенной провер-.
ки ограничений целостности.
Такая проверка удобна, например, при изменении значения первичного ключа для записи, у которой существуют
подчиненные записи в другой таблице. В этом случае можно
выполнить каскадное изменение значений ключей и зафиксировать транзакцию, что было невозможно в предыдущих версиях Oracle.
Для включения отложенной проверки ограничений требуется при определении таблицы указать следующую конструкцию:
402
Средства обеспечения целостности данных в Oracle
CONSTRAINT . . . [ { [[NOT] DEFERRABLE]
[INITIALLY {IMMEDIATE|DEFERRED}]
| [ I N I T I A L L Y {IMMEDIATE|DEFERRED}]
[[NOT] DEFERRABLE]} ]
По умолчанию ограничения целостности создаются не
откладываемыми. Для создания откладываемого ограничения
при его объявлении надо использовать ключевое слово
DEFERRABLE. Если транзакция не начинается с команды
SET CONSTRAINTS, то для откладываемого ограничения
Oracle использует стандартный алгоритм проверки. При этом
данные- проверяются на соответствие ограничению в конце
каждой команды DML. Если при определении ограничения
были использованы ключевые слова INITIALLY DEFERRED,
данные проверяются на соответствие ограничениям при фиксации транзакции.
При проведении массовых операций над данными иногда
целесообразно некоторые ограничения целостности отключить, провести операции, а затем опять включить ограничения.
Массовая загрузка данных
При создании базы данных обычно значительные объемы
данных загружаются из внешних источников. Одним из возможных вариантов решения этой задачи является подготовка
необходимого количества готовых операторов INSERT с подходящими значениями в поле VALUES. Но подобный прямолинейный подход может оказаться слишком дорогостоящим с
позиции подготовки данных и их загрузки, так как для каждого оператора будет выполняться синтаксический анализ.
Обычно применяется другая технология, основанная на массовой загрузке данных, предварительно подготовленных в
специальных форматах.
403
Раздел 6
При использовании такого подхода процесс загрузки
данных включает решение двух задач: собственно загрузка
данных и проверка достоверности загруженных данных.
Для загрузки данных предназначена утилита Oracle
SQL*Loader. SQL*Loader способен загружать данные самых
различных форматов. Кроме того, перед загрузкой записи
можно логически объединять и обрабатывать средствами языка SQL.
Для того чтобы запустить SQL*Loader, нужно набрать в
командной строке sqlldr (конкретное имя программы зависит
от поставки) и указать параметры загрузки данных.
Например,
D:\ORANT\BIN\SQLLDR80 USERID=system/manager§educ
CONTROL=l.ctl LOG=l.log
В качестве параметров здесь указан пароль и имя пользователя, который будет производить загрузку, управляющий
файл и файл протокола. Для настройки параметров загрузки
предназначен управляющий файл (control file). В нем указываются символьный набор, тип и способ размещения данных,
таблицы, в которые будет осуществляться загрузка и т. п. Параметры, которые обычно передаются SQL*Loader в командной строке, также могут быть указаны в управляющем файле.
Форматы данных, используемые при загрузке, могут быть
самыми различными — текстовые файлы с записями, dbfфайлы, файлы, загружаемые как LOB и т. п. Наиболее часто
используются следующие форматы: текстовые файлы с записями переменной длины и текстовые файлы с записями фиксированной длины.
Файлы с записями переменной длины включают записи
со значениями атрибутов, разделенных некоторыми стандартными разделителями (как правило, запятой). Строки разделяются стандартным разделителем. Значения атрибутов,
имеющих символьный тип, и даты, могут заключаться в
404
Средства обеспечения целостности данных в Oracle
двойные кавычки. NULL-значения, как правило, отображаются пробелом.
Для записей фиксированной длины позиции начала значений атрибутов строго фиксированы. То есть всех типов
данных начальные символы соответствующих значений располагаются с фиксированным смещением.
Пусть таблица Tab! создана следующим выражением:
CREATE TABLE Tabl (Atl NUMBER,
At2 NUMBER, At3 VARCHAR2(10));
Требуется загрузить в нее данные из файла 1 .dat, который
имеет такое содержимое:
1;Александр
2;Михаил
3;Мария
4;Ирина
Пример управляющего файла для загрузки записей переменной длины в таблицу ТаЫ представлен в листинге 208:.
LOAD DATA CHARACTERSET CL8MSWIN1251
INFILE ' l . d a t '
INTO TABLE Tabl
TRUNCATE
FIELDS TERMINATED BY ";"
TRAILING NULLCOLS •
(Atl INTEGER EXTERNAL,
At2 SEQUENCE ( M A X , 1 ) ,
At3 CHAR)Листинг 208. Управляющий файл для загрузки данных
переменной длины
После загрузки в таблице ТаЫ находятся следующие
данные:
'405
Раздел 6
SQL>, SELECT
ATI
1
2
/ 3
4
* FROM Tabl;
AT2 AT3
1
2
3
4
Александр
Михаил
Мария
Ирина
Листинг 209. Таблица Tab! после загрузки
Управляющий файл начинается с конструкции LOAD
DATA. Параметр INFILE определяет файл, в котором размещаются данные. Если данные находятся в нескольких файлах,
требуется последовательность параметров INFILE.
Параметр CHARACTERSET определяет кодировку символьных данных. При необходимости, в ходе загрузки данные
могут быть перекодированы.
Параметр INTO TABLE определяет таблицу, в которую
будут загружены данные. Таблица должна быть создана заранее. После названия таблицы указывается способ вставки в
нее записей: APPEND (записи добавляются в таблицу, которая, возможно, уже содержит данные), INSERT (перед загрузкой таблица не должна содержать записей), REPLACE (перед
загрузкой все записи в таблице удаляются с использованием
команды DELETE), TRUNCATE (перед загрузкой все записи
в
таблице
удаляются
с
использованием
команды
TRUNCATE).
Далее в управляющем файле следует перечисление атрибутов записей, накладываются на них логические условия,
приводятся ссылки на вложенные данные, специфицируется
использование встроенного генератора последовательностей,
И т. д. С полным списком параметров SQL*Loader можно ознакомиться в руководстве Oracle Utilities, Release 8.
В ходе загрузки SQL*Loader ведет протокол. Его расположение специфицируется параметром log командной строки.
406
Средства обеспечения целостности данных в Oracle
Протокол загрузки из предыдущего примера приведен в листинге 210.
SQL*Loader: Release 8.0.5.0.0 - Production on.Thu
Feb 14 13:54:29 2002 (c) Copyright 1998 Oracle
Corporation. All rights reserved.
Control. File:
l.ctl
Character Set CL8MSWIN1251 specified for all input .
Data File:
l.dat
l.bad
Bad File:
Discard File: none specified
(Allow all discards)
Number to load: ALL
'
Number to skip: 0
Errors allowed: 50
64 rows, maximum of 65536 bytes
Bind array:
Continuation:
none specified
Conventional
Path used:
Table TAB1, loaded from every logical record.
Insert option in effect for this table: TRUNCATE
TRAILING NULLCOLS option in effect
Column
ATI
AT 2
AT3
Position
r
Len Rerm Encl Datatype,
FIRST
*
NEXT
*
CHARACTER
SEQUENCE (MAX, 1)
CHARACTER
Table TABl:
4 Rows successfully loaded.
0 Rows not loaded due to data errors.
0 Rows not loaded because all WHEN clauses were
-failed.
0 Rows not loaded because all fields were null.
Space allocated for bind array: 65219 bytes(121
rows)
Space allocated for memory besides bind array:
0.bytes
407
Раздел 6
Total logical records skipped:
Total logical records read:
Total logical records rejected:
Total logical records discarded:
Run began on Thu Feb-14 13:54:29 2002
Run ended on Thu Feb 14 13:54:32 2002
Elapsed time was:
CPU time was:
0
4
0
0
00:00:03.10
00:00:00.00
Листинг 210. Протокол загрузки данных
При загрузке SQL*Loader производит проверку данных- в
две стадии. Сначала проверяется соответствие форматов и
типов данных в файле форматам и типам данных, указанным
в управляющем файле. Если какая-либо запись не удовлетворяет этому условию, то она отстраняется от загрузки и помещается в файл не прошедших проверку записей (Bad File). В
противном случае производится попытка вставки данных в
таблицы базы данных. При этом производится проверка ограничений целостности. Если данные не соответствуют им, то
они также отстраняются от загрузки и помещаются в файл
плохих записей. При достижении специфицированного количества ошибок загрузка прекращается. Число допустимых
ошибок регулируется параметром ERRORS (по умолчанию он
равен 50). В самом управляющем файле тоже могут быть наложены условия на значения атрибутов записей. Если записи
не удовлетворяют им, то они помещаются в файл некорректных данных (Discard File). Форматы обоих файлов идентичны
формату исходных файлов данных. Поэтому после отгрузки
их можно отредактировать и загрузить повторно.
Для получения значений числовых данных при загрузке
можно использовать встроенный генератор последовательностей SQL*Loader. Обратите внимание, этот генератор не имеет никакого отношения к последовательностям, хранимым-в
базе данных. Его использование не приводит к изменению их
состояний.
408
Средства обеспечения целостности данных в Oracle
Если возникает задача загрузки больших объемов данных
в короткие сроки, SQL*Loader может быть использован в режиме прямой загрузки. При этом способе формирование SQLоператоров INSERT не производится и будет проведено формирование блоков данных и их запись непосредственно в
файлы данных. Таким образом, достигается значительный
выигрыш в скорости загрузки. Режим прямой загрузки нельзя
использовать, если для данных существуют статические ограничения целостности. При проведении операции загрузки
рекомендуется отключить использование журналов регистрации транзакций для увеличения быстродействия.
Следует отметить, что загрузка данных из внешних источников или миграция из другой СУБД в большой степени
зависит от конкретной системы и должна тщательно настраиваться в соответствии с принятой стратегией для каждого
случая.
Экспорт/импорт данных
Одна из важных задач, решаемых администратором баз
данных, — обеспечение восстановления базы после аппаратного или программного сбоя. Решение задачи восстановления
данных может быть выполнено различными способами. В
качестве необходимой основы для выполнения операции восстановления должна быть некоторая логическая копия базы
данных.
Копия может содержать информацию обо всей или части
базы данных, звписанную на некоторый носитель с помощью
специальных утилит. Администратор баз данных должен регулярно, в соответствии с некоторым регламентом выполнять
контрольное копирование. Для критически важных и особо
ценных данных обычно поддерживается несколько копий базы.
Для реализации экспорта/импорта данных предназначены
утилиты Oracle IMPORT и EXPORT. Результат экспорта
409
Раздел 6
представляет собой совокупность файлов в бинарном формате, поддерживаемом Oracle. По умолчанию создается файл с
именем expdat.dmp.
Эти утилиты могут быть использованы для создания резервных копий базы данных, перемещения объектов и данных
между схемами (то есть тиражирования таблиц, индексов,
привилегий, хранимых программ и других объектов в другие
схемы и другие базы данных Oracle), для дефрагментации
табличного пространства (достаточно экспортировать данные, а затем импортировать их обратно). Важной особенностью является то, что результат экспорта является платформонезависимым и может быть использован для серверов, работающих под управлением различных операционных систем.
Имеется два способа работы с этими утилитами — интерактивный и автоматический. При первом способе пользователь непосредственно задает параметры экспорта/импорта,
отвечая на вопросы в диалоговом режиме. При втором способе параметры считываются из предварительно созданных
файлов. Следует отметить, что второй способ более гибкий,
так как позволяет специфицировать параметры, которые не
запрашиваются в диалоговом режиме.
Для запуска утилиты экспорта необходимо в командной
строке набрать команду ехр80 (конкретное имя программы
зависит от операционной системы и версии Oracle). В этом
случае утилита перейдет в интерактивный режим и будет запрошена информация, необходимая для подключения к базе
данных. Существует три вида экспорта:
— FULL — экспортируются все объекты, структуры и
данные в пределах базы данных. При экспорте данного вида
экспортируются и табличные лространства. При этом необходимо,
чтобы
пользователь
обладал
ролью
EXP_FULL_DATABASE. По умолчанию этой ролью обладает
пользователь SYSTEM;
410
Средства обеспечения целостности данных в Oracle
— OWNER — экспортируются только объекты, принадлежащие указанному пользователю (объекты его схемы);
—- TABLE —экспортируются только указанные таблицы
и секции секционированных таблиц, к которым имеется доступ.
После подключения к базе данных утилита экспорта
предлагает выбрать тип экспорта, имя файла, в который будут
экспортироваться данные и указать еще ряд параметров,
влияющих на производительность.
D:\ORANT\BIN\EXP80.EXE
Export: Release 8.0.5.0.0 - Production on Thu Feb
14 15:21:54 2002
(c) Copyright 1998 Oracle Corporation. All
rights reserved.
Username: system/manager@educ
Connected to: OracleS Enterprise Edition Release
8.0.5.0.0
Production
15:
With the Objects option
PL/SQL Release 8.0.5.1.0 - Production
Enter array fetch buffer size: 4096 > 4096
Export file: EXPDAT.DMP > EXPDAT.DMP
(l)E(ntire database), (2)U(sers), or (S)T(ables):
(2)U > Т
Export table data (yes/no): yes > yes
Compress extents (yes/no): yes > yes .
Export done in CL8MSWIN1251 character set and
CL8MSWIN1251 NCHAR character set
About to export specified tables via Conventional
Path ...
Table(T) or Partition(Т:Р) to be exported: (RETURN to quit) > TAB1
411
Раздел 6
' . . exporting table
TAB1
4 rows exported
Table(T) or Partition(Т:Р) to be exported: (RETURN to quit) >
Export terminated successfully without warnings.
Листинг 211. Использование утилиты экспорта в интерактивном 'режиме
•
Для автоматического режима параметры экспорта специфицируются в специальном файле, название которого передается утилите EXPORT в командной строке.
D:\ORANT\BIN\EXP80.EXE USERID=system/manager@educ
PARFILE=exp.par
Рассмотрим структуру файла параметров экспорта с базовым набором параметров. Полный список параметров файлов
утилиты EXPORT, а также дополнительная информация для
пользователя представлены в руководстве Oracle Utilities,
Release 8.
Параметр INCTYPE=(COMPLETE | CUMULATIVE |
INCREMENTAL) — указывает тип экспорта (инкрементальный, кумулятивный или полный). При полном экспорте экспортируется вся база данных. При инкрементальном — только те таблицы базы данных, которые изменялись с момента
последнего инкрементального экспорта. В том случае, если
такой экспорт не проводился, экспортируются те таблицы,
которые изменились, начиная с последнего кумулятивного
экспорта. При кумулятивном экспорте обрабатываются все
таблицы, изменившиеся с момента последнего полного экспорта. С помощью гибкой стратегии создания файлов экспорта различных типов достигается возможность гарантированного восстановления базы данных на некоторый момент времени и экономия пространства для хранения копий.
412
Средства обеспечения целостности данных в Oracle
Параметр ТАВЬЕ8=с«мсок_/яаблмг/ определяет, какие
таблицы и секции следует экспортировать. Этот параметр используется для табличного вида экспорта.
Параметр COMPRESS (Y/N) определяет, изменять ли
сценарий создания таблиц при импорте так, чтобы после импортирования существовал один экстент.
Параметр INDEXES (Y/N) определяет, создавать ли индексы при последующем импорте. Следует отметить, что индексы, которые автоматически создаются Oracle, например
индексы, ассоциированные с первичными ключами, экспортируются независимо от значения этого параметра.
Параметр STATISTIC (Y/N) определяет, собирать ли статистику для оптимизатора после импорта.
Параметр L,OG=mtx_(pawia определяет нахождение файла, в который будет осуществляться вывод протокола экспорта.
Параметр CONSISTENT (Y/N) — экспортировать ли данные на момент экспорта. В противном случае в резервной копии будут данные, которые изменялись в течение экспорта.
По умолчанию устанавливается N.
Параметр USERID требуется для подключения к базе
данных. В целях безопасности рекомендуется передавать его
в командной строке, а не указывать в файле параметров. Задается как имя_пользователя/паролъ@строка_связи.
Параметр ROWS (Y/N) — будут ли экспортироваться
данные таблиц и объектов. В противном случае будут экспортированы только определения объектов.
Параметр FlLE=uMxjpaivia, в который осуществляется
экспорт.
Параметр РАКР1ЬЕ=иуия_фаша — файл, из которого будут считываться параметры.
Параметр GRANTS (Y/N) — будут ли экспортироваться
привилегии для объектов.
Экспортируемые данные могут быть не только содержимым одной или нескольких таблиц базы данных, но и резуль413
Раздел 6
татом любого синтаксически правильного запроса. Пример
файла параметров приведен в следующем листинге.
USERID=system/manager@educ
LOG=export.log
FILE=expdat.dmp
TABLES=Tabl
INDEXES=N
Листинг 212. Файл параметров экспорта
Протокол этой операции представлен в листинге 213.
Connected to: OracleS Enterprise Edition Release
8.0.5.0.0 Production .
With the Objects option
PL/SQL Release 8.0.5.1.0 - Production
Export done in CL8MSWIN1251 character set and
CL8MSWIN1251 NCHAR"character set
Note: indexes on tables will not be exported
N
About to export specified tables via Conventional
Path .,.
. . exporting table
TAB1
4 rows exported
Export terminated successfully without warnings.
Листинг 213. Протокол экспорта
Для восстановления базы данных 'с использованием резервных копий, созданных утилитой EXPORT, служит утилита IMPORT. Во многом порядок работы с ней аналогичен работе с EXPORT, но вместе с тем имеется ряд особенностей.
Для запуска IMPORT необходимо в командной строке
набрать impSO и далее указать необходимые параметры.
414
Средства обеспечения целостности данных в Oracle
D:\ORANT\BIN\imp80 USERID=system/manager@educ
FILE=expdat.dmp
Аналогично EXPORT, утилита IMPORT поддерживает
три режима экспортирования (в зависимости от заданных параметров). Виды операции для экспорта и импорта, естественно, совпадают. Существенное различие состоит лишь в
том, что для импорта вида FULL требуется наличие роли
IMP_FULL_DATABASE.
Рассмотрим синтаксис команды разгрузки данных с базовым набором параметров. Полный список параметров файлов
утилиты IMPORT, а также дополнительная информация представлены в руководстве Oracle Utilities, Release 8.
Параметр ANALYZE (Y/N) — проводить ли для импортируемых таблиц сбор статистики для оптимизатора.
Параметр ¥1ЪЕ=имя_фаша, в котором находятся импортируемые объекты базы данных.
Параметр INDEXES (Y/N) — создаются ли индексы для
импортируемых таблиц.
Параметр ТАВЕЕ8=сямсол:_/ийгблмг/ — список таблиц (через запятую) или секций секционированных таблиц, которые
буду импортированы. Для Windows список таблиц требуется
заключить в скобки.
Параметр USERID требуется для подключения к базе
данных. Имеет вид имя_полъзователя/пароль@строка_связи.
В целях безопасности рекомендуется передавать его в командной строке, а не указывать в файле параметров. ,
Параметр TOUSER — пользователь, в схему которого
будет произведен импорт.
Параметр FROMUSER — импортируются те объекты,
владельцем которых является этот пользователь.
Параметр LOG определяет нахождение файла, в который
будет осуществляться вывод протокола экспорта.
Виды
импорта
устанавливаются
параметрами
FROMUSER, TABLES, FULL. В режиме владельцев импортируются таблицы, владельцем которых является указанный
415
Раадел 6
пользователь. В режиме таблиц импорт» >уются указанные
таблицы. По умолчанию данные импортируются в схему выполняющего импорт пользователя.
Пример файла параметров импорта представлен в листинге 214.
USERID=system/manager@educ
FILE=expdat4 dmp
TABLES=(Tab!,Tab2)
INDEXES=n
LOG=import.log
Листинг 214. Файл параметров импорта
В процессе импорта данных все действия производятся в
определенной последовательности. Сначала создаются таблицы, потом в них загружаются данные, затем создаются или
перестраиваются индексы. Ограничения целостности для всех
таблиц включаются в последнюю очередь.
Остальные объекты базы данных (последовательности,
представления, хранимые программы и т. д.) экспортируются
и импортируются без изменений.
416
Раздел 7
Методы повышения
производительности
Под управлением сервера Oracle могут храниться и обрабатываться значительные объемы данных. Управление большими и сверхбольшими базами данных, проектирование и
разработка приложений для них имеет свои особенности. Поэтому, чтобы не допустить ухудшения характеристик как отдельных приложений, так и всей системы в целом, требуется
использование специальных методов, повышающих скорость
доступа к данным.
Как правило, используется комплексный подход. Под
этим понимается оптимизация всех звеньев системы — серверной, клиентской и сетевой части. Существует целый ряд
способов настройки производительности: настройка рабочих
станций клиентов, сетевого транспорта, оптимизация клиентских приложений, оптимизация серверного PL/SQL-кода и
SQL-выражений. Для настройки клиентских компьютеров и
сети требуется обновление аппаратной части и системного
программного обеспечения. Для улучшения работы клиентских приложений необходимо переработать их исходный код,
как правило, написанный на языке программирования высокого уровня, или применить специальные средства оптимизации программ для конкретной аппаратной конфигурации. Та417
14. Заказ № 1628.
•
- -
.
.
Раздел 7
кие средства есть практически во всех современных интегрированных средах разработки.
Для оптимизации серверной части необходима настройка
параметров базы данных Oracle, перепроектирование структуры базы данных и переработка серверного кода. Настройку
базы данных обычно выполняют администраторы Oracle на
основе статистики из словаря данных, а перепроектирование
и переработку серверного кода — производители приложений.
Далее будут рассмотрены вопросы оптимизации взаимодействия с сервером базы данных с помощью SQLвыражений. Объясняется это тем, что, как показывает опыт,
это наиболее "узкое" место. По разным оценкам, общая производительность системы на 15-20% зависит от настройки
базы данных, а остальные 80-85% приходятся на приложение. Поэтому, прежде всего, требуется настроить приложение
в процессе его создания.
Оптимизатор
В разделе "Архитектура распределенных систем обработки данных" рассматривалась последовательность прохождения оператора SQL через архитектуру сервера Oracle. После
этапа синтаксического анализа на основе информации из словаря базы данных для разобранного оператора создается план
его выполнения. Эту работу выполняет оптимизатор.
Оптимизатор представляет собой программный продукт,
который является важнейшей частью сервера Oracle и предназначен для оптимизации — поиска наиболее эффективного
способа доступа к данным. Оптимизатор должен выбрать такую последовательность действий, которая обеспечит самый
эффективный путь доступа к данным, и сформировать план
выполнения запроса, основанный на найденных методах доступа. Под методом доступа (access path) подразумевается
вариант алгоритма доступа, а под планом выполнения
418
Методы повышения производительности
(execution plan) — последовательность выполняемых действий, которые обеспечивают выбранные методы доступа. Существует два основных вида оптимизаторов:
Оптимизатор по правилам (rule-based) — оптимизатор,
основанный на анализе жестко заданных правил. Этот оптимизатор выбирает методы доступа на основе предположения
о статичности базы данных и в соответствии с заданной системой правил выбора методов доступа.
Оптимизатор по стоимости (cost-based optimizer) — оптимизатор, основанный на анализе накладных затрат системы. Для этого оптимизатора выбор метода доступа основан
на хранимой внутренней статистике. Под статистикой понимаются точные или аппроксимированные сведения о распределении значений данных в таблицах. Сервер Oracle может
собирать статистику двумя способами: путем оценки, основанной на произвольной выборке данных, и путем точных
вычислений.
Для управления оптимизатором используются специализированные подсказки (hint), которые записываются в SQLвыражениях. Подсказки влияют на выбор сервером конкретного способа обращения к данным. Представленный в листинге 215 пример содержит выражение SELECT, включающее подсказку оптимизатору для использования индекса.
Здесь предполагается, что для указанной таблицы существует
только один индекс. Для задания в подсказке конкретногр
индекса из нескольких имеющихся следует использовать имя
таблицы и имя нужного индекса.
SQL> SELECT /*+ index*/ At2,At3
2 FROM Tab! WHERE Atl=10;
Листинг 215. Запрос с подсказкой для оптимизатора
Подсказка является частью комментария, следующего
сразу же после начала оператора SQL (ключевых слов
419
14*
Раздел 7
DELETE, UPDATE, SELECT), и обозначается символом "+".
после конструкции, начинающей комментарий. В предыдущем примере подсказка начинается с символов "/*", за которыми следуют символы "+", пробел и заканчивается символами "*/". Пример другой записи подсказки приведен в листинге 216.
SQL> SELECT --+ index
2 At2, At3 FROM Tabl WHERE Atl=10;
Листинг 216. Другой способ записи подсказки
Оптимизатор воспринимает только один набор подсказок,
оформленный как комментарий, для данного SQL-выражения
или блока выражений. Например, для составного запроса, состоящего из двух подзапросов, объединенных оператором
UNION, подсказка в первом выражении будет учитываться,
при формировании плана только для него и не будет учитываться для второго. Подсказки с неверным синтаксисом игнорируются, начиная с места ошибки.
Ранжирование методов доступа
Интуитивно понятно, что обращение к данным с использованием различных методов доступа будет отличаться как по
применяемым механизмам, так и по времени и эффективности. Оптимизатор Oracle при работе использует ранги методов доступа. Таблица 32 содержит список рангов методов
доступа в порядке эффективности: от самого быстрого до самого медленного.
420
Методы повышения производительности
Таблица 32. Методы доступа оптимизатору
Ранг
1
2
3
4
5
6
7
8
9
10
И
12
13
14
15
Метод доступа
Одна строка по ее идентификатору (по ROWID)
Одна строка по объединению кластеров
Одна строка по хэш-ключу кластера с
уникальным или первичным ключом
Одна строка по уникальному или первичному
ч
ключу^
Объединение кластеров
Ключ хэш-кластера
Ключ индексированного кластера
Составной индекс
Индекс на основе одного столбца
Ограниченный диапазон поиска по
индексированным столбцам
Неограниченный диапазон поиска по
индексированным столбцам
Соединение через сортировку слиянием
Поиск максимального или минимального
значения по индексированным столбцам
Упорядочение по индексированным столбцам
Полное сканирование таблицы
Таким образом, если оптимизатор основан на анализе
правил, то он будет выбирать из всех доступных для данного
запроса планов выполнения наиболее эффективный, опираясь
на возможные методы доступа и ранги этих методов. С помощью некоторых изменений записи выражений SQL можно
способствовать более удачному выбору метода доступа. Пример в листинге 217 содержит тот же запрос, что и в предыдущем примере, но с измененным оператора критерием отбора
данных.
421
Раздел 7
SQL> SELECT —+ index
2 A t 2 , A t 3 FROM Tabl WHERE Atl>45612367;
Листинг 217. Запрос с указанием неограниченного
диапазона поиска
При использовании стратегии, основанной на анализе
правил, и наличии первичного ключа — столбца Atl, для выполнения этого запроса будет применен метод доступа II
(неограниченный диапазон поиска по индексированным
столбцам).
Если критерий запроса содержит ограниченный диапазон
поиска (т. е. содержит два условных оператора — по одному с
каждой границы диапазона), то обе границы диапазона будут
известны еще во время синтаксического анализа выражения.
Превратить неограниченный диапазон в ограниченный можно
с помощью указания максимального значения (если оно известно) или с помощью предполагаемого (гипотетического)
максимального значения для столбца, исходя из априорных
знаний о данных. Например, сделать это так:
SQL> SELECT At2,At3 FROM Tabl
2 WHERE Atl>45612367 AND Atl<99999999;
Листинг 218. Использование ограниченного диапазона поиска с указанием гипотетического максимума
422
Методы повышения производительности
Анализ запросов
с целью повышения скорости
их выполнения
Изменение SQL-выражений на основе знаний о данных,
индексах, связях таблиц для повышения эффективности их
выполнения,
называется
коррекцией
запросов (query
rewriting). Изменение предложений SQL отличается от написания новых предложений. Для того чтобы эффективно переписывать запросы, необходимо в течение некоторого времени
накопить знания о системе. Сюда относятся сведения о том,
какие предложения SQL нуждаются в переписывании в связи
с их частым использованием или использованием ими значительных ресурсов, какие данные ими обрабатываются, каковы
характеристики и распределение этих данных, какие логические условия в выражениях можно убрать или трансформировать в связи с логикой функционирования системы. При решении задач оптимизации проблемных запросов необходимо
следовать следующим рекомендациям:
Во-первых, при необходимости доступа к значительной
части строк какой-либо таблицы полное сканирование (full
scan) является более эффективным, чем использование индексов. Граница применения данных методов доступа в общем случае составляет 5-10% записей таблицы, к которым
обращается запрос. Дело в том, что для сканирования индекса
и извлечения строки требуются, по крайней мере, две операции чтения для каждой строки (одна — для чтения индекса,
другая для чтения данных из таблицы). А при полном сканировании таблицы для извлечения строки требуется только
одна операция чтения. При доступе к большому количеству
строк становится очевидной неэффективность использования
индекса по сравнению с полным сканированием таблицы, при
котором строки считываются непосредственно из таблицы.
423
Раздел 7
Для небольших таблиц полное сканирование практически
всегда оказывается эффективнее использования индекса.
Во-вторых, на различных этапах выполнения запросов
следует максимально использовать результаты предыдущих
этапов. Например, если результирующий набор данных требуется отсортировать по значениям некоторого столбца, то
при выполнении операции соединения таблиц можно указать
способ выполнения этой Операции, при котором будет проведена сортировка этих значений. Полученные результаты будут использованы при окончательной сортировке.
В-третьих, при использовании различных видов подзапросов на основе знаний о данных следует учитывать особенности вычисления специальных предикатов и применения
операторов теоретико-множественных операций. Например,
оператор MINUS может выполняться гораздо быстрее, чем
запросы с WHERE NOT IN (SELECT) или WHERE NOT
EXISTS.
Помимо таких, достаточно очевидных, способов улучшения качества запросов можно использовать другие. Как правило, на основе опыта работы с конкретной базой данных у
каждого пользователя формируется свой стиль написания оптимальных SQL-выражений. При этом существуют объективные средства определения качества запроса. В первую очередь к ним относится трассировка.
Задание режима оптимизации
Одним из важнейших вопросов при работе с оптимизатором является выбор режима его работы. Описанные выше виды оптимизации могут быть заданы на уровне экземпляра,
сессии или SQL-выражения. Указание режима оптимизации
на уровне экземпляра осуществляют администраторы баз
данных с помощью параметров инициализации экземпляра.
Для указания режима оптимизации на уровне сессии следует
424
Методы повышения производительности
использовать выражение следующего вида: ALTER SESSION
SET ОРТ1МКЕК_ООАЬ=<режим>;
Заданный таким образом режим оптимизации будет использоваться только для данной сессии, при начале другой
его требуется указать вновь. В качестве режима оптимизатора
может быть задано одно из следующих значений:
"CHOOSE" —при указании этого значения будет выбрана стоимостная оптимизация, основанная на анализе затрат. В
противном случае будет использована оптимизация, основанная на анализе правил.
"RULE" — при указании этого значения будет использована оптимизация, основанная на анализе правил. Следует
отметить, что при указании только этого значения (или соответствующей подсказки) будет использован оптимизатор по
правилам.
"FIRST_ROWS" — это значение используется для минимизации времени отклика, то есть для сведения к минимуму
временного интервала между началом выполнения запроса и
появлением результатов на экране. Это значение следует использовать в системах, где критичным является время реакции. Оптимизатор игнорирует эту подсказку для предложений DELETE и UPDATE, а также в тех предложениях
SELECT, которые содержат хотя бы одну конструкцию вида
UNION, INTERSECT, MINUS, UNION ALL, GROUP BY, FOR
UPDATE, DISTINCT или групповые функции. Как уже отмечалось ранее, при вычислении этих выражений неявно производится сортировка и будет извлечен весь набор данных.
"ALL_ROWS" — при указании этого значения будет использована оптимизация, основанная на анализе затрат (при
наличии соответствующих статистических данных) для минимизации общего количества строк, обрабатываемых системой за единицу времени (в транзакциях за секунду). Это значение следует использовать в высокопроизводителЁных системах пакетной обработки. Например, рассмотрим предложение соединения таблиц, которое может быть выполнено либо
операцией вложенных циклов, либо операцией сортировки425
• .
Раздел 7
слияния. Операция сортировки-слияния быстрее возвратит
весь результат запроса, тогда как операция вложенных циклов может быстрее возвратить первую строку. Поэтому, если
целью является лучшая пропускная способность, оптимизатор
скорее выберет соединение через сортировку-слияние.
Если в запросе указана подсказка ALL_ROWS или
FIRST_ROWS, но словарь данных не содержит статистики
для таблиц, перечисленных во фразе FROM, то оптимизатор
воспользуется сведениями о параметрах хранения этих таблиц, чтобы оценить статистику и на этой основе выбрать план
исполнения. Для задания режима оптимизации на уровне выражения следует использовать ключевые слова методов доступов, которые содержит таблица 33, либо использовать одно
из приведенных выше значений (CHOOSE, RULE,
FIRST_ROWS, ALL_ROWS). При использовании в SQLвыражении любой подсказки, отличной от RULE, осуществляется автоматический выбор оптимизатора по стоимости!
Таблица 33. Подсказки, специфицирующие метод доступа
Подсказка
ROWID
CLUSTER
HASH
INDEX
INDEX_ASC
INDEX_DESC
INDEX FFS
AND_EQUAL
FULL
426
Описание
Использование идентификатора.
Сканирование ключа кластера.
Сканирование хэш-индекса.
Сканирование индекса.
Сканирование индекса в порядке возрастания.
Сканирование индекса в порядке убывания.
Быстрое полное сканирование индекса.
Использование нескольких индексов со
слиянием результатов.
Полное сканирование таблицы.
Методы повышения производительности
Обзор индексов Oracle
Понятие индекса было введено при изложении назначения основных объектов базы данных Oracle. Напомним, что
индекс — это объект базы данных, предназначенный для повышения производительности при проведении выборки данных. Цель использования индекса состоит в том, чтобы получить требуемые в запросе данные более эффективным, по
сравнению с полным просмотром таблицы, способом. Индексы улучшают производительность тех запросов, которые выбирают небольшой процент строк из таблицы с помощью относительно простых условий во фразе WHERE. Индексировать целесообразно лишь столбцы, обладающие высокой селективностью.
Селективность (selectivity) столбца — это процент строк,
имеющих одинаковое значение для индексированного столбца. Селективность столбца высокая, если мало строк имеют
одинаковые значения для этого столбца. Oracle автоматически создает индексы для первичных ключей или столбцов,
для которых существует ограничение на уникальность значений. Эти индексы наиболее эффективны (что видно из таблицы рангов методов доступа). Столбцы с мало различающимися значениями имеют низкую селективность. Отметим важный факт — если для индексированного столбца логическое
условие накладывается не на значение столбца, а на результат
некоторой функции от него, то этот индекс не используется.
Индексы бывают двух видов — простые и составные. Составной индекс — это индекс, включающий более чем один
столбец. Можно совместно проиндексировать два или более
столбца, каждый из которых обладает низкой селективностью, а пара их значений — высокой. Если все столбцы, используемые запросом, входят в составной индекс, то обращения к таблицам можно вовсе избежать — вся данные будут
считаны только из индекса. Для эффективного использования
составного индекса необходимо, чтобы логические условия
427
Раздел 7
были наложены на ведущие столбцы индекса, то есть на те
столбцы, которые были указаны первыми при создании индекса.
В индексах хранятся значения из одного или нескольких
стоЛ*бцов таблицы и значения ROWID для каждого из хранимых значений столбца (столбцов). Сервер Oracle, чтобы найти
строку в таблице по заданному значению столбца, ищет соответствующие ROWID в индексе и затем сразу переходит к
указанным ими строкам в таблице. В Oracle имеется несколько типов индексов:
— двоичные древовидные индексы (В*-Тгее-индексы);
— хэшированные индексы (hash);
— двоичные масочные индексы (bitmap).
В*-Тгее-индексы были реализованы в Oracle практически
с самого начала. Хэшированные индексы появились в Oracle
7.0. Двоичная индексация была реализована в Oracle 7.3. В
OracleS введены секционированные индексы и индекстаблицы. Понимание того, когда и где следует использовать
конкретные типы индексов, очень важно для эффективного
их применения. В*-Тгее-индексы используются наиболее часто, в то время как хэшированные и двоичные масочные индексы лишь при наличии некоторых условий могут обеспечить существенные преимущества в выполнении определенных запросов. Далее рассматривается, как работают индексы,
а также приводятся рекомендации, в каких случаях и почему
их следует использовать.
В*-Тгее-индекс содержит по одному индексному элементу для каждой строки таблицы, в которой имеется непустое
(NOT NULL) индексное значение. В*-Тгее-индекс состоит из
блоков-ветвей, которые содержат значения индекса и адреса
- или других блоков-ветвей, или блоков-листьев. Листовые
блоки содержат значения индекса и идентификаторы строк
(ROWID). Листовые блоки образуют дважды связанный список, так что листья могут просматриваться в любом направ428
Методы повышения производительности
лении (как по возрастанию, так и по убыванию значений индексного столбца). Oracle автоматически балансирует глубину дерева так, чтобы все листовые блоки были на одной и той
же глубине, и поэтому для доступа к ним требовалось бы одно и то же число операций чтения. Однако сбалансированное
дерево автоматически не уравновешивает распределение
ключей в пределах дерева так, чтобы половина ключей находилась бы на одной стороне В*-Тгее-индекса, а другая половина — на другой. Очевидно, что нет необходимости перестраивать дерево всякий раз, когда добавляются или удаляются ключи. Однако если ключи добавляются или удаляются
только на одной стороне дерева, то распределение индексных
ключей может стать неравномерным, с изрядным числом разреженных и даже опустошенных блоков по одну сторону дерева. В этом случае индекс рекомендуется перестроить.
На В*-Тгее-индексах для извлечения данных по запросу
может использоваться механизм быстрого полного просмотра (fast full scan). Этот механизм дает существенные преимущества, если все запрошенные из конкретной таблицы данные могут быть получены только из индекса. При быстром
полном просмотре эффективный многоблочный ввод/вывод,
обычно применяемый для полных просмотров таблиц, используется для прочтения всех листовых блоков В*-Тгееиндекса. Поскольку число листовых блоков индекса, скорее
всего, намного меньше, чем блоков данных в таблице, для
выполнения запроса требуется просмотреть меньшее число
блоков. Поэтому просмотр индекса совершится значительно
быстрее, чем полный просмотр таблицы, хотя иногда неравномерное распределение ключей снижает эффективность быстрого полного просмотра, поскольку требуется просмотреть
большее число листовых блоков (содержащих малое или вообще нулевое число элементов). При этом следует учитывать
наличие или отсутствие в таблице пустых значений, которые,
как было сказано выше, в индекс не заносятся. *
В*-Tree-индексы можно использовать для поиска данных
как по условиям равенства, так и по условиям неравенства.
429
Раздел 7
Это единственный тип индексов, который можно использо-.
вать для предикатов неравенства: LIKE, BETWEEN, ">", ">=",
"<", "<=". Исключение представляет случай использования
предиката LIKE при сравнении с шаблоном вида '%выражение' или '_выражение\ Хэшированные и двоичные масочные индексы работают только с предикатами равенства. В*Tree-индексы хранят только непустые значения ключей, так
что можно построить разреженный В*-Тгее-индекс.
Хэшированные индексы реализованы в Oracle в виде хэшированных кластеров. Хэшированный кластер — специализированный вид организации данных, обеспечивающий быстрый доступ к строкам таблицы. При обращении к хэшированному кластеру по значению кластерного ключа применяется
функция хэширования (hashing), результатом которой являются значение хэшированного ключа и адрес блока данных.
Хэшированный кластер группирует в одном блоке строки,
содержащие одинаковые значения этой функции от ключей.
На любой таблице можно построить только один хэшированный индекс.
Доступ к таблице посредством В*-Тгее-индекса требует
выполнения, по меньшей мере, двух операций ввода/вывода,
а обычно больше (если таблица, а потому и дерево ее индекса, большая). Доступ к хэшированному кластеру потребует
один вызов функции хэширования и одну операцию ввода/вывода для кластера.
Хэшированные кластеры целесообразно использовать для
больших таблиц, поиск по которым, как правило, осуществляется с условиями равенства по ключевому столбцу (столбцам). При этом значения ключей не модифицируются. Поэтому заранее можно точно определять число значений хэшированных ключей и размер кластера. В дополнение к этому,
ключевой столбец (столбцы) должен быть высокоселективен.
Главным преимуществом хэшированного индекса по
сравнению с В*-Тгее-индексом является лучшая производительность выборки, вставки, обновления и удаления записей,
430
Методы повышения производительности
если используются условия равенства для всех ключевых
столбцов кластера.
Двоичные масочные индексы обеспечивают быстрое обращение к данным больших таблиц, когда доступ организуется по столбцам с низкой или средней селективностью с использованием различных сочетаний условий равенства. Двоичный масочный индекс построен в виде двоичной карты
(bitmap) по значениям ключа. Это означает, что для каждой
строки таблицы в двоичной карте, то есть в определенном
бите некоторой последовательности байтов, поставлена 1 или
О ("да" или "нет") в соответствии со значением ключа конкретной строки. Например, если столбец содержит кодируемые значения и размерность множества возможных значений
не очень большая (скажем, цвета или ученые звания и степени).
Двоичные масочные индексы целесообразно использовать для таблиц, к которым обращаются от случая к случаю.
Также двоичные масочные индексы целесообразно применять, когда запросы содержат фразу WHERE с несколькими
условиями равенства, относящимися к низко и средне селективным столбцам.
Двоичные масочные индексы меньше по объему, чем В*Тгее-индексы, и значительно меньше по сравнению с хэшированными кластерами. Двоичные масочные индексы не следует строить по столбцам с высокой селективностью. В этом
случае целесообразно, использовать хэшированные или В*Tree-индексы. Двоичные масочные индексы можно использовать для поиска только по условиям равенства ("=", IN). Если
необходим доступ по интервалу индексированных значений,
то предпочтительнее использовать В*-Тгее-индексы.
Отметим, что возможности по управлению индексами в
OracleS значительно расширены и допускается указание нескольких десятков параметров, специфицирующих тип, свойства индексов, способ их построения, хранения и т. п. Оператор создания индекса использует следующий синтаксис:
431
Раздел 7
CREATE [UNIQUE I BITMAP]
INDEX
[имя_схемы. ]имя_индекса
ON {CLUSTER [имя_схемы.]имя_кластера
} | { [имя_схемы. ] имя_таблицы ( имя_столбца , [-••])}
Проиллюстрируем использование оператора CREATE
INDEX для создания индексов различных типов для таблицы
ТаЬ2, созданной следующим выражением:
CREATE TABLE Tab2 (Atl"NUMBER, At2 DATE,
At3 NUMBER CHECK (At3 IN (1,3,5,7)));
Протокол взаимодействия с системой представлен в листинге 219.
— создадим В*-Тгее-индекс для столбцов Atl, At2
SQL> CREATE INDEX Tab2$Atl$At2 ON Tab2 (Atl,At2);
Index created.
— создадим еще один В*-Тгее-индекс для Atl, At3
SQL> CREATE INDEX Tab2$Atl$At3 ON Tab2 (Atl,At3);
Index created.
— создадим еще один индекс
-- для уже индексированных столбцов
SQL> CREATE INDEX Tab2$Atl$At3_2
2 ON Tab2 {Atl, At3') ;
CREATE INDEX Tab2$Atl$At3_2 ON Tab2 (Atl,At3)
*
ERROR at line 1:
ORA-01408: such column list already indexed
— создадим масочный индекс для столбца At3
SQL> CREATE BITMAP INDEX Tab2$At3 ON Tab2(At3);
Index created.
Листинг 219. Примеры создания различных индексов
- (В*-Тгее и масочного)
432
Методы повышения производительности
Для изменения индексов используется оператор ALTER
INDEX. С его помощью можно изменить параметры хранения
индексов или перестроить их после интенсивных операций по
вводу, модификации и удалению данных. Пример перестройки индекса приведен в листинге 220.
SQL> ALTER INDEX Tabl$Atl$At2 REBUILD;
Index altered.
Листинг 220. Пример изменения индекса с помощью
оператора ALTER INDEX
Для удаления индекса используется оператор "DROP
INDEX. Оператор удаления индекса Oracle использует следующий синтаксис:
DROP INDEX [имя_схемы.]имя_индекса
Пример удаления индекса приведен в листинге 221. Естественно, на данные в таблице удаление индекса никакого
влияния не оказывает.
SQL> DROP INDEX
Index dropped.
Tabl$Atl$At2;
Листинг1 221. Пример удаления индекса оператором
DROP INDEX
Эффективное кодирование
SQL-выражений
Почти все типичные проблемы, возникающие при настройке производительности, связаны с неэффективным ко433
Раздел 7
дированием SQL-выражений либо с неоптимальным использованием индексов.
Одной из наиболее очевидных проблем эффективного
кодирования SQL-выражений является следующая. Если заранее известно, что запросом будет возвращено большое количество строк таблицы, то более целесообразным является
использование такого метода доступа, как полное сканирование (особенности использования полного сканирования таблиц рассматривались в предыдущих параграфах). Другая
проблема заключается в избыточном сканировании и может
быть проиллюстрирована в приведенном ниже примере. Требуется выполнить два запроса:
SELECT Atl FROM Tab! WHERE Atl>9;
SELECT At2/Atl FROM Tabl WHERE Atl>9;
Очевидно, что требуемые результаты могут быть получены с помощью одного сканирования:
SELECT Atl,At2/Atl FROM Tabl WHERE Atl>9;
Также не следует выбирать данные из таблицы, если
идентичные сведения можно вывести каким-то другим способом. Следует руководствоваться следующим общим правилом: лучше пожертвовать расходами на дополнительное вычисление, чем на дополнительные операции с устройствами
хранения. Исключение составляют выражения, в которых
большое число раз вызываются встроенные функции SQL
(значения которых вычисляются для каждой строки больших
таблиц или их соединений). В этом случае следует пересмотреть выражение и исключить лишние вызовы.
Особенно внимательно следует отнестись к использованию операторов DISTINCT, ORDER BY и UNION, поскольку
при выполнении этих операций происходит создание временных таблиц с дополнительными накладными расходами на
выполняемую сортировку. При необходимости использования
434
•
Методы повышения производительности
оператора DISTINCT желательно сохранять результаты его
выполнения для последующего использования. Вместо оператора UNION рекомендуется применять оператор UNION
ALL (если это допускается логикой запроса), при использовании которого не выполняется исключение дубликатов и, соответственно, сортировка.
Рассмотрим
использование
операторов
теоретикомножественных операций MINUS и INTERSECT. Как было
указано ранее, оператор UNION и подзапросы могут в значительной степени повлиять на производительность приложения, поэтому вместо него следует использовать операторы
MINUS и INTERSECT. Рассмотрим в качестве примера такой
запрос:
SELECT Atl FROM Tab! WHERE Atl NOT IN
(SELECT Atl FROM Tab2);.
Его можно переписать в таком виде:
SELECT Atl
FROM Tab! MINUS'SELECT Atl FROM Tab2;
Оба этих запроса фактически возвращают один результат
(если результирующий набор не содержит дубликатов). С помощью просмотра статистических сведений о выполнении
запросов можно обнаружить, что общее количество логических операций чтения для первого варианта запроса гораздо
больше, чем для второго. Использование оператора MINUS
может оказаться очень эффективным.
Логические выражения используются для оценки истинности (с результатом TRUE) или ложности (с результатом
FALSE) высказываний. Использование встроенных функций
Oracle для гибкой подстановки в логические выражения значений данных может значительно улучшить производительность системы. Рассмотрим в качестве примера таблицу, в
которой регистрируется наступление некоторых событий.
Пусть требуется узнать число событий, произошедших до
435
Раздел 7
1 марта 2002 года, между 1 марта 2002 и 1 апреля 2002 года и
с 1 апреля 2002 года по настоящее время. Первое решение —
выполнить три следующих запроса:
SELECT COUNT(*) FROM Tab2 WHERE
At2 < TO_DATE('01032002', 'ddmmyyyy');
SELECT COUNT(*) FROM Tab2 WHERE
At 2 BETWEEN TO_DATE (' 01.032002 ',' ddmmyyyy') AND
1
TO_DATE('01042002','ddmmyyyy );
SELECT COUNT(*) FROM Tab2 WHERE
At2 > TO_DATE('01042002', 'ddmmyyyy');
Для получения всей необходимой информации, скорее
всего, придется три раза выполнить полное сканирование
таблицы ТаЬ2. Этот пример хорош тем, что в нем приходится
иметь дело с тремя разными интервалами, которым должно
принадлежать значение столбца At2 и, на первый взгляд, непонятно, каким образом можно применить здесь двузначную
логику? Прежде всего, следует выполнить логическое преобразование. В Oracle для этой цели предусмотрена специальная
функция DECODE. При внимательном ознакомлении с приведенным ниже примером ее использования можно обнаружить, что данный запрос приводит к тем же результатам, но
за счет всего одного сканирования:
SELECT
SUM(DECODE(SIGN{TO_DATE('01032002','ddmmyyyy')At2),-1,0,1)) suml,
SUM(DECIDE(SIGN(At2TO_DATE('01032002','ddmmyyyy')),-1,0,
DECODE (SIGiJ(TO_DATE('01042002' ,'ddmmyyyy')At2),-1,0,1))) sum2,
SUM(DECODE(SIGN(At2TO_DATE( '01042002','ddmmyyyy')),-1,0,1}) sum3
FROM Tab2;
436
Методы повышения производительности
Эффективность выполнения данного запроса, по сравнению с исходными тремя, будет просто невероятной. Однако
читаемость программы и удобство ее сопровождения заметно
ухудшаются. Хотя, если вспомнить определения функций
DECODE, SIGN и семантику операций с датами в Oracle, логика вычисления выражений suml, sum2, sum3 становится
прозрачной.
Очевидно, что наиболее трудоемкой частью процесса
коррекции является просмотр текстов исходных запросов и
выявление тех из них, для которых может быть использована
простая функция логического преобразования, приводящая к
тем же результатам.
Изменение плана выполнения
запроса
При формировании плана выполнения запроса оптимизатор обычно принимает верные решения. Как правило, 95%
всех запросов в системе не нуждаются в дополнительной настройке. Оставшиеся 5% проблемных запросов подлежат Либо ручной коррекции, которая была рассмотрена выше, либо
принудительному изменению и фиксации плана с помощью
подсказок. На основе сведений о данных в таблицах для запросов, которые выполняются недостаточно быстро, пользователь может выбрать иной план выполнения, чем тот, что
автоматически генерирует оптимизатор.
Для изменения и фиксации плана выполнения запроса с
помощью подсказок необходимо выполнить следующие операции:
— зафиксировать порядок обхода таблиц с помощью
подсказки ORDERED;
— зафиксировать методы доступа с помощью подсказок
FULL, INDEX и т. д.;
— зафиксировать методы соединения таблиц с помощью
подсказок USE_NL, USE_HASH, USE_MERGE;
437
Раздел 7
— дополнительными подсказками тонко настроить запрос.
Дальнейшее изложение будем иллюстрировать на примере. Пусть таблицы Tab! и ТаЬ2 созданы предложениями:
CREATE TABLE Tab! (Atl NUMBER,
At2 NUMBER, At3 NUMBER);
CREATE TABLE Tab2 (Atl NUMBER, At2 NUMBER);
Построим для них индексы с помощью следующих выражений:
CREATE INDEX Tabl$Atl ON Tabl(Atl);
CREATE INDEX Tab2$Atl ON Tab2(Atl);
CREATE INDEX Tab2$At2 ON Tab2(At2);
Заполним таблицы случайными данными с помощью
следующего анонимного PL/SQL-блока (предварительно создав циклическую последовательность — генератор этих данных).
CREATE SEQUENCE sq$Tab MAXVALUE 10 CYCLE CACHE 5;
BEGIN
FOR i IN 1. .8000 LOOP
INSERT INTO Tabl
VALUES(sq$Tab.nextval, 15,2);
END LOOP;
FOR i IN 1..992000 LOOP
INSERT INTO Tabl
VALUES(sq$Tab.nextval, 15,3);
END LOOP;
COMMIT;
END;
Заполним таблицу ТаЬ2 случайными данными с помощью
другого анонимного PL/SQL-блока:
438
Методы повышения производительности
BEGIN
FOR i IN 1..333 LOOP
INSERT INTO Tab2 VALUES(sq$Tab.nextval, . 1);
END LOOP;
FOR 1 IN 1. .333 LOOP
INSERT INTO Tab2 VALUES(sq$Tab.nextval, 2 ) ;
END LOOP;
FOR i IN 1. .334 LOOP
INSERT INTO Tab2 VALUES(sq$Tab.nextval, 3 ) ;
END LOOP;COMMIT;..
END;
Теперь у нас есть большая (миллион строк) таблица Tab!
и связанная с ней относительно маленькая таблица ТаЬ2.
Пусть требуется выполнить следующий запрос:
.SELECT Tabl.At2, COUNT(l)
WHERE T a b l . A t l = T a b 2 . A t l
AND Tabl.At3=2
AND Tab2.At2=l
GROUP BY T a b l . A t 2 ;
FROM Tabl, Tab2
Отправим его на выполнение и отметим, нто выполняется
он достаточно долго. Очевидно, требуется внести коррективы
в план выполнения запроса. Настройка любого проблемного
запроса начинается с просмотра собственно плана. Для этого
предназначена команда EXPLAIN PLAN. Результаты создания
плана
сохраняются
в
специальную
таблицу
PLANJTABLE, которую предварительно необходимо создать
с помощью специального сценария. Каждому выражению,
для которого создается план, пользователь назначает специальный идентификатор (в данном примере "Z"). После создания плана его можно просмотреть с помощью специального
иерархического запроса в SQL*Plus (объем текста запроса не
позволяет привести его в книге полностью) или в каком-либо
графическом средстве, например в SQL Navigator.
План выполнения запроса, который предложил оптимизатор Oracle, приведен ниже.
439
Раздел 7
SQL> DELETE FROM plan_table
2 WHERE statement_id = 'Z';
2 rows deleted.
SQL> COMMIT;
Commit complete.
SQL> EXPLAIN PLAN SET stateme.nt^id=' Z' FOR
2 SELECT Tabl.At2, COUNT(1) FROM Tabl, Tab2
3 WHERE Tabl.Atl=Tab2.Atl
4
AND Tabl.At3=2
5
AND Tab2.At2=l
6 GROUP BY Tabl.At2;
'Explained.
SQL> COMMIT;
Commit complete.
— результат специального иерархического запроса
1.0 SELECT STATEMENT Z Optimizer: CHOOSE
2.1 SORT (GROUP BY)
3.1 TABLE ACCESS (BY INDEX ROWID) - TAB1
4.1 NESTED LOOPS
5.1 TABLE ACCESS (BY INDEX ROWID) - TAB2
6.1 INDEX(RANGE SCAN)-TAB2$AT2 (NON-UNIQUE)
5.2 INDEX(RANGE SCAN)-TAB1$AT1 (NON-UNIQUE)
7 rows selected.
Листинг1 222. План выполнения запроса, предложенный оптимизатором Oracle
Что же представляет собой этот план? План выполнения
запроса представляет собой пошаговые действия сервера при
обращении к данным на основании сведений, полученных на
предыдущих шагах. Графически план представляется ft виде
древовидной структуры, пример которой приведен в листинге
222. Рассмотрим, какие действия при выполнении запроса
будет производить сервер, руководствуясь этим планом.
В нашем случае сначала по индексу Tab2$At2 был найден
идентификатор строки в таблице ТаЬ2, у которой значение
440
Методы повышения производительности
столбца At2 равно 1. Затем по этому идентификатору произошло обращение к самой таблице ТаЬ2 за значением столбца Atl в этой строке. Если бы индекс Tab2$At2 был составным и наряду с At2 включал в себя и Atl, то обращения к
таблице не ^произошло бы вовсе, необходимое значение Atl
было бы считано из индекса.
На следующем шаге по найденному значению Atl из таблицы ТаЬ2 происходит поиск в индексе Tabl$Atl таблицы
Tab! значений. Такой порядок действий сервера будет предпринят для всех записей таблиц Tab! и ТаЬ2. Если соответствующие значения в индексе будут найдены, то по идентификаторам строк таблицы Tab! из индекса происходит обращение к таблице Tab! за необходимыми для вычислений значениями столбцов, которых нет в индексе Tabl$Atl. Для нашего примера это At2 и At3. На следующем этапе происходит
сравнение значения столбца At3 с константой (At3=2) и, если
оно истинно, то эта строка из таблицы Tab! будет учитываться в конечном результате (в той или иной группе —в зависимости от значения столбца At2). В нашем случае оптимизатор
выбрал способ соединения таблиц с помощью вложенных
циклов, поэтому изложенная последовательность действий
сервера будет использована для каждой строки таблицы ТаЬ2
циклично. Последний этап плана выполнения запроса (сортировка) появился из-за присутствия в запросе агрегирующей
функции.
Приступим к оптимизации запроса. Как уже отмечалось
выше, качественная оптимизация невозможна без знаний о
данных априори либо знаний, которые пользователь может
собрать сам с помощью простых запросов, условия которых,
как правило, частично взяты из оптимизируемого запроса. В
этом случае посмотрим, как распределены значения, для которых у нас есть условия сравнения с константами
(Tabl.At3=2, Tab2.At2=l). Выясняется, что в ТаЬ2 записей со
значением столбца At2, равным 1, примерно треть, а в Tab!
записей со значением столбца At3, равным 2, около ста. Менее процента! Очевидно, что целесообразнее начинать поиск
441
Раздел 7
именно с Tabl. Пользуясь таким хорошим логическим условием (Tabl .At3=2). провести ее полное сканирование, отобрать эти 100 строк и уже по их значениям Atl найти подходящие строки в ТаЬ2 (таких строк будет немного, так как таблица ТаЬ2 небольшая) и для них выполнить операцию сравнения с константой (Tab2.At2=l). А так как таблица ТаЬ2 небольшая, то для нее также можно использовать полное сканирование и отказаться от метода соединения с помощью~вяоженных циклов, применив, например, HASH_JOIN.
Приступим к реализации этой идеи. Начнем с фиксации
порядка обхода таблиц. Подсказка ORDERED указывает на
то, что порядок обхода таблиц слева направо — таблицы соединяются в той последовательности, в какой они перечислены во фразе FROM. Обратите внимание, если эту подсказку
не использовать, то оптимизатор сам примет решение, в какой
последовательности соединять таблицы (как правило, в обратной последовательности, чем таблицы перечислены во
фразе FROM). Рекомендуется таким образом организовать
соединение, чтобы на ранних этапах (в начале списка таблиц)
были таблицы, на данные в которых накладываются самые
селективные условия. Делается это для того, чтобы было как
можно меньше операций соединений со строками из других
таблиц на следующих этапах. Если в запросе выполняется
соединение большой таблицы, для которой целесообразно
полное сканирование, с несколькими маленькими, практически всегда целесообразно ее поставить на первое место. Список подсказок, влияющих на последовательность обхода таблиц, приведен в таблице 34.
Таблица 34. Методы обхода таблиц
Подсказка
ORDERED
442
Описание
Использование порядка таблиц, указанного в предложении FROM, в качестве
порядка их объединения.
Методы повышения производительности
PUSH_SUBQ
STAR
Использование плана выполнения запроса с вложенным подзапросом на первом месте.
Использование плана выполнения запроса на основе составного ключа
("звездочки") при разрешении объединения.
После фиксации порядка соединения таблиц необходимо
указать методы доступа к ним с помощью подсказок, которые
описаны в таблице 33. Если эта подсказка содержит список
доступных индексов, то оптимизатор вычисляет стоимость
просмотра по каждому из индексов в списке, после чего выбирает метод доступа с наименьшей стоимостью. Полное
сканирование таблицы или доступ с использованием других
индексов (не перечисленных в списке) оптимизатором не рассматриваются.
В заключение следует указать методы соединения таблиц. Эти методы перечислены в таблице 35. Их назначение
понятно из названий. Для того чтобы выполнить соединение
для двух таблиц, соединение способом вложенных циклов
использует в цикле строки ведущей таблицы для поиска подходящих по условию соединения строк другой таблицы: после первой — вторую, третью и т. д. При сортировке слиянием производится сортировка строк таблиц по столбцу, по которому выполнятся соединение и затем производится их слияние. Этот способ характеризуется большими затратами ресурсов на сортировку и должен использоваться аккуратно. В
пользу его выбора может повлиять необходимость получения
отсортированных результатов (наличие в запросе конструкции ORDER BY) или наличие подходящих индексов. От
некоторых недостатков сортировки со слиянием освобождено
хэш-объединение, в котором используется хэш-таблица для
значений столбца, по которому производится объединение.
443
Раздел 7
Как правило, чаще всего используется самый простой способ
— объединение с помощью вложенных циклов.
Таблица 35. Методы объединения таблиц
Подсказка
USE NL
USE MERGE
USE HASH
Описание
Использование вложенных циклов.
Использование сортировки со слиянием.
Использование hash-объединения.
Оптимизированный запрос представлен в листинге 223.
SQL> DELETE FROM plan_table
2 WHERE statement_id = 'Z';
2 rows deleted.
SQL> COMMIT;
Commit complete.
SQL> EXPLAIN PLAN SET statement_id='Z' FOR
2 SELECT /*+ ORDERED FULL(Tabl) FULL(Tab2)
3 USE_HASH (Tab2)*/ Tabl.At2, COUNT(1)
4 FROM Tabl, Tab2 WHERE Tabl.Atl=Tab2.Atl
5 AND Tabl.At3=2
6 AND Tab2.At2=l GROUP BY Tabl.At2;
Explained.
— результат специального иерархического запроса
1.0 SELECT STATEMENT Z Optimizer: CHOOSE Cost
2.1 SORT (GROUP BY)
3.1 HASH JOIN
4.1 TABLE ACCESS (FULL) - TAB1
4.2 TABLE ACCESS (FULL) - TAB2
i
Листинг 223. Запрос с подсказками оптимизатору и
его план выполнения, полученный командой
EXPLAIN PLAN
444
Методы повышения производительности
Секционирование таблиц
Понятие секционирования может иметь много разных
значений. В Oracle подразумевается, что термин секционирование (partitioning) означает возможность разбиения на разделы (секции) таблиц и индексов. Секции образуют новый
физический уровень архитектуры Oracle, который находится
между таблицей и ее экстентами. При этом таблица отображается на набор секций, которые в свою очередь, однозначно
отображаются на набор экстентов, а каждый экстент отображается на одно или несколько табличных пространств с одним или несколькими файлами данных.
Секционирование таблиц и индексов применяется, как
правило, в двух случаях:
— падение производительности при увеличении объемов
обрабатываемых данных;
-'— при проектировании, когда прогнозируется большой
размер создаваемых таблиц.
Средства секционирования таблиц можно использовать
наряду с параллельными запросами. Степень параллелизма
обычно устанавливается кратной количеству секций, которые
образуют таблицу. При этом используются не только преимущества исключения секций, но и возможность параллельного выполнения запросов по отношению к неисключенным
секциям.
В OracleS таблица или индекс может содержать до 64000
секций. Ключом секционирования (partition key) называется
столбец (столбцы), на основании которого выполняется секционирование таблицы или индекса. Ключ секционирования
может быть составным и насчитывать до 16 столбцов.. В каче-^
стве ключа секционирования обычно выбирается столбец,
значения которого редко изменяются, равномерно распределены и для которых можно выделить логические интервалы.
Например, время начала разговора для таблицы, в которой
445
•
'-
Раздел 7
хранятся сведения о телефонных разговорах. Секции в этом
случае могут содержать разговоры, которые были в течение
одних суток или одной недели. В секционированных таблицах не поддерживаются кластеры и большие объекты (например, объекты LONG и RAW). Пример создания секционированной таблицы приведен в листинге 224.
SQL> CREATE TABLE Tab!
2 (Atl NUMBER, At2 V A R C H A R 2 ( 2 0 Q ) )
3 PARTITION BY RANGE (Atl)
4 (PARTITION pi VALUES LESS THAN (10001)
5 TABLESPACE Tsl STORAGE (INITIAL 1M NEXT 1M) ,
6 PARTITION p2 VALUES LESS THAN (20001)
7 TABLESPACE Ts2. STORAGE (INITIAL 1M NEXT 1M) ,
8 PARTITION p3 VALUES LESS THAN "(30001)
9 TABLESPACE Ts3 STORAGE (INITIAL 1M NEXT 1M),
10 PARTITION p4 VALUES LESS THAN (40001)
11 TABLESPACE Ts4 STORAGE (INITIAL 1M NEXT 1M),
12 PARTITION p5 VALUES LESS THAN (50001)
13 TABLESPACE Ts5 STORAGE(INITIAL 1M NEXT 1M) ) ;
Table created.
Листинг1 224.
таблицы
Пример
создания
секционированной
Выражение VALUES LESS THAN указывает верхнюю
границу секции. Например, секция р! может содержать строки со значением столбца Atl, не превышающим 10000 (LESS
THAN в предложении VALUES LESS THAN означает строго
меньше). Такое ограничение автоматически устанавливается
в каждой секции. Например, при попытке вставить строку со
значением 60000 столбца Atl будет получено сообщение об
ошибке, так как максимальное допустимое значение для
крайней секции (р5) равно 50001.
SQL> INSERT INTO Tab! VALUES(60000,'A1);
446
Методы повышения производительности
INSERT INTO Tab! V A L U E S ( 6 0 0 0 0 , ' А ' )
*
ERROR at line 1:
ORA-14400: inserted partition key does not map to
any partition
Листинг 225. Пример попытки вставки записи, у которой значение столбца-ключа секционирования не попадает в указанный при создании
таблицы диапазон
Для того чтобы избежать возникновения таких ошибок,
при создании таблиц следует указывать специальную границу
для крайней секции.
SQL> CREATE TABLE Tab2
2 (Atl NUMBER, At2 VARCHAR2(200))
3 PARTITION BY RANGE (Atl).'
4 (PARTITION pi VALUES LESS THAN (10001),
5 PARTITION p2 VALUES LESS THAN (20001),
6 PARTITION p3-VALUES LESS THAN (30001),
7 PARTITION p4 VALUES LESS THAN (40001),
8 PARTITION p5 VALUES LESS THAN (MAXVALUE));
Table created.
SQL> INSERT INTO Tab2 VALUES ( 60000, 'A1 ) ,"
1 row created;
Листинг 226. Пример создания секционированной
таблицы с указанием специальной границы для
крайней секции
Единственным отличием двух последних примеров является указание ключевого слова MAXVALUE для крайней секции. Следует учесть, что в предложении VALUE LESS THAN
не допускается использование значений NULL. В тех случаях,,
когда вставляются строки со значениями ключа секционирования NULL, строки сортируются так же, как строки,
447
Раздел 7
которые обладают большими литеральными значениями, чем
у остальных, но меньшими, чем значение MAXVALUE.
Ключ секционирования может быть создан на основе нескольких столбцов (то есть быть составным). При этом приоритет операций сравнения убывает слева направо и, если в
такой
операции
сравнения
используется
значение
MAXVALUE, все остальные расположенные за ним значения
игнорируются. Секционирование по составному ключу имеет
смысл применять для таблицы с составным первичным ключом или при необходимости разбить ее на секции по комбинациям первичного ключа и внешних ключей часто объединяемых таблиц. В листинге 227 представлен пример создания
секционированной таблицы с составным ключом секционирования.
SQL> CREATE TABLE ТаЬЗ
2 (Atl NUMBER, At2 NUMBER, At3 VARCHAR2(200))
3 PARTITION BY RANGE (Atl,~At2)
4 (PARTITION pi VALUES LESS THAN (10001,10),
5 PARTITION p2 VALUES LESS THAN (20001,20),
6 PARTITION p3 VALUES LESS THAN (30001,30),
7 PARTITION p4 VALUES LESS THAN (40001,40),
8 PARTITION p5 VALUES LESS THAN
9, (MAXVALUE,MAXVALUE));
Table created.
—запись попадет в секцию PI
SQL> INSERT INTO ТаЬЗ VALUES(10000, 5, 'A');
1 row created.
—запись попадет в секцию РЗ
SQL> INSERT INTO ТаЬЗ VALUES(25000,35,'В');
1 row created.
Листинг 227. Пример секционирования таблицы с использованием составного ключа секционирования
448
Методы повышения производительности
Секционирование индексов
В секционированных и несекционированных таблицах
могут использоваться четыре основных типа индексов:
— несекционированный индекс;
— глобальный префиксный индекс;
— локальный префиксный индекс;
— беспрефиксный индекс.
Секционированные и несекционированные таблицы могут иметь как секционированные, так и несекционированные
индексы. Единственным ограничением в данном случае является невозможность секционирования кластерного индекса.
Индекс считается префиксным (prefixed), если его крайние слева столбцы находятся в том же порядке и имеют точно
такой же размер, как и ключ секционирования. Кроме того,
подобные индексные столбцы могут быть множеством ключа
секционирования, но не его подмножеством.
Глобальный (global) индекс может-быть только префиксным, но его секционирование обычно отличается от секционирования связанной с ним таблицы. Глобальные индексы не
поддерживаются в Oracle, то есть не поддерживаются особые
взаимосвязи (соответствие диапазона значений) между секционированным индексом и секционированной таблицей. Основным недостатком глобального индекса является то, что
оптимизатор Oracle не может использовать преимущества
исключения секций. G другой стороны, глобальные индексы
могут быть разбиты на секции на основе диапазонов значений, отличных от тех, которые имеются в связанной с ним
таблице. Это может быть полезным при работе с несколькими
индексами, которые связаны с приложениями интерактивной
аналитической обработки.
Локальный (local) индекс может быть префиксным или
беспрефиксным. В случае его использования между секциями
индекса и соответствующими секциями таблицы устанавли449
15. Заказ № 1628.
Раздел 7
вается взаимно однозначное соответствие. Такое секционирование называется эквивалентным (equi-partitioned) и поддерживается Oracle. Оптимизатор Oracle использует преимущества отсутствия обращения к секциям. Следовательно, основными преимуществами локальных индексов являются автоматическая эквивалентная для всех секций поддержка разбиения и соответствующие преимущества от использования
оптимизатора. Единственным недостатком локального индекса является необходимость иметь такое же секционирование,
как и для связанной с ним таблицы (независимо от того, префиксный этот индекс или беспрефиксный).
Следующий пример содержит SQL-выражение для создания секционированной таблицы и связанных с ней локального
префиксного и локального беспрефиксного индексов.
SQL> CREATE TABLE Tab4
2 (Atl NUMBER, At2 NUMBER, At3 VARCHAR2(200))
3 PARTITION BY RANGE (Atl)
- 4 (PARTITION pi VALUES LESS THAN (10001),
.5 PARTITION p2 VALUES LESS THAN (20001),
6 PARTITION p3 VALUES LESS THAN (30001),
7 PARTITION p4 VALUES LESS THAN (40001));
Table created.
SQL> CREATE INDEX Tab4$Atl$At2 ON Tab4 (Atl,At2)
2 LOCAL
3 (PARTITION pi,
4 PARTITION p2,
5 PARTITION p3,
6 PARTITION p4);
Index created.
SQL>
2
3
4
5
6
7
450
CREATE INDEX Tab4$At2
ON Tab4 (At2)
LOCAL
(PARTITION PI,
PARTITION P2,
PARTITION P3,
PARTITION P4);
Методы повышения производительности
Index created.
Листинг 228. Пример создания секционированной
таблицы и связанных с ней локального пре.
фиксного и беспрефиксного индексов
Обратите внимание на то, что в обоих случаях не испольг
зуются предложения PARTITION BY RANGE и VALUES
LEES THAN, так как с помощью ключевого слова LOCAL
Oracle уведомляется о типе индекса и в индексе будет применено эквивалентное секционирование по тем же спецификациям, которые используются в таблице.
Операции с секциями
Для выполнения всех операций с секциями предусмотрено использование двух основных выражений: ALTER TABLE
и ALTER INDEX. Эти выражения обладают следующими
расширениями, предназначенными для работы с секциями: •
Таблица 36. Операции с секциями
ALTER TABLE
DROP PARTITION
ADD PARTITION
RENAME PARTITION
MODIFY PARTITION
TRUNCATE PARTITION
SPLIT PARTITION
MOVE PARTITION
EXCHANGE PARTITION
MODIFY PARTITION
ALTER INDEX
DROP PARTITION
RENAME PARTITION
REBUILD PARTITION
MODIFY PARTITION
SPLIT PARTITION
PARALLEL
UNUSABLE
Многие из операций, связанных с работой с секциями,
уже по своим названиям могут быть понятны или известны,
поскольку, на первый взгляд, они выглядят так же, как обыч451
15*
Раздел 7
ные операции с таблицами и индексами, например DROP
TABLE и DROP INDEX. Однако здесь следует обратить более
пристальное внимание на расширения, которые свойственны
только секциям (SPLIT, MOVE, EXCHANGE и UNUSABLE).
Проиллюстрируем технику работы с секциями на примере
таблицы ТаЫ, созданной следующим выражением:
CREATE TABLE ТаЫ
(Atl NUMBER, At2 NUMBER, At3 V A R C H A R 2 ( 2 0 0 ) )
PARTITION BY RANGE (Atl)
(PARTITION pi VALUES LESS THAN (10001),
PARTITION p2 VALUES LESS THAN ( 2 0 0 0 1 ) ,
PARTITION p3 VALUES LESS THAN ( 3 0 0 0 1 ) ) ;
На основе секции рЗ с помощью спецификации SPLIT
PARTITION создадим новую секцию р4. Прежняя секция рЗ
будет содержать все строки, для которых значения поля Atl
меньше значения 25000, а новая секция р4 будет содержать
все строки, значения которых больше или равны 25000.
SQL> ALTER TABLE Tab! SPLIT PARTITION рЗ
2 AT (25000)
3 INTO (PARTITION p3, PARTITION p4);
Table altered.
Листинг1 229. Изменение способа секционирования
таблицы
с . помощью
конструкции
'SPLIT
,, PARTITION
В листинге 230, изменяется место хранения одной из секций таблицы ТаЫ.
SQL> ALTER TABLE ТаЫ MOVE PARTITION рЗ
2 TABLESPACE TS4;
Table altered.
Листинг1 230. Изменение места хранения секции рЗ с
помощью оператора ALTER TABLE
452
Методы повышения производительности
Как уже отмечалось выше, для ранних версий Oracle
проводилось ручное секционирование путем создания нескольких таблиц и представления UNION ALL над ними. Для
миграции из такой базы данных специально предназначена
команда EXCHANGE PARTITION. С ее помощью можно
преобразовать как таблицу в секцию, так и наоборот. Результат преобразования секции в несекционированную таблицу
представлен в листинге 231. В этом примере включаются индексы и не производится проверка диапазонов значений для
перемещаемых строк.
-SQL> ALTER TABLE Tab! EXCHANGE PARTITION pi
2 WITH TABLE Tabla INCLUDING INDEXES
3 WITHOUT VALIDATION;
Table altered.
Листинг 231. Пример преобразования секций и таблиц
Индекс-таблицы
Индекс-таблица — это таблица, которая физически построена в виде двоичного дерева относительно своего первичного ключа. Oracle, начиная с версии 6, допускает возможность не производить чтение блоков данных таблицы в
тех случаях, когда в запросах на выборку данных используются только столбцы индекса. Однако при операциях добавления, обновления и удаления записей обязательно должна
была участвовать основная таблица. Начиная с OracleS,.существует возможность определить таблицу, которая одновременно является и собственным индексом, что устраняет ведение двух отдельных структур. Как правило, это таблицы с короткими строками, обращение к которым всегда производится или по первичному ключу, или полным сканированием.
453
Раздел 7
Не рекомендуется использовать индекс-таблицы, если
строки имеют относительно большую длину, например свыше 20% от размера блока. В этом случае лучшим выбором
является использование обычных таблиц и индексов. Для
создания индекс-таблиц в предложении CREATE TABLE указываются ключевые слова ORGANIZATION INDEX. Пример
создания индексно-организованной таблицы представлен в
листинге 232.
SQL> CREATE TABLE Tablndex
2 , (Atl NUMBER PRIMARY KEY,
3 At2 VARCHAR2(40))
4 ORGANIZATION INDEX;
Table created.
Листинг 232. Пример создания индекс-таблицы "
Существуют некоторые ограничения при работе с индекс-таблицами. Наиболее важно, что их строки не имеют
идентификаторов (ROWID), поэтому не могут быть созданы
никакие дополнительные индексы, за исключением обязательного первичного ключа.
454
Раздел 8
Объектные расширения
в Oracle8
В конце 60-х годов в методологии программирования
возникла идея объединить два понятия: данные и операции в
одно целое, которое впоследствии получило название объект:
Объект = Данные + Операции.
Понятие объекта естественным образом согласуется с
нашими представлениями об окружающем мире. Объект
можно представить себе как сущность предметной области,
которая характеризуется определенным набором свойств и
"умеет" выполнять некие действия (методы). Чтобы понять
суть и назначение объекта, нужно обязательно знать его свойства и методы.
Каждый объект всегда принадлежит некоторому классу.
Класс — это обобщенное описание множества однотипных
объектов. Объекты являются конкретными представителями
своего класса, их принято называть экземплярами класса. В
объектно-реляционных СУБД классы принято называть объектными типами.
455
Раздел 8
Объектно-ориентированное программирование строится
на основе трех принципов: инкапсуляции, наследовании и
полиморфизме.
Инкапсуляция означает наблюдаемое в объектах объединение данных и операций в одно целое, которое ведет к сокрытию внутреннего устройства объектов.
Наследование означает, что на основе уже существующих
объектов можно строить новые, которые могут отличаться от
родительского объекта собственными методами и свойствами. Иными словами, при наследовании происходит переход
общего к частному.
Полиморфизм означает, что в производных объектах
функционирование наследуемых операций может быть изменено. При этом весь код, управляющий элементами родительского объекта, пригоден для управления дочерним объектом
без всякой модификации.
OracleS можно считать первым шагом корпорации Oracle
на эволюционном пути к объектной ориентации. OracleS работает с объектами с помощью процессора реляционной базы
данных. Такой механизм в конечном счете должен привести к
истинно объектно-ориентированным системам управления
базами данных (ОРСУБД). В настоящее время сервером поддерживаются инкапсуляция и полиморфизм. В следующей
версии сервера (Oracle 9i) декларируется поддержка механизма наследования.
Объектные типы
Под объектным типом понимается объект базы данных
Oracle, которая объявляет структуру данных (атрибуты) и
разрешенные операции над ней. Объектный тип — это шаблон, по которому можно создавать переменные, таблицы,
столбцы и другие конструкции этого типа. Объектный тип во
многом похож на класс или абстрактный тип данных объектно-ориентированного программирования.
456
Объектные расширения в OracleS
Объект — это экземпляр объектного типа OracleS. Объекты могут храниться в таблицах (в таких случаях они являются постоянными), либо они могут существовать только
временно в переменных PL/SQL.
Атрибут — это структурная часть объекта Oracle. Каждый атрибут может принадлежать одному типу данных, либо
скалярному, например VARCHAR2, либо составному, как
объявленные пользователем вложенные таблицы или массивы. К объявлениям атрибутов предъявлены следующие требования: не допускается указание ограничения NOT NULL,
значений по умолчанию, типы данных должны соответствовать типам данных, которые используются при описании таблиц и других объектов схем (за исключением LONG и LONG
RAW). To есть нельзя объявить атрибут, например, типа
BOOLEAN.
Метод — это процедура или функция, которая, как правило, производит операции над атрибутами объекта. Методы
для объекта могут быть вызваны только в контексте конкретного объекта этого типа. Методы могут быть созданы на
PL/SQL и других языках программирования. Для каждого
объектного типа существует специальный метод по умолчанию — так называемый конструктор, который инициализирует объекты. При определении объектного типа можно предусмотреть методы, которые будут являться членами объектного типа. В определение типа входит только заголовок метода
со спецификациями доступа к объектам базы данных.^ Для
определения тела метода необходимо определить тело типа
(TYPE BODY), в котором определены тела всех методов. Определению тела каждого метода должно предшествовать ключевое слово MEMBER FUNCTION (MEMBER PROCEDURE).
Для доступа к атрибутам и методам в контексте экземпляра
объекта в функции используется ключевое слово SELF. Для
доступа к методам используется точечная нотация.
Конструкция "объявление типа—тело" очень похожа на
конструкцию "спецификация—тело пакета". Работа с ними
очень похожа, но, вместе с тем, имеется ряд различий. Так,
457
Раздел 8
для объектных типов нельзя использовать дополнительные
программы, отсутствующие в объявлении типа.
Для сравнения объектов в определении объектного типа
необходимо предусмотреть реализацию двух стандартных
методов MAP и ORDER. Метод MAP не имеет аргументов и
возвращает значение скалярного типа (DATE, NUMBER,
VARCHAR2, CHAR, REAL). При сравнении двух объектов
для каждого из них вычисляется значение этой функции, и
объекты упорядочиваются в соответствии с этими значениями.
Метод ORDER предоставляет пользователю несколько
больше возможностей по определению внутренней логики
оператора сравнения для данного объектного типа. Он использует в качестве аргумента другой объект того же типа и
возвращает -1,0 или 1, если собственный объект (объект, для
которого вызывается данный метод) соответственно меньше,
равен или больше объекта, переданного в качестве аргумента
функции. Следует отметить, что тип может иметь только одну
функцию MAP или ORDER.
Для создания объектных типов используется оператор
CREATE TYPE. В следующем листинге приведен пример создания объектного типа, который имеет пять атрибутов и один
метод.
SQL> CREATE OR REPLACE TYPE~Otl AS OBJECT
2 (Atl NUMBER,
3 At2 VARCHAR2(50),
-4 At3 VARCHAR2(50) ,
5 At4 VARCHAR2{50) ,
6 At5 DATE,
7 MEMBER FUNCTION AtlAt2At3 RETURN VARCHAR2,
8 MAP MEMBER FUNCTION M RETURN NUMBER);
9 /
Type created.
Листинг 233. Пример, иллюстрирующий создание объектного типа
458
Объектные расширения в Oracle8
Код методов объектного типа создается при создании его
тела. При создании самого типа они только объявляются, а
реализуются с помощью оператора CREATE OBJECT TYPE
BODY.
SQL>
2
3
4
56
7
8
9
10
11
Type
CREATE OR REPLACE. TYPE BODY Otl IS
MEMBER FUNCTION AtlAt2At3 RETURN VARCHAR2 AS
BEGIN
RETURN Atl||' '|IAt2||' '||At3;
END;
MAP MEMBER FUNCTION m RETURN NUMBER AS
BEGIN
RETURN Atl;
-END;
END;
/
body created.
Листинг 234. Пример, иллюстрирующий создание тела
объектного типа
Для изменения или замены объектного типа используется
оператор ALTER TYPE имя_тта. С его помощью, например,
можно добавить новые методы или перекомпилировать тело
объекта.
SQL> ALTER TYPE Otl REPLACE AS OBJECT
2
3
4
5
6
7
8
Type
(Atl NUMBER,
At2 VARCHAR2(50),
At3 VARCHAR2(50),
At4 VARCHAR2(50),
At5 DATE,
MEMBER FUNCTION AtlAt2At3 RETURN VARCHAR2,
MEMBER FUNCTION AtlAt2 RETURN VARCHAR2);
altered.
Листинг 235. Пример, иллюстрирующий замену объектного типа с добавление нового метода
459
'
'
..
•
'
Раздел 8
Для удаления объектного типа используется оператор
DROP TYPE имя_типа. Если существуют объекты, зависящие от удаляемого объектного типа, то требуется указание
ключевого слова FORCE. Удаление объектного типа Otl
представлено в листинге 236.
SQL> DROP TYPE Otl FORCE;
Type dropped.
x
Листинг 236. Пример удаления объектного типа
Если при объявлении двух типов используются взаимные
ссылки объектов друг на друга или один из атрибутов типа
ссылается на объект этого же типа, то объявить эти типы
обычным способом не получится, так как в момент объявления одного типа второй будет еще не объявлен. Для таких
объявлений используются неполные типы. В этом случае объявляется заголовок типа, что сообщает серверу Oracle, что
такой тип существует и будет полностью определен позднее.
Рассмотрим пример создания такого типа.
SQL> CREATE OR REPLACE TYPE Ot2;
Type created.
SQL> CREATE OR REPLACE TYPE Ot2 AS OBJECT
2
(Atl NUMBER,
3
At2 REF Ot2);
Type created.
Листинг 237. Пример предварительного объявления
типа
460
Объектные расширения в OracleS
Объекты в базе данных
После определения объектногб типа его можно использовать как при определении столбца реляционной таблицы, так
и при определении таблицы объектов. Объекты, хранящиеся в
объектных таблицах, называются объектами в таблице. Объекты, хранящиеся в столбце таблицы или как атрибут другого
объекта, называются объектами в столбцах. Для их создания
при описании таблицы нужно просто указать тип данных одного из столбцов как соответствующий объектный тип. В следующем примере таблица ТдЫ содержит столбец At2,
объявленный как объектный тип Otl.
SQL> CREATE TABLE Tab!
2
(Atl NUMBER,
3
At2 Otl);
Table created.
Листинг 238. Пример создания таблицы, один
столбцов которой имеет объектный тип
из
В общем случае объектный тип имеет древовидную
структуру, в которой каждый атрибут объекта является вершиной. Если же сам этот атрибут имеет объектный тип, то у
него есть потомки. При таком построении каждое поддерево
будет завершаться атрибутом встроенного типа или набором.
Такие атрибуты называются атрибутами-листьями исходного
объектного типа. В следующем примере для создания объекта
используется поставляемая системой функция-конструктор,
имя которой совпадает с именем объектного типа, а ее аргументы имеют типы соответствующих атрибутов объектного
типа в порядке их объявления при определении типа.
461
Раздел 8
SQL> • INSERT INTO Tabl VALUES'
(i'0,Qtl(l, ' A ' , ' B ' , 'C',SYSDATE) ) ;
1 row created.
Листинг 239. Пример вставки записи
функции-конструктора объекта
с
помощью
Для выборки данных из этой таблицы необходимо объявить алиас для таблицы и в явном виде специфицировать каждый атрибут объекта.
SQL> SELECT t.Atl,t.At2.At2 FROM Tabl t
2 WHERE t.At2.At2='A';
ATI AT2.AT2
10 A
Листинг 240. Пример запроса к таблице, содержащей
объекты в столбцах
Наряду с хранением объектов в столбцах, можно использовать таблицы объектов. Таблицы объектов — это специальный вид таблиц, содержащих объекты и обеспечивающих реляционное представление их атрибутов. Для следующего
примера объектная таблица ТаЬ2 может рассматриваться
двумя способами: таблица с одним столбцом, каждый элемент которого объект типа ОН; таблица с несколькими
столбцами, каждый из которых имеет тип и имя соответствующего атрибута объектного типа, то есть Atl, At2, At3, At4,
At5. Для создания таблицы объектов используется следующий упрощенный синтаксис:
CREATE TABLE [имя__схемы. ] имя_таблицы OF
имя объектного типа.
462
Объектные расширения в OracleS
Пример создания объектной таблицы приведен в листинге 241.
SQL> CREATE TABLE Tab2 OF Otl;
Table created.
Листинг 241. Пример создания объектной таблицы
Для вставки данных в объектную таблицу можно использовать два способа — создать объект с помощью функцииконструктора или перечислить атрибуты объекта явно во фразе INSERT. Пример вставки данных в объектную таблицу
приведен ниже.
SQL> INSERT INTO Tab2 VALUES
(Otl(10,'D1,'E','F',SYSDATE));
1 row created.
SQL> INSERT INTO Tab2 VALUES
(10,'D1,'E1,'F',SYSDATE);
1 row created.
Листинг 242. Пример различных способов
данных в объектную таблицу
вставки
Выборку данных из объектной таблицы можно производить двумя способами: с помощью оператора VALUE (в данном случае использование алиаса обязательно) и с помощью
спецификации атрибутов объектного типа. Примеры обоих
способов приведены в листинге 243.
SQL> SELECT VALUE(t) FROM Tab2 t
2 WHERE t.At4='F';
463
Раздел 8
SQL> -SELECT sql.NEXTVAL FROM dual;
NEXTVAL
62
SQL> INSERT INTO Tab2
2 VALUES (NULL,'X','¥','Z',SYSDATE);
1 row created.
SQL> SELECT VALUE(t) FROM Tab2 t
2 WHERE t.At4='Z';
VALUE(T)(ATI, AT2, АТЗ, АТ4, ATS)
OT1(63, 'X', 'У, 'Z', 40-MAR-02')
Листинг 246. Пример создания триггера для объектной таблицы
Ссылки на объекты
В реляционной модели данных для выражения отношений между строками разных таблиц используются механизмы
внешних ключей и поддержание ссылочной целостности. Для
объектных расширений предусмотрен другой способ.
Для каждого объекта в таблице объектов Oracle создает
уникальный и неизменный идентификатор объекта. Этот
идентификатор позволяет обращаться к соответствующему
объекту таблицы из другого объекта или реляционной таблицы. Гарантируется, что во всей базе данных нет пары объектов с одинаковыми идентификаторами, также гарантируется
повторное неиспользование идентификаторов удаляемых
объектов. Встроенный тип данных, обеспечивающий возможность использования таких ссылок, называется REF. Переменную типа REF можно использовать для доступа к объекту,
как если бы данная переменная имела бы тот же тип, что и
объект, на который она ссылается.
В OracleS в операторах INSERT и UPDATE используется
конструкция RETURNING, которая позволяет без дополни466
Объектные расширения в OracleS
тельных перезапросов копировать в локальные переменные
новые значения. В приведенном ниже листинге приведена
техника работы с ссылками ha объекты (заносится объект в
объектную таблицу ТаЬЗ с ссылкой на объект из объектной
таблицы ТаЬ2).
SQL> CREATE OR REPLACE TYPE Ot2 AS OBJECT
2 (Atl VARCHAR2(20),
3
At2 VARCHAR2{20),
4
At3 BLOB,
5
At4 DATE);
6 /
Type created.
SQL>
2
3
4
Type
CREATE OR REPLACE TYPE Ot3 AS OBJECT
(Atl NUMBER,
At2 REF Ot3) ;
/
created.
SQL> CREATE TABLE Tab2 OF Ot2;
Table created.
•
SQL> CREATE TABLE ТаЬЗ OF Ot3;
Table created.
SQL> DESC ТаЬЗ
Name
ATI
AT2
Null?
Type
NUMBER
REF OF OT2
SQL> DECLARE
2 'I_ref_ot2 REF Ot2;
3 BEGIN
4
INSERT INTO Tab2 t
5
VALUES('A','В',EMPTY_BLOB(),SYSDATE)
6
RETURNING REF(t) INTO I_ref_ot2;
7
INSERT INTO ТаЬЗ VALUES (I, I_ref_ot2);
8 END;
. .
9 /
467
16*
Раздел 8
I
PL/SQL procedure successfully completed.
Листинг 247. Пример работы с REF-ссылками
Очевидно, что для REF напрашивается прямая аналогия с
ROWID, но есть и различия. ROW1D не изменяется в течение
жизни строки в таблице (если с базой данных не производятся
специальные операции), а с переменными типа REF можно
производить следующие действия: присваивать значение другой переменной типа REF; устанавливать ее значение в NULL
и т. п.
REF состоит из следующих частей: ROWID (при определении атрибута таблицы, имеющего тип REF, необходимо
указать WITH ROWID); уникального идентификатора таблицы; уникального идентификатора объекта. При объявлении
переменной типа REF можно определить ее структуру (какие
из перечисленных частей включать в нее, т. к. единственной
обязательной частью REF является идентификатор объекта).
Когда сервер Oracle обращается к объекту, на который
ссылается REF, он использует ROWID для выбора строки из
таблицы. Если ссылка не содержит ROWID, то сервер использует идентификатор таблицы и идентификатор объекта,
по которым построены индексы.
Как следует из вышесказанного, REF является ссылкой на
объект. Обратной функцией, которая позволяет по ссылке
. обратиться к объекту, является DEREF. Пример работы с ней
представлен в листинге 248.
SQL> DECLARE
2
I_ref_ot2 REF Ot2;
3
I_ot2 Ot2;
4 BEGIN •
5
SELECT At-2 INTO I_ref_ot2
6
FROM Tab3 WHERE At 1=1;
7
SELECT DEREF(I_ref_ot2) INTO I_ot2
468
Объектные расширения в OracleS
A
8
FROM dual;
9
DBMS_OUTPUT.PUT_LINE(l_ot2.Atl);
10 END;
11 /
PL/SQL procedure successfully completed.
Листинг 248. Применение операции DEREF
При определении атрибута таблицы, имеющего тип REF,
можно ограничить область действия ссылки, указав таблицу
объектов, в которой хранятся объекты, на которые может
ссылаться данная переменная. Такие ссылки называются ограниченными. Они могут ссылаться только на объекты, хранящиеся в специфицированной таблице. Если создать другую
таблицу объектов того же типа, то данная переменная не
сможет указывать на объект из новой таблицы. В ограниченных ссылках не используются ROWID и идентификатор таблицы (то есть они состоят только из идентификатора объекта). Так как при обращении к объекту по ограниченной
ссылке сервер заранее знает таблицу, в которой хранятся объекты, то доступ к объектам через такие ссылки осуществляется быстрее. Для работы с такими ссылками требуется привилегия на получение данных из этой таблицы или системная
привилегия SELECT ANY TABLE.
Следующий листинг демонстрирует изменение описания
таблицы объектов ТаЬЗ.
SQL> ALTER TABLE ТаЬЗ
2 ADD (SCOPE FOR (At2) is. ТаЬЗ);.
Table altered.
Листинг 249. Пример указания таблицы, в которой
хранятся объекты, с •помощью ограниченных
ссылок
469
.
Раздел 8
Если в таблице объектов удалить объект, на который имеется REF-ссылка, то такая ссылка становится "зависшей". Для
поиска таких ссылок используются запросы со специальными
предикатами IS DANGLING. "Зависшие" ссылки не тождественны пустым. Для проверки ссылки на "пустоту" используется стандартный предикат IS NULL. При попытке обратиться к объекту по пустой или "зависшей" ссылке ошибки
не произойдет, будет возвращено NULL-значение. Для
иллюстрации вышесказанного приведем следующий пример:
SQL> DELETE FROM Tab2;
1•row deleted.
SQL> SELECT COUNT(*) FROM Tab3 WHERE At2 IS NULL;
COUNT(*)
0
SQL> SELECT COUNT(*) FROM ТаЬЗ
2 WHERE At2 IS DANGLING;
COUNT(*)
1
Листинг 250., Пример поиска зависших (DANGLING) и
пустых (NULL) ссылок
Массивы
Другим способом для представления отношений между
сущностями являются наборы объектов. OracleS поддерживает два типа наборов. Они описывают набор данных, состоящий из неопределенного числа записей одного типа. Соответствующие конструкции называются массивами переменной
длины (VARRAY) и вложенными таблицами (NESTED
470
Объектные расширения в OracleS
TABLES). Наборы имеют конструкторы, представляющие
собой функцию, имя которой совпадает с именем типа набора, а аргументами является некоторое число объектов.
' Массив — это упорядоченный набор данных одного типа.
Каждый элемент массива имеет индекс, который является
числом, соответствующим позиции элемента в массиве. Количество элементов в массиве называется размером массива.
Массив имеет переменную длину. При объявлении массива
необходимо указать его максимально возможный размер.
При проектировании базы данных рекомендуется выбрать VARRAY, если:
— важен порядок элементов в наборе (записи в массивах
переменной длины упорядочены);
—известно ограничение на количество элементов в наборе (при описании массива указывается его максимально
возможный размер, что позволяет более эффективно хранить
их по сравнению с вложенными таблицами, размер которых
неограничен).
Для объявления массивов
CREATE TYPE следующего вида:
используется
оператор
SQL> CREATE OR REPLACE TYPE Tml AS
2 VARRAY(10) OF NUMBER;
3
/
Type created.
Листинг 251. Пример,
массива
иллюстрирующий
объявление
Можно объявить массив, элементы которого будут иметь
скалярный тип, тип записи или объектный тип PL/SQL. Для
элементов массива можно указать ограничение NOT NULL.
Создание массивов производится стандартным образом — с
помощью конструктора, имя которого совпадает с именем
471
Раздел 8
типа, а обращение к элементам — с указанием индекса. Для
увеличения размера массива служит метод EXTEND, однако
увеличить размер массива так, чтобы он вышел за пределы,
указанные при его объявлении, нельзя.
Также массивы можно использовать для объявления типа
переменных в программах на PL/SQL.
SQL> DECLARE
2
TYPE m IS VARRAY(26)
OF VARCHAR2(1};
3
l_mass m;
4 BEGIN
5
1 mass := m ( ' A ' , ' B ' , ' C 1 , ' D 1 , ' E 1 ) ;
6
DBMS_OUTPUT.PUT_LINE(l_mass(l)||l_mass(2)||l_mass
(3));
7 END;
8 /
ABC
PL/SQL procedure successfully completed.
Листинг 252. Пример,
массива
иллюстрирующий объявление
Для определения актуального размера массива используется метод COUNT. В листинге 253 приведен пример создания таблицы, один из столбцов которой объявлен как массив,
и функции, которая позволяет вывести в запросе все значения
элементов массива через точку с запятой. Аналогичным образом можно определить и другие функции, например, для доступа к конкретному элементу набора по его индексу или получения актуального размера массива.
gQL>
2
3
4
472
CREATE OR REPLACE TYPE Tm2 AS OBJECT
(Atl VARCHAR2(30),
At2 Tml);
/
Объектные расширения в OracleS
Type cheated.
SQL> CREATE TABLE Tab4 OF Tm2;
Table created.
SQL> INSERT INTO Tab4 .
2 VALUES ('Tm2('A', Tml(1,2,3)));
1 row created.SQL> INSERT INTO Tab4
2 VALUES (Тт2('В', Tml(4,5,6)});
1 row created.
SQL> CREATE OR REPLACE FUNCTION f2(pi IN Tml)
2 RETURN VARCHAR2 AS
3
s VARCHAR2(255);
4
i INTEGER;
5 BEGIN
6
FOR i IN 1..pi.COUNT LOOP
7
s:=s| Г; ' | ITO_CHAR(pl(i));
8
END LOOP;
9
RETURN SUBSTR(s,2);
10 END;
11 /
Function created.
.SQL> SELECT Atl,f2(At2) FROM Tab4;
ATI
F2(AT2)
A
B.
1;2;3
4; 5; 6
Листинг 253.
Пример,
иллюстрирующий
функцией массива в запросе
,
обработку
С помощью операторов SQL с массивами в таблицах
можно работать только целиком, модифицировать его отдельные элементы нельзя. То есть сначала необходимо считать значение массива в переменную такого же типа в программе на PL/SQL, изменить ее значение (значения элементов
массива) и занести обратно в таблицу.
473
Раздел 8
Вложенные таблицы
Вложенная таблица — это неупорядоченный набор данных одного типа. Она имеет один столбец встроенного или
определенного пользователем типа. Если этот столбец объектного типа, то вложенная таблица может рассматриваться
как многостолбцовая таблица со столбцом для каждого атрибута типа объекта. Работа с вложенными таблицами очень
похожа на работу с PL/SQL таблицами. Работать с вложенными таблицами можно как с динамическими переменными в
программах на PL/SQL, а также хранить в базе данных. Далее
будем рассматривать вложенные таблицы в базе данных.
При создании таблицы объектов необходимо указать таблицу-хранилище для строк вложенной таблицы. Все вложенные таблицы данной объектной или реляционной таблицы
хранятся в таблице-хранилище. Для разных таблиц объектов
необходимо использовать разные таблицы-хранилища. С точки зрения реализации отличие между массивами-переменной
длины и вложенными таблицами заключается в том, что данные вложенных таблиц хранятся в еще одной специальной
таблице, а данные массивов хранятся в той же таблице. Пример создания таблицы, тип одного из столбцов которой объявлен как вложенная таблица, приведен ниже. Для хранения
вложенной
таблицы
используется
таблица-хранилище
Tab5 At2 NESTED TABLE.
SQL>
2
3
4
Type
CREATE OR REPLACE TYPE Ot4 AS OBJECT
( Atl NUMBER,
At2 VARCHAR2(2000));
/
created.
SQL->
2
3
Type
CREATE OR REPLACE TYPE Ttl
AS TABLE OF Ot4;
/
created.
474
Объектные расширения в OracleS
SQL> CREATE TABLE Tab5
2 (Atl NUMBER,
3
At2 Ttl)
4
NESTED TABLE At2
5
STORE AS Tab5_At2_NESTED_TABLE;
Table created.
Листинг 254. -Пример объявления вложенной таблицы
Инициализация вложенной таблицы производится с помощью функции конструктора, имя которого совпадает с названием таблицы.
С вложенными таблицами, хранящимися в базе данных,
можно выполнять различные операции, как со всей таблицей,
так и со строками. Порядок работы с родительской таблицей
ничем не отличается от обычного, а для доступа к вложенным
таблицам предназначены расширения, предусмотренные в
реализации SQL. Первым из них является раскрывающий
подзапрос (оператор THEQ), позволяющий выбрать одну таблицу, над которой будут производиться операции. Обязательным условием является единственность возвращаемой таблицы (запрос в предложении THE должен возвращать одну запись, в противном случае будет получено сообщение об
ошибке). Также раскрывающий подзапрос используется для
вставки строк во вложенную таблицу, обновления данных в
ней и удаления строк из нее. Проиллюстрируем технику
вставки записей во вложенную таблицу на примере следующего выражения INSERT. Здесь использован конструктор типа Ttl.
После инициализации вложенной таблицы как значения
столбца родительской таблицы можно обратиться к ней непосредственно.
SQL> INSERT INTO Tab5 VALUES (10,Ttl());
1 row created.
475
Раздел 8
SQL> INSERT INTO
2 THE
3 (SELECT At 2 FROM Tab5 .t
4. WHERE t.At1=10) VALUES (Ot4(1,'A')); ~
1 row created.
-SQL> INSERT INTO Tab5 VALUES (10,Ttl()).;
1 row created.
. \
.
SQL> INSERT INTO
2 THE
3 {SELECT At2 FROM Tab5 t
4 WHERE t.Atl=10) VALUES (Ot4(1,'A'));
(SELECT At2 FROM Tab5 t
*
ERROR at line 3:
ORA-01427: single-row subquery returns more than
one row
Листинг 255. Пример вставки записей во вложенную
таблицу, идентифицированную оператором THE
Техника удаления и изменения данных во вложенных
таблицах идентична и представлена в листинге 256.
SQL> UPDATE
2 THE
3
(SELECT At2 FROM Tab5 ,'t
4
WHERE t.At1=10) nt
5 SET nt.At2 ='B';
1 row updated.
SQL> DELETE FROM
2
THE
3
(SELECT At2 FROM Tab5
4
WHERE t.At1=10) nt
5 WHERE nt.At2 ='В';
1 row deleted.
t
Листинг 256. Пример, иллюстрирующий изменение и
удаление
данных
во
вложенной
таблице,
идентифицированной выражением THE()
476
Объектные расширения в OracleS
Другим способом доступа к вложенным таблицам являются вложенные курсоры (NESTED CURSORS). Вложенный
курсор объявляется с помощью ключевого слова CURSOR в
списке операндов оператора SELECT. Вложенные курсоры
можно использовать только для выбора данных из таблицы.
Для вставки, удаления или обновления данных во вложенных
таблицах их использовать нельзя. В приведенном в листинге 257 запросе выражение CURSOR возвращает курсоруказатель (в открытом состоянии) для каждой строки'запроса.
После получения значения вложенного курсора его можно
использовать аналогично обычным курсорам для доступа к
строкам вложенной таблице.
SQL> SELECT At 1, CURSOR '(SELECT *
2
FROM TABLE ( t . A t 2 ) ) At2 FROM Tab5 t;
ATI AT2
10
CURSOR STATEMENT :
CURSOR STATEMENT
ATI
AT2
1
2
A
В
Листинг 257. Доступ к вложенной таблице с помощью
вложенных курсоров
Вложенные таблицы и массивы являются объектными
типами и имеют методы. Некоторые из них уже были использованы при иллюстрации работы с наборами. В таблице 37
приведен полный список методов и выполняемых ими действий. Методы используются при разработке программ PL/SQL,
более подробно ознакомиться с их назначением и примерами
можно в документации Oracle Application Developer's Guide.
477
• •
Раздел 8
Таблица 37. Методы наборов
Метод
EXISTS
COUNT
LIMIT
FIRST/LAST
NEXT/PRIOR
EXTEND
TRIM
DELETE
Описание
Определяет, существует ли
некоторый элемент набора.
Возвращает число элементов набора.
Возвращает максимальное число
элементов набора.
Возвращает первый/последний
элемент набора.
Возвращает элемент набора,
следующий/предыдущий по
отношению к данному элементу.
Добавляет элементы к набору.
Удаляет элементы, начиная с конца
набора.
Удаляет указанные элементы из
набора.
Спецификации доступа
Спецификации доступа — это директивы компилятора,
запрещающие указанному методу доступ к объектам базы
данных. Их назначение аналогично назначению так называемых "уровней чистоты" для пакетных функций PL/SQL, которые можно использовать в SQL-запросах (подробно об этом
рассказывается в разделе "PL/SQL — процедурное расширение языка SQL"). Спецификации доступа перечислены в таблице 38.
Таблица 38. Спецификации доступа
Директива
WNDS
478
Ограничения
Данному методу запрещена
модификация данных в таблицах
(представлениях) базы данных.
Объектные расширения в OracleS
WNPS
RNDS
RNPS
"
Данному методу запрещена
модификация пакетных переменных.
Данному методу запрещено чтение
данных из таблиц и представлений
базы данных.
Данному методу запрещено чтение
значений переменных, хранимых в
пакетах.
Указание спецификаций доступа при определении заголовка объектного типа позволяет потом не заботиться о том,
что при определении тел методов в них будут совершены действия, которые не являются необходимыми при работе этих
методов. Помимо некоторых моментов, связанных с реализацией механизма методов объектов в сервере Oracle, это важно
по следующим причинам.
Определять заголовок объектного типа и тела его методов могут разные пользователи. При определении спецификаций доступа не будет возможности осуществлять действия,
создающие угрозу безопасности данным. Все запросы, исполнение которых производится во время работы метода, исполняются с привилегиями пользователя, создавшего тип, или
пользователя, использовавшего данный тип (при применении
динамического SQL). В дальнейшем Oracle планирует предоставить возможность указания привилегий конкретного
пользователя (создавшего метод или его вызвавшего).
В листинге 258 приведен пример попытки создания тела
объектного типа с двумя методами, обладающими различными спецификациями доступа, функция fl не должна модифицировать информацию из базы данных, а функция f2 не
должна читать данные из таблиц и представлений. Как следует из примера, на этапе компиляции обнаруживается, что
функция f2 не соответствует своим ограничениям (осуществляет выборку данных из таблицы dual).
479
Раздел 8
SQL> CREATE OR REPLACE TYPE Ot7 AS OBJECT
2 (Atl NUMBER,
3 At2 DATE,
4 At3 DATE,
5 MEMBER FUNCTION fl RETURN NUMBER,
6 MEMBER FUNCTION f2 (pi IN NUMBER) RETURN
VARCHAR2,
7 PRAGMA RESTRICT_REFERENCES (fl,WNDS),
8 PRAGMA RESTRICT_REFERENCES (f2, RNDS) -) ;
9 ./
Type created.
, SQL> CREATE OR REPLACE TYPE BODY Ot7 IS
2 MEMBER FUNCTION f1 RETURN NUMBER AS
3 BEGIN
4
RETURN TRUNC(At3-At2);
5 END;
6
7 MEMBER FUNCTION f2 (pi IN NUMBER) RETURN
VARCHAR2 AS
8 1 NUMBER;
9 BEGIN
10
SELECT COUNT(1) INTO 1 FROM dual;
11 END;
12 END;
/
Warning: Type Body created with compilation errors .
SQL> show errors
Errors for TYPE BODY OT7:
1
LINE/COL ERROR
7/8
PLS-00452: Subprogram 'f2' violates its
associated pragma
Листинг 258. Пример попытки создания тела объектного типа, одна из функций которого нарушает свою спецификацию доступа
480
,
'.
Объектные расширения в OracleS
Объектные представления
Объектные представления позволяют обращаться к данным из реляционных таблиц. Обычно они используются, если
приложение не допускает изменения структуры таблиц и необходимо организовать поддержку объектов в базе данных.
При создании объектного представления с помощью конструкции WITH OBJECT OID указывается идентификатор объекта. В следующем примере данные хранятся в реляционной
таблице ТаЬб, а объектное представление
Ovl
содержит
один столбец предварительно созданного типа Ot5.
SQL> CREATE OR REPLACE TYPE Ot5 AS OBJECT
2
3
4
Type
(Atl NUMBER,
At2 VARCHAR2(40));
/
created.
SQL> CREATE TABLE Tab6
2 (Atl NUMBER,
3
At2 VARCHAR2(40));
Table created.
SQL>
2
3
View
CREATE OR REPLACE VIEW Ovl OF Ot5
WITH OBJECT OID(Atl)
AS SELECT Atl,At2 FROM Tab6;
created.
SQL> INSERT INTO ТаЬб VALUES (1,'A1);
1 row created.
SQL> SELECT VALUE(v) FROM Ovl v;
VALUE(V)(ATI, At2)
OT5(1, 'A')
Листинг 259. Пример, иллюстрирующий создание объектного представления, над реляционной таблицей и выборку объектов из него.
481
Раздел 8
Важной особенностью OracleS является появление нового
типа триггеров. Наряду с триггерами BEFORE и AFTER для
реляционных таблиц, новый тип триггеров INSTEAD OF
предназначен специально для объектных представлений. Этот
триггер срабатывает при попытке модификации данных с использованием объектного представления. В листинге 260
представлен сценарий создания такого триггера и его срабатывания при применении операторов модификации данных к
объектному представлению Ovl.
SQL> CREATE OR REPLACE TRIGGER Tr2.
2 INSTEAD OF INSERT ON Ovl
3 BEGIN
4
INSERT INTO ТаЬб VALUES(:NEW.Atl,:NEW.At2);
5 END;
6 /
Trigger created.
SQL> INSERT INTO Ovl VALUES ( 2 , ' B 1 ) ;
1 row created.
Листинг 260. Пример, иллюстрирующий создание объектного представления и выборку объектов из
него.
Триггер Тг2 срабатывает в момент вставки новой записи
и обновляет связанную с объектным представлением реляционную таблицу. С помощью этого вида триггеров для объектных представлений разработчик может гибко реализовать необходимую логику обновления объектно-реляционных данных.
482
Oracle 9i
Как и любая фирма, разрабатывающая программное
обеспечение, Oracle выпускает исправления (патчи) для текущих релизов сервера баз данных и других продуктов и время от времени (обычно с интервалом в несколько лет)
представляет новые версии программ. В первой половине
2001 г. (официальное объявление широкой публике
произошло в Англии в декабре 2000 г.) на рынке появилась
версия Oracle 9i. Это событие можно рассматривать гораздо
шире чем обычно, ведь изменениям подвергся не один
конкретный продукт, а все семейство. За словами Oracle 9i
стоят две ключевые технологии: Oracle 9i Application Server и
Oracle 9i Database.
Настоящая книга посвящена технологии баз данных
Oracle и не включает описание инструментальных средств
разработки, сервера приложений, комплексов анализа данных
и т. п. Поэтому остановимся кратко на основных особенностях Oracle 9i Database.
В основном они связываются с хранилищами данных и
аналитической обработкой информации. В состав Oracle 9i
Database включены средства добычи данных (data mining), a
так же средства извлечения, преобразования и загрузки (ETL)
для хранилищ данных. Средства ETL предназначены для
прямого обращения к внешним данным, например к текстовым файлам с помощью обычных SQL-операторов.
Предполагаются и новшества другого порядка. Так, в
Oracle 9i Database должна быть встроена поддержка
возможности
персонализации
в
реальном
времени.
Назначение этой возможности связано с позиционированием
сервера баз данных как платформы для электронной
коммерции. Персонализация посетителей Web-узла позволит
выдавать им рекомендации, основываясь на индивидуальных
профилях, хранимых в базе данных, и текущем поведении
пользователей.
483
Нововведения затронули и языковые средства Oracle.
SQL в Oracle 9i соответствует требованиям стандарта ANSI
SQL99. В язык введено много новых синтаксических конструкций. В SQL также появились новые типы данных, например, тип TimeStamp дает возможность хранить в базе данных
даты с точностью до долей секунды. Для аналитической обработки введены новые статистические функции, позволяющие выполнять операции, ранее специфичные для OLAPприложений, например, вычислять параметры тренда или выявлять зависимость двух выборок значений случайных величин.
Изменения появились и в PL/SQL. В основном они коснулись внутренней среды, обеспечивающей эффективное использование ресурсов сервера для работы PL/SQL-программ,
но появились и новые операторы, предназначенные, в частности, для работы с наследованием.
Сервер баз данных стал значительно интеллектуальнее.
Многие рутинные операции администрирования и конфигурирования теперь выполняются автоматически или максимально автоматизированы.
Применение Oracle 9i Database в электронной коммерции
предъявляет повышенные требования к системе безопасности. Для демонстрации защищенности web-узла, построенного на основе Oracle 9i, корпорация специально провела акцию
"Неуязвимый Oracle", предложив всем,желающим атаковать
свой сайт. Система виртуальных частных баз данных и проверка безопасности в контексте приложений предназначены
для активно развивающейся бизнес-схемы сдачи приложений
в аренду.
В завершение краткого изложения в духе "выше, дальше,
быстрее" следует отметить, что основные положения техноло^гий Oracle, представленные в книге, останутся актуальными и для 91 и для следующих релизов. Дело даже не в том, что
авторам хочется, чтобы их книга была востребованной в течении как можно большего времени, а в том, что уровень
языковых средств и механизмов сервера более чем за 20 лет
484
эксплуатации достиг в некотором смысле совершенства и
вряд ли будет заметно меняться в дальнейшем. Например,
вряд ли для генерации уникальных значений можно придумать механизм, работающий удобнее последовательностей
(sequence). Кроме того, существует огромное количество приложений и баз данных, работающих под управлением младших версий Oracle, для которых в силу каких-либо причин не
планируется переход на другие версии.
Также хочется отметить, что конкуренция на рынке корпоративных СУБД довольно велика и это обстоятельство
иногда заставляет производителей в целях захвата новых сегментов рынка, продвижения новых технологий и т. п. выпускать не до конца доведенные версии программных продуктов.
Первый релиз сервера баз' данных Oracle 9i содержит'серьезные ошибки (например, включение поддержки ANSIсинтаксиса для внешних соединений привело к тому, что любой пользователь получает возможность просмотра данных из
любой таблицы). Поэтому, как и для всего нового, требуется
некоторое время для широкомасштабной обкатки Oracle 9i
Database.
Всего же для подробного описания новых возможностей
Oracle 9i потребуется несколько книг. Поэтому специалистам,
желающим системно овладеть этими новыми, стремительно
развивающимися технологиями в области баз данных, можно
порекомендовать прослушать специально построенный набор
курсов в каком-либо авторизованном центре обучения Oracle
в соответствии с выбранной для себя специализацией. В настоящее время в этих центрах существуют программы подготовки администраторов, разработчиков приложений, проектировщиков и аналитиков. Вместе с тем хочется отметить,
что все без исключения наборы включают в себя подготовку
по SQL, PL/SQL, разграничению доступа и архитектуре сервера баз данных Oracle. Надеемся, что в изучении этой обязательной части вам поможет наша книга.
•:
,
ЯМ
-
.
485
Заключение
Перевернута последняя страница последнего раздела этой
книги. Настала пора подвести некоторые итоги. Прежде всего, есть смысл оценить степень усвоения материала книги,
проведя анализ степени достижения целей каждого раздела.
Основная задача, решаемая в первом разделе, — дать общее представление об архитектурах и компонентах распределенной системы обработки данных. Цель данного раздела
достигнута, если у читателя сформировано четкое представление об архитектуре сервера Oracle, его основных возможностях, различных архитектурах информационных систем,
организации локальных сетей, рассматриваемых как основа
распределенных систем обработки данных, общих принципах
конфигурирования сетевых средств Oracle, организации доступа к серверу базы данных.
Основная цель второго раздела — систематическое изложение языка SQL. Читателя, успешно усвоившего темы второго раздела, характеризует умение создавать и изменять основные объекты Oracle и управлять данными.
Читателя, овладевшего материалом третьего раздела, отличает умение создавать и отлаживать прикладные программы на языке PL/SQL. Для эффективной разработки программ
читатель получил сведения о стандартных пакетах, входящих
в комплект поставки сервера.
Полученные в первых трех разделах теоретические представления и навыки активно используются при обсуждении
методов и средств разграничения доступа и аудита Oracle,
рассмотренных в четвертом разделе.
• Итогом изучения пятого раздела должно стать умение
написать и интегрировать в систему обработки данных прикладную программу на языке Java и построить приложениеапплет для обеспечения доступа к серверу баз данных на основе универсального клиента.
486
Шестой раздел должен сформировать понимание концепции и основных методов обеспечения целостности базы данных в условиях многопользовательского доступа и умение
использовать соответствующие средства и утилиты Oracle.
Для углубления полученных знаний предназначен седьмой раздел о способах, повышающих скорость доступа к данным. Он должен предоставить знания, необходимые для эффективного применения изученных языковых средств для работы с большими и сверхбольшими базами данных.
Читатель, изучивший восьмой раздел, ознакомился с основным направлением развития современных технологий баз
данных. Объектные расширения предлагаются практически
всеми крупными поставщиками решений в этой области и
Oracle не исключение.
Что же делать дальше?
Во-первых, продолжать изучение литературы. В последнее время вышло большое количество книг о современных
технологиях обработки данных в системах промышленного
уровня. Ряд издательств выпускает серии книг, предназначенных для профессиональных разработчиков, проектировщиков, администраторов, других специалистов, работающих
с Oracle. Специальные серии ориентированы на начинающих
пользователей. Издательство "Гелиос" также планирует продолжить публикации учебных материалов по технологиям и
продуктам Oracle.
Во-вторых, использовать для пополнения и совершенствования своих знаний практически неограниченные информационные ресурсы Internet. В настоящее время количество
Web-серверов, содержащих информацию о технологиях и
продуктах Oracle, постоянно увеличивается. Выходят электронные версии специализированных журналов. В различных
конференциях и форумах можно задать интересующие вопросы или найти готовые решения. Адреса некоторых Webресурсов приведены ниже.
В-третьих, (в перечислении, но не по значимости) постоянно практиковаться в решении конкретных задач. Решение
487
бесконечно многообразных и постоянно возникающих задач
обработки информации есть не только способ зарабатывать
на жизнь, но и источник самосовершенствования. Изящное
решение сложных задач, которых множество в сфере обработки данных, может принести и приносит незабываемое эстетическое наслаждение.
Нам же остается пожелать Вам успехов в освоении и построении систем распределенной обработки информации на
базе технологий Oracle.
Литература
1.
2.
3.
4.
5.
6.
7.
8.
Бобровски С. OracleS. Архитектура. — М.: ЛОРИ, 1999.
Пейдж Б., ХьюзН., Остин Д. Использование OracleS. —
К.; М.; СПб.: Вильяме, 1998.
Баженова И. Ю. Oracle 8/8i. Уроки программирования.
— М.: Диалог-МИФИ, 2000.
Урман С. OracleS. Программирование на языке PL/SQL.
— М.: Изд-во ЛОРИ, 1999. .
Эбби М., Кори М. OraeleS: Первое знакомство. — М.:
ЛОРИ, 1998.
Энсор Д., Стивенсон И. Oracle. Проектирование баз
данных. — К.: BHV, 1999.
Koch G., Loney К, OracleS; The complete Reference. —
Osborne/McGraw-Hill, 1997.
Theriault M.,
Heney
W.
Oracle
Security.
—
O'Reilly&Associates, Inc., 1998.
Адреса основных Web- серверов Internet, содержащих информацию о технологиях, продуктах Oracle и опыте их использования.
Адрес в сети Internet
Описание Web-сервера
www.oracle.com
Web-сервер корпорации
Oracle
www.oracle.com/ru/oramag Web-сервер журнала Oracle
Magazine (RE)
www.oracle.ru
Web-сервер представительства корпорации Oracle в РФ
www.fors.ru
Web-сервер фирмы ФОРС
(Москва)
www.interface.ru
Web-сервер фирмы Interface
Ltd. (Москва)
www.rdtex.ru
Web-сервер фирмы RDTeX
(Москва)
Содержание
Азбука Oracle
3
Предисловие ко второму изданию
8
Благодарности
..12
Раздел 1. Архитектура распределенных систем обработки
данных
13
Средства обработки данных: эволюция идей и систем
13
Эволюция реляционных СУБД на фоне истории Oracle
18
OracleS. Основные возможности..
:
20
Архитектуры обработки данных
27
Локальные вычислительные сети как среда передачи данных
33
Эталонная модель взаимодействия открытых систем
35
Компоненты распределенной системы и ЭМВОС..;
41
Конфигурирование сетевых компонент Oracle.
43
Архитектура сервера Oracle
48
Использование инструментального средства SQL*Plus
54
Информация о результатах операции
60
Поддержка мультиязычности в Oracle
62
Соглашения, принятые для описания команд..
65
Раздел 2. SQL — язык обработки данных Oracle
66
Основные объекты Oracle
67
Средства манипулирования данными языка SQL ,
73
Структура запроса
74
Простейшие запросы:
74
Формирование критерия отбора,
..77
Базовые средства определения критерия отбора
,
79
Язык описания данных Oracle
81
Типы данных Oracle
82
Строки символов
82
Числовые типы
84
TnnROWID
86
Битовые строки
87
Дата и время
88
LOB-объекты
90
Таблицы. Представления. Пользователи
91
Создание и удаление таблиц в Oracle
91
Средства определения и уничтожения представлений
97
Средства регистрации и исключения пользователей
103
4.91
Операция вставки строк...
Операция удаления строк
Операция модификации строк
!
Специальные предикаты SQL
Предикат IN
Предикат BETWEEN
Предикат LIKE
Предикат IS NULL
Предикат EXISTS
Предикаты с кванторами ALL, ANY и SOME
Теоретико-множественные операции
Внешнее объединение
Сортировка
Иерархии
Группирование и агрегатные функции
Синтаксис языка запросов
Связи с удаленными базами данных. Снимки данных
Создание связей с удаленной базой данных Oracle
Средства определения и уничтожения снимков
Последовательности. Синонимы
Создание последовательностей
Создание синонимов в Oracle
Работа с табличными областями в Oracle
;
107
109
111
112
113
114
116
118
120
121
122
125
128
130
133
139
143
143
146
151
151
157
161
Раздел 3. PL/SQL — процедурное расширение языка SQL..... 165
Структура программы на PL/SQL
166
Переменные, константы и типы„
167
Управление выполнением программы
169
Оператор ветвления
170
Операторы цикла
171
Оператор GOTO
.....174
Курсоры
174
Обработка исключительных ситуаций
*...
182
Процедуры, функции и пакеты
188
SQL-функции Oracle
189
Функции, устанавливающие соответствие числовых кодов и
символов
189
Функции преобразования символов подстрок
190
Символьные функции усечения и дополнения строк
192
Символьные функции преобразования строк
194
492
Функции, связанные с выделением подстрок
195
Числовые функции, связанные с возведением в степень и
логарифмированием
197
Тригонометрические функции
198
Числовые функции, связанные с округлениями
200
Числовые функции, связанные со знаком числа
201
Числовые функции, связанные с модулярной арифметикой....202
Функции, оперирующие с датами
203
Функции преобразования типов данных
205
Функции замены аргументов
208
Справочные функции
211
Создание пользовательских процедур и функций
213
Пакеты
.-.
;
220
Триггеры базы данных
:
....228
Стандартные пакеты Oracle
238
Динамический SQL.
,
238
Файловый ввод-вывод
,....:
.....245
Управление заданиями
248
Управление LOB-объектами
'.
252
Управление многопользовательским доступом
258
Использование функций PL/SQL в SQL-выражениях
262
Раздел 4. Средства разграничения доступа в Oracle
264
Анализ включающей инфраструктуры
266
Идентификация пользователей..
270
Базовое понятие системы разграничения доступа—
привилегии
272
Предоставление системных привилегий
274
Системные привилегии, определяющие права по работе с
таблицами и представлениями
275
Системные привилегии, определяющие права по работе с
процедурами и триггерами.
279
Системные привилегии, определяющие права по работе с
пользователями
282
Системные привилегии, определяющие права по работе с
табличными областями
283
Системные привилегии, определяющие права по работе с
последовательностями...
285
Системные привилегии, определяющие права по работе с
синонимами
286
'
493
Системные привилегии, определяющие права по
выполнению глобальных действий в системе
288
Системные привилегии, определяющие права по
выполнению действий с остальными объектами БД...
288
Использование конструкции PUBLIC и параметра WITH
ADMIN OPTION
,
.292
Предоставление привилегий доступа к объекту
295
Управление привилегиями с помощью ролей
300
Системные привилегии, определяющие права по работе с
ролями
301
Предопределенные роли в Oracle
302
Создание ролей и предоставление им привилегий
304
Управление допустимостью использования ролей
305
Отмена привилегий
308
Отмена системных привилегий и ролей
308
Отмена привилегий доступа к объекту,
309
Использование представлений для разграничения доступа
310
Хранимые процедуры как средство разграничения доступа
312
Использование триггеров для повышения защиты системы
314
Средства аудита
319
Аудит системных событий
320
Аудит событий, связанных с доступом к объекту
.....327
Прекращение регистрации событий
330
Обработка данных аудита
332
Профили пользователя как средство повышения
защищенности системы
337
Дополнительные сведения....:
340
Раздел 5. Создание приложений на языке Java
Средства построения приложений и организации доступа к
базам данных
Создание приложений на языке Java
Простейшее приложение на Java
Простейший апплет
Выполнение SQL-операторов создания таблиц, ввода и
модификации данных
^
Простая выборка данных
Параметрические запросы
Хранимые процедуры на языке Java
494
..342
342
344
345
349
353
357
362
366
Раздел 6. Средства обеспечения целостности данных
376
Определение транзакции и ее роль в СУБД
,
....378
Начало и окончание транзакции
...379
Предложения SQL, управляющие транзакциями
380
Предложение COMMIT WORK
381
Использование предложения SAVEPOINT
...383
Предложение ROLLBACK WORK
383
Непротиворечивость и параллельная обработка
385
Типы блокировок
391
Ограничения целостности
..393
Массовая загрузка данных
403
Экспорт/импорт данных
409
Раздел 7. Методы повышения производительности
417
Оптимизатор
,...,
418
Ранжирование методов доступа
420
Анализ запросов с целью повышения скорости их выполнения ...423
Задание режима оптимизации
424
Обзор индексов Oracle
.......427
Эффективное кодирование SQL-выражений
433
Изменение плана выполнения запроса
437
Секционирование таблиц
445
Секционирование индексов
449
Операции с секциями....
451
Индекс-таблицы,....
453
Раздел 8. Объектные расширения в OracleS
455
Объектные типы
456
Объекты в базе данных
461
Ссылки на объекты..
466
Массивы
470
Вложенные таблицы
474
Спецификации доступа
478
Объектные представления
481
Oracle 9i..
'.
,
483
Заключение
....'.
486
Литература
489
Содержание
491
495
•
Учебное издание
Смирнов Сергей Николаевич, Задворьев Иван Сергеевич
Работаем с Oracle
Корректор £ Н. Клитина
ЛР № 066255 от 29.12.98. Издательство «Гелиос АРВ». www.gelios-arv.ru
107014, Москва, Верхняя Красносельская, 16. Тел. (095)264-44-39, e-mail: info@gelios-arv.ru.
Формат 84x108/32. Бумага газетная. 15,5 п. л. Тираж 3 000 экз. Заказ № 1628.
Отпечатано с готовых диапозитивов в РГУП «Чебоксарская типография № 1».
Адрес типографии: 428019, г. Чебоксары, пр. И. Яковлева, 15.
Download