ORACLE: материализованное представление не работает при использовании LEFT JOIN

Я хочу создать MATERIALIZED VIEW из LEFT JOIN из 2 таблиц. Однако следующее сообщение дает мне ошибку:

    SELECT field1 
     FROM table_1 a 
     LEFT JOIN table_2 b 
     ON a.field1=b.field2

ORA-12054: не может установить атрибут обновления ON COMMIT для материализованного представления

Однако следующие работы:

SELECT field1 
 FROM table_1 a, table_2 b 
 WHERE a.field1=b.field2

Есть ли у кого-нибудь идеи, почему это происходит.

спасибо для справки

Ответы

Ответ 1

Есть два условия, которые не удовлетворяются, чтобы быстро обновить материализованное представление. Во-первых, вы не указали столбцы rowid для каждой таблицы. И второе - недокументированное ограничение: ANSI-соединения не поддерживаются.

Вот пример, когда DEPT является таблицей_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-соединения упоминается в пункте 6 в этом blogpost.

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

Ответ 2

Так как это старый пост; no не упомянул о полном решении.

  • В таблице с внешним соединением должен быть первичный ключ, как указано в документе Oracle.
  • В запросе не должно быть никаких других ограничений. Я не должен иметь никаких критериев фильтрации в WHERE, только соединения; также не может иметь операторов CASE/DECODE в разделе SELECT; GROUP BY, SUM(), COUNT() и, тем не менее, разрешены.

В приведенном выше примере примера запрос будет работать, если первичный ключ создается в таблице отдела в столбце dept id.

Ответ 3

Следуя инструкциям, чтобы сделать работу DBMS_MVIEW.EXPLAIN_MVIEW: http://www.sqlsnippets.com/en/topic-12884.html

Способность:

REFRESH_COMPLETE

Невозможно:

REFRESH_FAST

REFRESH_FAST_AFTER_INSERT
  встроенный просмотр или подзапрос в списке FROM не поддерживается для этого типа MV

REFRESH_FAST_AFTER_INSERT
  встроенный просмотр или подзапрос в списке FROM не поддерживается для этого типа MV

REFRESH_FAST_AFTER_INSERT
  просмотр или подзапрос из списка

REFRESH_FAST_AFTER_ONETAB_DML
  см. причину, по которой REFRESH_FAST_AFTER_INSERT отключен

MV_REPORT

REFRESH_FAST_AFTER_ANY_DML
  см. причину, по которой REFRESH_FAST_AFTER_ONETAB_DML отключен