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

Create Materialized View With Defined Columns & Refresh Rate

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

我正在尝试在创建过程中完成所有这些工作。 此查询将通过 rails 迁移执行,我试图先在 rails 之外获取它。

在 sql 开发人员中,我在 IDE

中遇到错误

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

语法错误位于 REWRITE ("COLUMN1",

("C

我在 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.. 放在列名之后,但这会引发不同的错误。这个saysBUILD应该在最上面

更新:

这是我最终得到的结果(基于答案):

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;

关键事项:

这方面的好资源:

使用 CREATE MATERIALIZED VIEW,您无需像使用普通视图那样从查询中单独指定列名。列名 only/always 来自查询本身,但您可以在那里使用别名。有关示例和语法,请参见此处:

另外:

  • 一般来说,不要在对象名称或列名称上使用引号,因为它会强制区分大小写,否则不会存在这种情况。这在 Oracle 中通常被认为是不好的做法,因为以后每次引用该对象时都将被迫使用引号。
  • 如果您的意图是让您的 MV 每天在 5:00am 刷新,您的 NEXT 子句将无法实现。目前,作业完成后 运行 29 小时,这是一个奇怪的时间表,并且(与大多数 DBMS_JOB 时间表一样)的开始时间会随着 DBMS_JOB 所需的时间逐渐增加 运行 工作,每次。如果您想要精确的刷新时间和内置的作业执行日志记录,建议使用 Oracle Scheduler 而不是默认的 DBMS_JOB。这将需要额外的 DDL 命令(不能在 CREATE MV 中执行)。如果您使用的是 Oracle 19c 或更高版本,默认情况下会使用 Oracle Scheduler,但是如果您将 start/next 时间放在 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;