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



              

Имена объектов, ключевые и зарезервированные слова - часть 3


Table created.

SQL> UPDATE t1 SET begin = 1;

0 rows updated.

SQL> BEGIN UPDATE t1 SET begin = 2; END; 2 /

PL/SQL procedure successfully completed.

SQL> DECLARE begin NUMBER; BEGIN NULL; END; 2 / DECLARE begin NUMBER; BEGIN NULL; END; * ERROR at line 1: ORA-06550: line 1, column 38: PLS-00103: Encountered the symbol "end-of-file"
when expecting one of the following: ... ... ... ...

(Но, конечно же:

SQL> DECLARE "begin" NUMBER; BEGIN NULL; END; 2 /

PL/SQL procedure successfully completed.

)

Однако жизнь бывает сложнее, чем иногда хотелось бы. Вопреки утверждению документации по Oracle (сказали разработчики PL/SQL) не все ключевые слова являются зарезервированными. Вызвано это тем, что язык живет, и в нем могут появляться новые ключевые слова, которые кто-то, когда они еще не были ключевыми, мог использовать для названий объектов. Запрет вдруг их такового употребления способен был бы вызвать возмущение пользователей, принужденных переделывать имеющиеся БД и приложения. Отсюда и отклонения от идеального равенства "ключевые слова" = "зарезервированные слова". Нагладный пример: до версии 9 в Oracle не было типа TIMESTAMP, и многие использовали это слово для именования поля в таблице. В версии 9 эту вольность (по законам новой версии) употребления пришлось оставить, хотя и удалось это не совсем последовательно:

SQL> ALTER TABLE t1 ADD (timestamp TIMESTAMP);

Table altered.

SQL> UPDATE t1 SET timestamp = SYSTIMESTAMP;

SQL> DECLARE t TIMESTAMP; BEGIN t := SYSTIMESTAMP; END; 2 /

PL/SQL procedure successfully completed.

SQL> DECLARE timestamp NUMBER; BEGIN timestamp := 1; END; 2 /

PL/SQL procedure successfully completed.

но, правда

SQL> DECLARE timestamp TIMESTAMP; BEGIN timestamp := NULL; END; 2 / DECLARE timestamp TIMESTAMP; BEGIN timestamp := NULL; END; * ERROR at line 1: ... ... ... ...

Есть в Oracle и другое правило, уже наблюдавшееся выше по тексту: и в SQL, и в PL/SQL заключение имени объекта в двойные кавычки сравнение со списком зарезервированных слов отменяет:

SQL> DECLARE "timestamp" TIMESTAMP; BEGIN "timestamp" := NULL; END; 2 /

PL/SQL procedure successfully completed.

Это и объясняет срабатывание примера, с которого начался этот раздел, при замене "NUMBER" вместо NUMBER.

Все это можно понять. А остался ли за Oracle какой-нибудь грех ? Не без того. Разработчики PL/SQL признались: несмотря на то, что с версии 9 обработка SQL в PL/SQL и в качестве самостоятельных команд происходит одинаково, список зарезервированных слов в PL/SQL свой (по-прежнему) собственный, и, как оказалось, не всегда совпадает со аналогичным списком в SQL там, где он бы должен совпадать. Это и привело к непредусмотренному архитекторами Oracle результату при попытке обратиться к полю "NUMBER" в PL/SQL. Иными словами, это ошибка разработчиков, которая сохранилась в нынешней версии 10.1, и которую пообещали исправить в будущем.




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