2015-10-23 2 views
2

Мне нужно извлечь уникальные значения столбца, который является частью первичного ключа из таблицы, в материализованное представление. Я могу создать материализованное представление, если вы используете «refresh complete», но не повезло, когда пытаетесь использовать «обновить быстро на фиксации». Может ли кто-нибудь указать, пропустил ли я что-либо, или Oracle не поддерживает такое действие.Невозможно установить атрибут обновления ON COMMIT при создании материализованного представления, содержащего частичный первичный ключ в Oracle

Ниже приведен пример вывода. Благодарю.

SQL> create table TEST(col1 number, col2 number, col3 varchar(32), CONSTRAINT test_pk Primary Key (col1, col2)); 

Table created. 

SQL> create materialized view test_mv build immediate refresh fast on commit as select distinct col2 from test; 
create materialized view test_mv build immediate refresh fast on commit as select distinct col2 from test 
                            * 
ERROR at line 1: 
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view 


SQL> create materialized view test_mv build immediate refresh complete as select distinct col2 from test; 

Materialized view created. 

SQL> drop materialized view test_mv; 

Materialized view dropped. 

SQL> create materialized view log on test; 

Materialized view log created. 

SQL> create materialized view test_mv build immediate refresh fast on commit as select distinct col2 from test; 
create materialized view test_mv build immediate refresh fast on commit as select distinct col2 from test 
                            * 
ERROR at line 1: 
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view 

ответ

1

Основная проблема вашего представления - предложение DISTINCT. При фиксации быстрого обновления суперчувствителен к базовому запросу. Существует множество правил, которые должны быть выполнены для материализованного представления для поддержки быстрого обновления. DISTINCT предотвращает это.

Вы можете проверить возможности материализованного представления с использованием DBMS_MVIEW.EXPLAIN_MVIEW процедуры:

DECLARE 
    result SYS.EXPLAINMVARRAYTYPE := SYS.EXPLAINMVARRAYTYPE(); 
BEGIN 
    DBMS_MVIEW.EXPLAIN_MVIEW('TEST_MV', result); 

    FOR i IN result.FIRST..result.LAST LOOP 
     DBMS_OUTPUT.PUT_LINE(result(i).CAPABILITY_NAME || ': ' || CASE WHEN result(i).POSSIBLE = 'T' THEN 'Yes' ELSE 'No' || CASE WHEN result(i).RELATED_TEXT IS NOT NULL THEN ' because of ' || result(i).RELATED_TEXT END || '; ' || result(i).MSGTXT END); 
    END LOOP; 
END; 

Вы найдете более подробную информацию в документации http://docs.oracle.com/cd/B28359_01/server.111/b28313/basicmv.htm#i1007007

+0

Вы правы, что разные препятствуют этому. Но, как ни странно, вы можете создать его с помощью GROUP BY, и Oracle сможет использовать это для запросов 'DISTINCT'. См. Мой ответ для деталей. –

0

просмотров быстрого обновления придирчивы. Это решение требует материализованного журнала просмотра со специфическими свойствами и материализованного представления с несколькими дополнительными функциями и другим синтаксисом.

DISTINCT, по-видимому, не поддерживается. Но есть aggregate materialized views, которые поддерживают GROUP BY. Если это материализованное представление создается с помощью ENABLE QUERY REWRITE, Oracle может использовать его в запросе DISTINCT. Существует также дополнительный COUNT(*), потому что «COUNT (*) всегда должен присутствовать, чтобы гарантировать все виды быстрого обновления».

Создайте стол, материализованный просмотр журнала и материализованный вид.

create table test(col1 number, col2 number, col3 varchar(32) 
    ,constraint test_pk primary key (col1, col2)); 
create materialized view log on test with rowid (col2) including new values; 
create materialized view test_mv 
    build immediate 
    refresh fast on commit 
    enable query rewrite as 
    select col2, count(*) total from test group by col2; 

Запросы могут использовать материализованные представления.

Эти планы объясняют, что материализованное представление работает как для запроса GROUP BY, так и для DISTINCT.

explain plan for select col2 from test group by col2; 
select * from table(dbms_xplan.display); 

explain plan for select distinct col2 from test; 
select * from table(dbms_xplan.display); 


Plan hash value: 1627509066 

---------------------------------------------------------------------------------------- 
| Id | Operation     | Name | Rows | Bytes | Cost (%CPU)| Time  | 
---------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT    |   |  1 | 13 |  2 (0)| 00:00:01 | 
| 1 | MAT_VIEW REWRITE ACCESS FULL| TEST_MV |  1 | 13 |  2 (0)| 00:00:01 | 
---------------------------------------------------------------------------------------- 
+0

Поскольку я использую Oracle SE, у меня нет поддержки перезаписи запросов, но я все же могу создать материализованное представление без предложения «включить запрос переписать». Недостатком является то, что он приведет к полному доступу к таблице при запуске двух запросов в вашем ответе. Во всяком случае, я не беспокоюсь об этом прямо сейчас и верю, как только я перейду к Oracle EE, проблема исчезнет. Теперь я запутался после обновления col2 в тесте базовой таблицы, mv не обновляется/обновляется. Mv будет обновляться после вставки новых записей в базовую таблицу. Есть ли еще одна вещь, которую я пропустил/неправильно понял? – Jason

+0

Это то, что я пропустил - совокупные материализованные представления должны включать 'COUNT (*)'. Измененный пример работает лучше. –

+0

Работайте как очарование! mv успешно обновляется. Большой! – Jason

 Смежные вопросы

  • Нет связанных вопросов^_^