Оракл для начинающих. Советы программистам, администраторам, IT-специалистам, только начинающим изучать СУБД Oracle. Оракл для чайников.
Таблица DUAL и для чего она нужна
В Oracle, в отличие от того же MS SQL Server, нельзя сделать запрос «из ниоткуда».
SELECT 1
*
ERROR at line 1:
ORA-00923: FROM keyword not found where expected
Поэтому в большинстве запросов должна быть ссылка на таблицу или представление. Как правило, для таких запросов используется таблица DUAL. Таблица DUAL — это реальная таблица в схеме SYS, содержащая только одну запись.
SELECT * FROM DUAL;
1 rows selected
Как можно использовать таблицу DUAL в запросах? К примеру мы хотим получить системное время. Тогда, раз что-то во FROM указывать надо — укажем таблицу DUAL:
И.Гершанов с комментарием А.Бачина
Наш читатель Илья Гершанов написал в редакцию:
В недавней апрельской статье «Предупреждение проблем с таблицей DUAL», раздел «Опыт пользователей», написано, что если в таблице DUAL может оказаться более одной строки или не оказаться строк вовсе, то могут возникнуть проблемы.
Однако, буквально несколько дней назад в учебнике «Введение в Oracle SQL и PL/SQL» (410010RU11) на стр. 3-16 я прочел легко запоминающееся, просто афористичное определение таблицы DUAL: «DUAL — это фиктивная таблица, используемая для просмотра SYSDATE». Лучше не скажешь.
Но, раз таблица фиктивная, то у нее нет сегмента, то и речи быть не может о добавлении строк. Был проведен эксперимент:
1. Запуск экземпляра в режиме » startup nomount » и запрос:
SVRMGR> select * from dual;
ADDR INDX INST_ID D
2. Перевод экземпляра в режим » alter database mount; » и запрос
SVRMGR> select * from dual;
ADDR INDX INST_ID D
3. Перевод экземпляра в работоспособное состояние » alter database open; » и запрос
SVRMGR> select * from dual;
То есть в пути от nomount к open табличка успела поменяться. Таким образом, SYS.DUAL — это, и фиктивная таблица, и нормальный сегмент типа «TABLE» (Что и показывает запрос, например, к DBA_SEGMENTS).
Продолжим эксперименты с DML на таблице DUAL
4. Выполним следующие запросы в SQL*Plus. (Проверено на Oracle 8.0.6 и 8.1.7.)
SQL> select * from dual;
SQL> insert into dual values (‘Y’);
1 строка создана.
SQL> select * from dual;
SQL> delete from dual;
1 строка удалена.
SQL> select * from dual;
SQL> delete from dual;
1 строка удалена.
SQL> select * from dual;
строки не выбраны
Таким образом, SQL*Plus ограничивает все DML для DUAL по псевдостолбцу «. WHERE ROWNUM = 1. «.
Комментарий А.Бачина : Скажем спасибо Илье Гершанову за интересный эксперимент. Немного его продолжим и покажем, что именно механизм SQL*Plus ограничивает выборку одной строкой.
SVRMGR> insert into dual values (‘V’);
SVRMGR> insert into dual values (‘W’);
SVRMGR> insert into dual values (‘Y’);
SVRMGR> select * from dual;
4 rows selected.
И так далее. Но SQL*Plus верен себе
SQL> select * from dual;
SQL> select count(*) from dual;
SQL> select dummy from dual where dummy = ‘W’ ;
SQL> delete from dual where dummy in (‘Y’,’V’,’W’);
SQL> select * from dual;
Следовательно, в «недооткрытом» состоянии работает фиксированная (И.Гершанов неправильно называет ее фиктивной) таблица DUAL, вмонтирования в ядро Oracle.
После открытия базы начинает работать обычная (но специализированная) таблица словаря данных DUAL, про которую (скорее всего) только SQL*Plus «знает», что в ней только одно значение. Другие программные механизмы могут этого не знать, НО все пользуются однозначностью таблицы DUAL. Поэтому, если эта однозначность по каким-то причинам нарушена, то у многих приложений может «поехать крыша», со всеми вытекающими для пользователя результатами.
Поэтому АБД должен, как дворник (я не шучу), следить за чистотой вверенного ему пространства. Хорошо еще, что хоть не всякий scott/tiger сможет совершить такую диверсию.
SELECT
SYSDATE,
TRUNC(SYSDATE,’mm’),
TRUNC(SYSDATE,’yyyy’),
ROUND(TO_DATE(‘14.03.2018′,’dd.mm.yyyy’),’mm’)a,
ROUND(TO_DATE(‘14.03.2018′,’dd.mm.yyyy’),’yyyy’)b
FROM DUAL;
SELECT 1
*
ERROR at line 1:
ORA-00923: FROM keyword not found where expected
Поэтому в большинстве запросов должна быть ссылка на таблицу или представление. Как правило, для таких запросов используется таблица DUAL. Таблица DUAL — это реальная таблица в схеме SYS, содержащая только одну запись.
SELECT * FROM DUAL;
1 rows selected
Как можно использовать таблицу DUAL в запросах? К примеру мы хотим получить системное время. Тогда, раз что-то во FROM указывать надо — укажем таблицу DUAL:
Источник: