Базы данных Oracle - статьи


           

Как сделать функцию невидимой


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

К счастью, проблема неожидаемой маскировки объекта в БД, о которой пойдет речь, довольно специфична. Однако ж она вполне реальна.

Рассмотрим пример функции в схеме SCOTT:

SQL> CREATE FUNCTION ename RETURN VARCHAR2 AS 2 BEGIN RETURN 'I am a function'; END; 3 /

Function created.

Это не запрещено, несмотря на наличия поля ENAME в одной из таблиц схемы, так как пространства имен функций и столбцов не пересекаются (и правильно !). Но что произойдет, если к ней обратиться при выборке данных из таблицы EMP ? Если выполнить следующий запрос, что мы увидим: столбец или функцию ?

SELECT ename FROM emp;

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

Закономерно возникает вопрос: а как при обращении к EMP выдать значение функции ENAME ? Несложные эксперименты приводят к необходимости указать полное имя функции, снабдив его именем схемы:

SELECT scott.ename, ename FROM emp;

Или же (что в некоторых смыслах более правильно)

SELECT scott.ename, emp.ename FROM emp;

Крайне неудачная система обозначений (в SCOTT.ENAME SCOTT - это имя схемы, а в такой же по виду записи EMP.ENAME EMP - это имя таблицы), но свое дело она делает. К сожалению, этим дело не кончается. Пространства имен схем и пакетов тоже разные, что тоже правильно. Рассмотрим теперь следующее:

CREATE OR REPLACE PACKAGE scott IS FUNCTION ename
RETURN varchar2; END scott; /

CREATE OR REPLACE PACKAGE BODY scott IS FUNCTION ename RETURN varchar2 IS BEGIN RETURN 'I am a package function'; END ename; END scott; /

SELECT scott.ename FROM emp;

Убедитесь, что получим 'I am a package function'. Но теперь, обращаясь к EMP мы никогда не увидим результат самостоятельной (не пакетированной) функции ENAME ! Если в вашем приложении были запросы типа SELECT scott.ename FROM emp, то после создания пакета они начнут выдавать попросту другой ответ.

Способ формирования составных имен не идеален и в других языках. Например, даже в таком архитектурно продуманном языке, как Java, понять по тексту смысл каждой компоненты в имени java.lang.System.out.println без дополнительной информации невозможно. Но другой системы, кроме Oracle, где допускалось бы исчезновение видимости имени одного объекта вследствие вполне законного заведения других, мне неизвестно.



Содержание  Назад  Вперед





Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий