|
Навигация
|
Главная » Sql Заморочки от Oracle, или знать бы, где упасть…Владимир Пржиялковский "...да вот веревкой хочу море морщитьДа вас, проклятое племя, корчить" А. С. Пушкин, Сказка о попе и его работнике Балде Оглавление
Эта заметка продолжает серию статей о возможностях Oracle, но выбор самих возможностей необычен. Речь пойдет о неудобных или даже неприятных возможностях - хотя бы и потенциально неприятных. Признаться, некоторые колебания в целесообразности подобной публикации у меня были, но ведь многие читатели доверяют СУБД Oracle самое святое - бизнес, и поэтому знать, откуда ждать беду они просто обязаны. В более безобидном варианте знание некоторых "заморочек от Oracle" способно улучшить ваше понимание этой системы. Рекурсивные вызовы PL/SQL в Oracle относится к языкам, в которых рекурсивные вызовы подпрограмм разрешены . В теле одной подпрограммы можно обратиться к самой себе, или же, например, к другой, а та, в свою очередь к первой. Рекурсия иногда удобна. Пример из учебников - вычисление факториала. Более жизненный пример - размечивание весами древовидной структуры, позволяющее организовать быстрый доступ к хранимому в БД справочнику без привлечения нестандартных и несовместимых конструкций (в Oracle это конструкция CONNECT BY). Особенность в том, что машина PL/SQL в СУБД Oracle никак не регламентирует глубину повторных обращений, что оставляет лазейку "бесконечного" зацикливания. Ответственность за его возникновение СУБД перекладывает на программистов. Хуже того, организовать такое зацикливание может любой пользователь, обладающий всего только-то привилегией CREATE SESSION:
Во-первых, сеанс пользователя ADAM начинает жадно расходовать процессорное время. Другие сеансы связи с СУБД это сразу почувствуют. Во-вторых, сеанс пользователя ADAM начинает неумолимо захватывать оперативную память во все больших и больших количествах. Пусть не сразу, но другие сеансы связи с СУБД почувствуют и это. Если ваша база загружена какой-то реальной работой, проделанная простая операция - эффективный способ дезорганизовать эту работу. У меня ни разу не хватило терпения дождаться, когда Oracle исчерпает всю оперативную память, и проверить его способность самому переварить проблему. Но если не предпринять заблаговременных мер по нейтрализации подобных диверсий, даже естественная попытка убить вредоносный сеанс не будет простой. Сначала из-за страшно медленной реакции СУБД на ваши действия от имени SYS, а потом из-за страшно медленного освобождения памяти после команды ALTER SYSTEM KILL SESSION. Вопрос, стоило ли разработчикам Oracle оставлять возможность неограниченной рекурсии, способен разжечь спор. Но сделано то, что сделано: Oracle награждает нас здесь одновременно со свободой действий и риском потери нормальной работы СУБД. Как сделать функцию невидимой Следующий пример показывает архитектурное упущение создателей Oracle. Оно обязано одному из недальновидных решений, принятых в первых версиях Oracle, очевидно в угоду скорости утверждения на рынке. Позже, подобно некоторым другим сходным в этом отношении "ранним" решениям Oracle, исправить положение дел уже не представилось возможным. К счастью, проблема неожидаемой маскировки объекта в БД, о которой пойдет речь, довольно специфична. Однако ж она вполне реальна. Рассмотрим пример функции в схеме SCOTT:
Закономерно возникает вопрос: а как при обращении к EMP выдать значение функции ENAME? Несложные эксперименты приводят к необходимости указать полное имя функции, снабдив его именем схемы:
Способ формирования составных имен не идеален и в других языках. Например, даже в таком архитектурно продуманном языке, как Java, понять по тексту смысл каждой компоненты в имени java.lang.System.out.println без дополнительной информации невозможно. Но другой системы, кроме Oracle, где допускалось бы исчезновение видимости имени одного объекта вследствие вполне законного заведения других, мне неизвестно. Имена объектов, ключевые и зарезервированные слова История этой задачки началась с форума Oracle на www.sql.ru, куда я однажды случайно забрел. Один из участников форума пытался перенести в Oracle схему БД, подготовленную в другой системе. В таблице было поле, названное NUMBER. Очевидно, в нем хранилось какое-то число; с этим-то полем в Oracle и случилась незадача. Ее раскрывает следующий (уже мой) пример:
Неужели перенося базу в Oracle придется править схему, а значит и приложение? Если не выход, то лазейку из положения автор вопроса в форум нашел правильно. Заключив имя объекта в Oracle в двойные кавычки, мы приобретем право использовать абсолютно любые доступные в кодировке символы, хоть звездочки, хоть точки, хоть пробелы:
Заинтересовавшись, после серии экспериментов я нащупал очередную уступку Oracle, позволившую достичь компромисса, но сообщить найденное решение автору вопроса уже не смог, так как sql.ru оказался для меня слишком сложно устроен: он не только требует регистрации (а придуманные себе кличку и пароль я назавтра же забыл), но и содержит чересчур много "нитей", среди которых "свою" я безнадежно потерял. Вот что выяснилось: PL/SQL начинает все обрабатывать правильно, как только в названии столбца появляется хотя бы одна малая буква, например, не "NUMBER", а "NuMBER". Лучше, конечно, "number". Возникает вопрос: в чем причина такого странного поведения? Переписка с разработчиками PL/SQL несколько прояснила ситуацию. Можно посочувствовать: им приходится расплачиваться по счетам самой логики жизни. В любом языке есть множество зарезервированных слов, которые нельзя использовать для имен объектов. В Oracle первую очередь это ключевые слова: BEGIN, SELECT и другие. Заметьте кстати, что множества зарезервированных слов Oracle в SQL и PL/SQL не совпадают:
Однако жизнь бывает сложнее, чем иногда хотелось бы. Вопреки утверждению документации по Oracle (сказали разработчики PL/SQL) не все ключевые слова являются зарезервированными. Вызвано это тем, что язык живет, и в нем могут появляться новые ключевые слова, которые кто-то, когда они еще не были ключевыми, мог использовать для названий объектов. Запрет вдруг их такового употребления способен был бы вызвать возмущение пользователей, принужденных переделывать имеющиеся БД и приложения. Отсюда и отклонения от идеального равенства "ключевые слова" = "зарезервированные слова". Наглядный пример: до версии 9 в Oracle не было типа TIMESTAMP, и многие использовали это слово для именования поля в таблице. В версии 9 эту вольность (по законам новой версии) употребления пришлось оставить, хотя и удалось это не совсем последовательно:
Все это можно понять. А остался ли за Oracle какой-нибудь грех? Не без того. Разработчики PL/SQL признались: несмотря на то, что с версии 9 обработка SQL в PL/SQL и в качестве самостоятельных команд происходит одинаково, список зарезервированных слов в PL/SQL свой (по-прежнему) собственный, и, как оказалось, не всегда совпадает с аналогичным списком в SQL там, где он бы должен совпадать. Это и привело к непредусмотренному архитекторами Oracle результату при попытке обратиться к полю "NUMBER" в PL/SQL. Иными словами, это ошибка разработчиков, которая сохранилась в нынешней версии 10.1, и которую пообещали исправить в будущем. Заключение По сути, это заключение является лирическим отступлением, на мой взгляд, способным несколько сгладить то негативное мнение о СУБД Oracle, которое способна породить эта статья. Дело в том, что среди писем от разработчиков, которые я получил, расследуя последнюю описанную проблему, неожиданно оказалось письмо от Кена Джекобса. Напомню, это вице-президент компании Oracle, второй по размеру в области разработки ПО. Конечно, не он дал исчерпывающий ответ, это сделал другой специалист (к слову сказать, тоже не низшей должности), но он обратил внимание на проблему. Сам факт такой реакции мне показался крайне симпатичным и симптоматичным. Представьте себе компанию с оборотами в десятки миллиардов долларов, на втором уровне иерархии управления которой имеются технические специалисты, а не специалисты по рекламе, связям с общественностью и организации денежных потоков! Это так непохоже на некоторые соразмерные Oracle однопрофильные компании и (увы) на все отечественные (за отсутствием таковых, соответственно другого профиля). Конкретно меня такое положение дел побуждает смотреть сквозь пальцы на грехи разработчиков Oracle (по крайней мере, отчасти). И все же: если у вас есть что добавить в приведенную выше коллекцию, буду рад получить письмо. Спецификации SQL Server 2012. Вычисление производительности выпуска SQL Server. Как создать блог на платформе WordPress?. Объектно-ориентированное программирование в языке PHP. Использование хэш-ключей вместо строковых индексов. Мониторинг использования индексов в планах запросов в Oracle 10g. Главная » Sql |
© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено. |