使用定义的列和刷新率创建物化视图

问题描述

我对以下的确切语法有疑问:

  • 创建物化视图
  • 设置刷新时间
  • 禁用查询重写

我正在尝试在创建过程中做到这一切。 此查询将通过 rails 迁移执行,我试图首先将其置于 rails 之外。

sql 开发人员中,我在 IDE 中遇到错误

Syntax error partially recognized rules (railroad diagrams): unusable_editions_clause := UNUSABLE

语法错误位于 ("CREWRITE ("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,您无需像使用普通视图一样从查询中单独指定列名。列名仅/始终源自查询本身,但您可以在那里使用别名。有关示例和语法,请参见此处:

还有:

  • 通常,不要在对象名称或列名称上使用引号,因为它会强制区分大小写,否则将不存在。这在 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;