Oracle: материализованный вид не работает при использовании левого соединения

StackOverflow https://stackoverflow.com/questions/1312980

Вопрос

Я хочу создать материализованный вид из левого соединения 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 в этот пост.

С уважением, Роб.

Другие советы

Поскольку это старый пост; Нет, упомянул полное решение.

  1. Внешняя таблица, которая должна иметь первичный ключ, как упомянуто в Oracle Doc.
  2. Запрос не должен иметь никаких других ограничений, т.е. не должно иметь никаких критериев фильтра в 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 отключена

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top