Ограничения встроенного просмотра
SELECT in_ev.type, pl.name, in_ev.year
FROM places pl INNER JOIN (SELECT e.type, e.place_id, e.year
FROM events e)in_ev ON in_ev.place_id=pl.place_id
WHERE EXISTS (SELECT 1 FROM in_ev sub_ev WHERE sub_ev.year=1994)
Я пытаюсь понять, как обрабатываются встроенные представления и почему мы не можем использовать их в качестве "исходной таблицы" в подзапросах оператора where. Когда я пытаюсь выполнить этот запрос, я получаю ORA-00942: таблица или представление не существует
Вышеуказанный фрагмент приведен только для иллюстрации.
Какова точная разница в хранении и обработке между обычными таблицами и встроенными представлениями?
1 ответ
Подзапрос в where
предложение просто не может видеть встроенное представление, которое, я думаю, вы выяснили; на самом деле это проблема масштаба. Здесь нет хранилища, и то, как оно управляется в памяти и обрабатывается, зависит от оптимизатора - например, он может существенно переписать вещи. Я полагаю, что подзапрос может быть логически оценен до оценки встроенного представления.
Поскольку синтаксический анализатор выбрасывает ORA-00942 до того, как запрос фактически будет выполнен, то, как обрабатывается встроенное представление, является спорным вопросом.
Вместо этого вы можете использовать факторинг подзапроса:
WITH in_ev AS (
SELECT e.type, e.place_id, e.year
FROM events e
)
SELECT in_ev.type, pl.name, in_ev.year
FROM places pl INNER JOIN in_ev ON in_ev.place_id=pl.place_id
WHERE EXISTS (SELECT 1 FROM in_ev sub_ev WHERE sub_ev.year=1994)
Что выглядит странно с таким надуманным примером, но вы признали, что это показательно в этом вопросе. Подзапрос в where
Предложение может видеть CTE - это находится в области видимости парсера.
Как отметил @mathguy в комментарии, оптимизатор может по-прежнему рассматривать CTE как подзапрос, но обычно это не то, о чем вам нужно беспокоиться, особенно если вы просто пытаетесь избежать ошибки, которую получаете.