问题描述
我对以下的确切语法有疑问:
- 创建物化视图
- 设置刷新时间
- 禁用查询重写
我正在尝试在创建过程中做到这一切。 此查询将通过 rails 迁移执行,我试图首先将其置于 rails 之外。
Syntax error partially recognized rules (railroad diagrams): unusable_editions_clause := UNUSABLE
语法错误位于 ("C
的 REWRITE ("COLUMN1",
我在 Rails 迁移中遇到的错误是
OCIError: ORA-00905: missing keyword: CREATE MATERIALIZED VIEW "MT_VIEW"...
查询:
CREATE MATERIALIZED VIEW "MT_VIEW"
BUILD IMMEDIATE
REFRESH FAST START WITH (SYSDATE) NEXT (SYSDATE + 1) + 5 / 24 WITH ROWID
ON COMMIT
disABLE QUERY REWRITE ("COLUMN1","COLUMN2") AS...
我基于以下条件构建了这部分查询:Create Materialized view which refresh records on daily
他的示例在视图中没有列名,我尝试将 BUILD..
放在列名之后,但这会引发不同的错误。此 says BUILD
应位于顶部。
更新:
这是我最终得到的结果(基于答案):
BEGIN
dbms_refresh.make(
name => 'refresh',list => 'mt_view',next_date => SYSDATE + 1,interval => 'next_day(trunc(sysdate),''SATURDAY'') + 4/24',implicit_destroy => FALSE,lax => TRUE
);
END;
关键事项:
-
name
不能以数字开头 -
list
不能为空 - 你需要一个间隔
-
next_date
不需要是字符串,字符串对我不起作用
这方面的好资源:
解决方法
使用 CREATE MATERIALIZED VIEW,您无需像使用普通视图一样从查询中单独指定列名。列名仅/始终源自查询本身,但您可以在那里使用别名。有关示例和语法,请参见此处:
- https://oracle-base.com/articles/misc/materialized-views
- https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/CREATE-MATERIALIZED-VIEW.html#GUID-EE262CA4-01E5-4618-B659-6165D993CA1B
还有:
- 通常,不要在对象名称或列名称上使用引号,因为它会强制区分大小写,否则将不存在。这在 Oracle 中通常被认为是不好的做法,因为以后每次引用该对象时都将被迫使用引号。
- 如果您的意图是在每天凌晨 5:00 刷新您的 MV,那么您的 NEXT 子句将无法实现。目前,它将在作业完成后 29 小时内运行,这是一个奇怪的计划,并且(与大多数 DBMS_JOB 计划一样)的开始时间会随着每次运行作业所需的时间而增加。如果您想要精确的刷新时间和作业执行的内置日志记录,建议使用 Oracle 调度程序而不是默认的 DBMS_JOB。这将需要额外的 DDL 命令(不能在 CREATE MV 中执行)。如果您使用的是 Oracle 19c 或更高版本,则默认使用 Oracle 调度程序,但如果您将它们放在 CREATE MV 语句中,您仍然必须小心如何指定开始/下一次。
- 您不能使用 START/NEXT 进行 ON COMMIT 和 计划执行。您需要选择其中之一。
所以使用这样的东西可以在一个命令中获取所有内容:
CREATE MATERIALIZED VIEW MT_VIEW
BUILD IMMEDIATE
REFRESH FAST
ON DEMAND START WITH (SYSDATE) NEXT TRUNC(SYSDATE+1)+5/24 WITH ROWID
DISABLE QUERY REWRITE
AS SELECT ...
或者执行此操作,然后创建一个 Oracle 调度程序作业来执行 MV 刷新并按固定计划记录结果。
CREATE MATERIALIZED VIEW MT_VIEW
BUILD IMMEDIATE
REFRESH FAST
ON DEMAND WITH ROWID
DISABLE QUERY REWRITE
AS SELECT ...
begin
dbms_refresh.make(
name => '5AM_REFRESH',list => '',next_date => '/* 5am */ trunc(sysdate+1)+5/24',interval => null,implicit_destroy => false,lax => false,job => 0,rollback_seg => null,push_deferred_rpc => true,refresh_after_errors => true,purge_option => null,parallelism => null,heap_size => null);
end;
/
begin
dbms_refresh.add(
name => '5AM_REFRESH',list => 'MT_VIEW',lax => true);
end;
/
commit;