Oracle不允许ALTER MATERIALIZED VIEW直接修改NEXT刷新时间,必须用完整REFRESH子句重写调度逻辑,包括FORCE ON DEMAND START WITH NEXT,并检查DBA_JOBS确保旧job被清除。
很多人执行 ALTER MATERIALIZED VIEW mv_name REFRESH ... NEXT ... 时发现语法报错,或者执行成功但刷新没按新时间跑——根本原因是:Oracle 不允许在 ALTER MATERIALIZED VIEW 语句中直接修改 NEXT 表达式。所谓“修改刷新周期”,实际是重置物化视图的内部调度状态,必须用完整 REFRESH 子句覆盖原定义。
必须显式写出 REFRESH FORCE ON DEMAND START WITH ... NEXT ... 全部关键词,哪怕只改 NEXT 部分。否则 Oracle 会沿用旧值或报 ORA-12015 错误。
START WITH 建议保持为 SYSDATE(立即生效),避免因时间计算偏差导致首次刷新延迟NEXT 必须是合法日期表达式,推荐用 TRUNC(SYSDATE) + 1 + 2/24(次日 2:00)这类确定性写法,别依赖 TO_DATE(CONCAT(...)) —— 容易因 NLS 设置失败FAST 刷新,ALTER 时也得带 FAST,否则可能降级为 COMPLETE,引发性能抖动示例(改为每天凌晨 3 点刷新):
ALTER MATERIALIZED VIEW mv_sales REFRESH FORCE ON DEMAND START WITH SYSDATE NEXT TRUNC(SYSDATE) + 1 + 3/24;
Oracle 对 ON DEMAND 物化视图的自动刷新,底层靠 job 触发。但 job 不是每次 ALTER 都自动重建——它可能还在用旧 job ID 跑旧逻辑。
SELECT job, what FROM dba_jobs WHERE what LIKE '%DBMS_MVIEW.REFRESH%mv_sales%';
BROKEN = 'Y'),需手动 EXEC DBMS_JOB.REMOVE(job_id); 清掉ALTER 语句,Oracle 会新建 job 并绑定新调度规则如果物化视图创建时指定了 ON COMMIT,它的刷新完全由事务提交驱动,和 START WITH/NEXT 无关。ALTER 时强行加 NEXT 会报 ORA-12000 错误。这种场景下,要么接受实时一致性,要么删掉重建为 ON DEMAND 模式。
ALTER 语句、确认 job 被刷新、避开 ON COMMIT 陷阱。最容易被忽略的是 job 残留——看起来改完了,其实后台还在跑旧计划。