Ограничения встроенного просмотра

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 как подзапрос, но обычно это не то, о чем вам нужно беспокоиться, особенно если вы просто пытаетесь избежать ошибки, которую получаете.

Другие вопросы по тегам