Oracle: материализованный вид не работает при использовании левого соединения
-
19-09-2019 - |
Вопрос
Я хочу создать материализованный вид из левого соединения 2 таблиц. Однако следующее дает мне ошибку:
SELECT field1
FROM table_1 a
LEFT JOIN table_2 b
ON a.field1=b.field2
ORA-12054: Невозможно установить атрибут On Commit Rebresh для материализованного представления
Однако следующее работает:
SELECT field1
FROM table_1 a, table_2 b
WHERE a.field1=b.field2
У кого -нибудь есть идеи, почему это происходит.
Спасибо за помощь
Решение
Есть два условия, которые не удовлетворены, чтобы сделать этот материализованный облигальный обновление. Во -первых, вы не указали столбцы Rowid каждой задействованной таблицы. А второй-недокументированное ограничение: ANSI-Joins не поддерживаются.
Вот пример, когда DEPT - Table_1, псевдоним A и EMP - Table_2, псевдоним B:
SQL> create materialized view log on emp with rowid
2 /
Materialized view log created.
SQL> create materialized view log on dept with rowid
2 /
Materialized view log created.
SQL> create materialized view empdept_mv
2 refresh fast on commit
3 as
4 select a.deptno
5 from dept a
6 left join emp b on (a.deptno = b.deptno)
7 /
from dept a
*
ERROR at line 5:
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view
Это имитирует вашу ситуацию. Сначала добавьте Rowid's:
SQL> create materialized view empdept_mv
2 refresh fast on commit
3 as
4 select a.rowid dept_rowid
5 , b.rowid emp_rowid
6 , a.deptno
7 from dept a
8 left join emp b on (a.deptno = b.deptno)
9 /
from dept a
*
ERROR at line 7:
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view
Тем не менее, он не может быстро обновить, из -за соединений ANSI. Преобразование в синтаксис внешнего соединения в старом стиле:
SQL> create materialized view empdept_mv
2 refresh fast on commit
3 as
4 select a.rowid dept_rowid
5 , b.rowid emp_rowid
6 , a.deptno
7 from dept a
8 , emp b
9 where a.deptno = b.deptno (+)
10 /
Materialized view created.
И чтобы доказать, что это работает:
SQL> select * from empdept_mv
2 /
DEPT_ROWID EMP_ROWID DEPTNO
------------------ ------------------ ----------
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAA 20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAB 30
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAC 30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAD 20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAE 30
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAF 30
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAG 10
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAH 20
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAI 10
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAJ 30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAK 20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAL 30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAM 20
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAN 10
AAARhmAAEAAAAI/AAD 40
15 rows selected.
SQL> insert into dept values (50,'IT','UTRECHT')
2 /
1 row created.
SQL> commit
2 /
Commit complete.
SQL> select * from empdept_mv
2 /
DEPT_ROWID EMP_ROWID DEPTNO
------------------ ------------------ ----------
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAA 20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAB 30
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAC 30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAD 20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAE 30
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAF 30
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAG 10
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAH 20
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAI 10
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAJ 30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAK 20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAL 30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAM 20
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAN 10
AAARhmAAEAAAAI/AAD 40
AAARhmAAEAAAAI7AAA 50
16 rows selected.
Ограничение синтаксиса ANSI-Join упоминается в точке 6 в этот пост.
С уважением, Роб.
Другие советы
Поскольку это старый пост; Нет, упомянул полное решение.
- Внешняя таблица, которая должна иметь первичный ключ, как упомянуто в Oracle Doc.
- Запрос не должен иметь никаких других ограничений, т.е. не должно иметь никаких критериев фильтра в
WHERE
Пункт, только объединения; также не может иметьCASE
/DECODE
заявления вSELECT
пункт;GROUP BY
,SUM()
,COUNT()
И таковые разрешены, хотя.
В примере примера пример запроса будет работать, если первичный ключ будет создан в таблице отделов в столбце идентификаторов DEPT.
Следуют следующим инструкциям, чтобы сделать DBMS_MVIEW.EXPLAIN_MVIEW.http://www.sqlsnippets.com/en/topic-12884.html
Способен:
Refresh_complete
Не способен:
Refresh_fast
Represh_fast_after_insert
Встроенное представление или подложка из списка не поддерживается для этого типа MV
Represh_fast_after_insert
Встроенное представление или подложка из списка не поддерживается для этого типа MV
Represh_fast_after_insert
Просмотреть или подразделение из списка
Represh_fast_after_onetab_dml
См. Причина, по которой обновления represh_fast_after_insert отключена
Mv_report
Represh_fast_after_any_dml
См. Причина, по которой обновляется rebresh_fast_after_onetab_dml отключена