Идентификатор — это имя объекта данных PL/SQL, которым может быть:
- константа или переменная;
- исключение;
- курсор;
- имя программы: процедура, функция, пакет, объектный тип, триггер и т. д.;
- зарезервированное слово;
- метка.
Идентификаторы PL/SQL обладают следующими свойствами:
- длина — до 30 символов;
- должны начинаться с буквы;
- могут включать символы «$», «_» и «#»;
- не должны содержать пропусков.
Если два идентификатора различаются только регистром одного или нескольких символов, PL/SQL обычно воспринимает их как один идентификатор. Например, следующие идентификаторы считаются одинаковыми:
lots_of_$MONEY$ LOTS_of_$MONEY$ Lots_of_$Money$
Примеры допустимых имен идентификаторов:
company_id# primary_acct_responsibility First_Name FirstName address_line1 S123456
Идентификаторы, приведенные ниже, в PL/SQL недопустимы:
1st_year -- Не начинается с буквы procedure-name -- Содержит недопустимый символ "-" minimum_%_due -- Содержит недопустимый символ "%" maximum_value_exploded_for_detail -- Имя слишком длинное company ID -- Имя не может содержать пробелов
Идентификаторы используются для обращения к элементам программы и являются одним из основных средств передачи информации другим программистам. По этой причине во многих организациях принимаются стандартные правила выбора имен; даже если в вашем проекте такие правила отсутствуют, имена все равно должны быть содержательными... даже если вы будете единственным человеком, который когда-либо увидит код!
Некоторые из правил именования объектов можно нарушить, заключая идентификатор в кавычки. Мы не рекомендуем пользоваться этим методом, но когда-нибудь вам может встретиться хитроумный код вроде следующего:
SQL> DECLARE 2 "pi" CONSTANT NUMBER := 3.141592654; 3 "PI" CONSTANT NUMBER := 3.14159265358979323846; 4 "2 pi" CONSTANT NUMBER := 2 * "pi"; 5 BEGIN 6 DBMS_OUTPUT.PUT_LINE('pi: ' || "pi"); 7 DBMS_OUTPUT.PUT_LINE('PI: ' || pi); 8 DBMS_OUTPUT.PUT_LINE('2 pi: ' || "2 pi"); 9 END; 10 / pi: 3.141592654 PI: 3.14159265358979323846 2 pi: 6.283185308
Обратите внимание: в строке 7 идентификатор pi используется без кавычек. Поскольку компилятор преобразует все идентификаторы и ключевые слова в верхний регистр, данный идентификатор относится к переменной, объявленной в строке 3 под именем PI.
Иногда прием с кавычками применяется в SQL-инструкциях для ссылки на таблицы базы данных, имена столбцов которых содержат символы разных регистров (например, если программист использовал Microsoft Access для создания таблиц Oracle).
Зарезервированные слова
Конечно, выбор идентификаторов в программе нельзя назвать полностью произвольным. Некоторые идентификаторы (такие, как BEGIN, IF и THEN) имеют в языке PL/SQL специальное значение.
В PL/SQL встроенные идентификаторы делятся на два вида:
- ключевые слова;
- идентификаторы пакета STANDARD.
Вы не должны (а в большинстве случаев и не сможете) использовать их в качестве имен объектов, объявляемых в своих программах.
Ключевые слова
Некоторые идентификаторы с точки зрения компилятора PL/SQL имеют строго определенную семантику. Иначе говоря, вы не сможете определить переменную с именем идентификатора. К таковым относится, например, слово END, завершающее программу, условная команда IF и команды цикла. При попытке объявить переменную с именем end:
DECLARE end VARCHAR2(10) := 'blip'; /* не работает; "end" нельзя использовать в качестве имени переменной. */ BEGIN DBMS_OUTPUT.PUT_LINE (end); END; /
компилятор выдает сообщение об ошибке:
PLS-00103: Encountered the symbol "END" when expecting one of the following: ...
Идентификаторы пакета STANDARD
Также не следует использовать в качестве идентификаторов имена объектов, определенные в специальном встроенном пакете STANDARD — одном из двух стандартных пакетов PL/SQL. В нем объявлено большое количество основных элементов языка PL/SQL, включая типы данных (например, PLS_INTEGER) идентификаторов — имена встроенных исключений (DUP_VAL_ON_INDEX и т. д.), функций (например, UPPER, REPLACE и TO_DATE).
Вопреки распространенному мнению, идентификаторы пакета STANDARD (и DBMS_STANDARD, другого стандартного пакета) не являются ключевыми словами. Вы можете объявлять собственные переменные с такими же именами, и программа успешно откомпилируется. Тем не менее это создаст изрядную путаницу в вашем коде.
Как избежать использования зарезервированных слов
Поиск допустимого имени для идентификатора — далеко не самая серьезная проблема, так как существуют многие тысячи комбинаций допустимых символов. Вопрос в другом: как узнать, не используете ли вы зарезервированное слово в своей программе? Прежде всего компилятор сообщит о попытке использования зарезервированного слова в качестве идентификатора. Если ваша любознательность этим не ограничивается, постройте запрос к представлению V$RESERVED_WORDS и попробуйте откомпилировать динамически построенный блок PL/SQL, использующий зарезервированное слово в качестве идентификатора. Я так и поступил; соответствующий сценарий хранится в файле reserved_words. sql на сайте книги. Выходные данные сценария находятся в файле reserved.txt.
Результаты очень интересны. Общая сводка выглядит так:
Reserved Word Analysis Summary Total count in V$RESERVED_WORDS = 1733 Total number of reserved words = 118 Total number of non-reserved words = 1615
Итак, подавляющее большинство слов, которые Oracle включает в это представление, не являются формально зарезервированными; эти слова могут использоваться в качестве имен идентификаторов.
В общем случае я рекомендую избегать тех слов, которые Oracle Corporation использует в своих технологиях. А еще лучше — используйте правила назначения имен, основанные на последовательном применении префиксов и суффиксов. Такие схемы практически исключают случайное использование зарезервированных слов PL/SQL.
Пропуски и ключевые слова
Идентификаторы необходимо отделять друг от друга хотя бы одним пробелом или разделителем. Вы можете форматировать текст программы, вставляя дополнительные пробелы, разрывы строк и табуляции во всех местах, где могут находиться пробелы, — смысл кода при этом не изменится.
Например, две приведенные ниже команды эквивалентны:
IF too_many_orders THEN warn_user; ELSIF no_orders_entered THEN prompt_for_orders; END IF; IF too_many_orders THEN warn_user; ELSIF no_orders_entered THEN prompt_for_orders; END IF;
С другой стороны, пробелы, табуляции и разрывы строк недопустимы внутри лексических единиц — таких, как оператор «не равно» (!=). Следующая команда приводит к ошибке компиляции:
IF max_salary ! = min_salary THEN -- ошибка компиляции PLS-00103
потому что символы ! и = разделены пробелом.