物化视图必须设为ON DEMAND模式才支持定时刷新,REFRESH ON COMMIT会完全忽略START WITH和NEXT;二者必须为合法DATE表达式(如NEXT TRUNC(SYSDATE)+1+8/24),不可写字符串;需确认USER_JOBS中job已注册且BROKEN='N',并确保数据库非RESTRICTED SESSION。
物化视图必须设为 ON DEMAND 模式才支持定时刷新
如果你的物化视图创建时用了 refresh fast on commit 或 refresh complete on commit,start with 和 next 会被 oracle 完全忽略——它压根不走定时逻辑。必须确认当前是 on demand 模式:
SELECT REFRESH_MODE, REFRESH_METHOD FROM USER_MVIEWS WHERE MVIEW_NAME = 'YOUR_MV';
返回结果中 REFRESH_MODE 应为 DEMAND,否则改用:
- 重建:加
REFRESH COMPLETE ON DEMAND(或FORCE ON DEMAND) - 或 ALTER:
ALTER MATERIALIZED VIEW your_mv REFRESH COMPLETE ON DEMAND;(注意:ALTER 不支持直接改START WITH/NEXT,只能重建或靠 job 补位)
START WITH 和 NEXT 必须是合法 DATE 表达式,不能是字符串
常见写法如 START WITH 'SYSDATE' 或 NEXT 'TRUNC(SYSDATE) + 1' 看似合理,实则会把整个字符串当字面量存入数据字典,导致 job 执行时报 ORA-12012,且无明显错误提示。
正确写法只接受函数调用形式:
-
START WITH SYSDATE(立刻触发首次刷新) -
NEXT TRUNC(SYSDATE) + 1 + 8/24(每天凌晨 8 点) -
NEXT TRUNC(SYSDATE) + 1 + 12/24(每天中午 12 点) - 避免
TO_DATE('2026-06-04', 'YYYY-MM-DD'):NLS 设置一变就解析失败
验证是否生效:SELECT NEXT FROM USER_MVIEWS WHERE MVIEW_NAME = 'YOUR_MV';,结果应是可读日期,不是空、null 或乱码。
job 没跑 ≠ 时间没配对,先查 USER_JOBS 是否注册成功
即使建 MV 语句语法没错,Oracle 也可能跳过 job 注册。典型情况是用了 BUILD DEFERRED 却没配 REFRESH COMPLETE,导致系统认为“暂不需要刷新”,不生成后台 job。
执行:SELECT JOB, BROKEN, FAILURES FROM USER_JOBS WHERE WHAT LIKE '%DBMS_MVIEW.REFRESH%';
- 返回空 → job 根本没注册,需手动触发一次刷新:
EXEC DBMS_MVIEW.REFRESH('YOUR_MV', 'C');,再查 job 是否出现 -
BROKEN = 'Y'→ job 被标记为中断,常见于权限缺失或存储过程不可执行 -
FAILURES > 0→ job 调度成功但DBMS_MVIEW.REFRESH内部报错退出,错误被静默吞掉,不是“没跑”,是“跑挂了”
关键点:job 存在且 BROKEN = 'N' 仅说明调度器准备就绪,不代表刷新一定成功。
复杂时间需求(如每天 2 次)别硬塞 NEXT,改用 DBMS_SCHEDULER
NEXT 只支持单表达式,无法描述“每天 12:00 和 19:00”,强行拼 NEXT CASE WHEN ... 会报错或行为不可控。
推荐做法:剥离定时逻辑,用独立 scheduler job 控制:
- 先建一个刷新存储过程:
CREATE OR REPLACE PROCEDURE refresh_your_mv AS BEGIN DBMS_MVIEW.REFRESH('YOUR_MV'); END; - 再建 scheduler job:
DBMS_SCHEDULER.CREATE_JOB( job_name => 'mv_refresh_daily_twice', job_type => 'STORED_PROCEDURE', job_action => 'refresh_your_mv', start_date => SYSDATE, repeat_interval => 'FREQ=DAILY; BYHOUR=12,19', enabled => TRUE );
好处是时间规则清晰、可单独启停、日志完整;坏处是 job 和 MV 解耦,需额外维护过程名和权限。如果数据库处于 RESTRICTED SESSION,scheduler job 同样不会启动,这点和旧版 DBMS_JOB 一致。
真正容易被忽略的是:物化视图所有者必须对基表有**直接 SELECT 权限**(不能靠角色继承),且要有 CREATE JOB 权限(Oracle 12c+ 默认不继承,需显式授予)。涉及 DB Link 时,远端连通性必须单独验证,否则刷新失败也不报错。











