DBMS_SCHEDULER的CHAIN是唯一原生支持作业依赖的机制,但必须严格按三步构建:先建PROGRAM,再建CHAIN和STEP,最后配置RULE;缺任何一步链均不执行且不报错。

直接说结论:DBMS_SCHEDULER 的 CHAIN 是唯一原生支持作业依赖关系的机制,但必须分三步走——先建 PROGRAM,再建 CHAIN 和 STEP,最后配 RULE;漏掉任何一步,链就断在数据库里,不报错也不执行。
CHAIN 本身不干活,必须定义 STEP 才有执行单元
很多人执行完 DBMS_SCHEDULER.CREATE_CHAIN('my_chain') 就以为链建好了,其实这只是个空壳。查 USER_SCHEDULER_CHAINS 能看到名字,但 USER_SCHEDULER_CHAIN_STEPS 是空的,链根本不会触发。
-
DEFINE_CHAIN_STEP必须显式指定program_name(不能是存储过程名,得是已启用的PROGRAM对象) - 一个
STEP只能绑定一个PROGRAM,想调用带参过程?得把参数封装进PLSQL_BLOCK类型的PROGRAM里 -
STEP名称区分大小写,且不能重复;若重名,第二次调用会报ORA-27476: object "my_step1" does not exist(因为 Oracle 把它当更新操作,但实际没建过)
RULE 决定链如何流转,缺了它所有 STEP 都卡在 STARTED 状态
只建 CHAIN 和 STEP,链启动后只会停在第一个 STEP,状态变成 STARTED 后再也不动——这不是 bug,是设计如此。流转逻辑全靠 DEFINE_CHAIN_RULE 驱动。
- 最简规则:
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain', 'TRUE', 'START my_step1')(启动第一步) - 依赖规则必须用布尔表达式:
'my_step1 COMPLETED'表示上一步成功才走下一步,'my_step1 STOPPED'则用于异常分支 - 多个规则可共存,但顺序不保证;若逻辑冲突(比如两个规则同时试图启动
my_step2),Oracle 会随机选一个执行,不报错
启动链必须用 ENABLE + START,且不能跳过 ENABLE
和普通 JOB 类似,CHAIN 默认创建后是 DISABLED 状态。只执行 DBMS_SCHEDULER.START_CHAIN 会报 ORA-27477: chain "my_chain" is disabled。
- 必须先
DBMS_SCHEDULER.ENABLE('my_chain'),再DBMS_SCHEDULER.START_CHAIN('my_chain') -
START_CHAIN是一次性命令,不带调度逻辑;要周期性跑链,得另建一个JOB,job_action设为DBMS_SCHEDULER.START_CHAIN('my_chain') - 链运行中若某
STEP报错,默认整个链停住;想自动重试,得在RULE里明确定义失败分支,比如'my_step1 FAILED' → 'START my_step1_retry'
真正容易被忽略的是 RULE 的布尔表达式语法——它不支持 PL/SQL 函数、不认变量、不能拼字符串,只能用硬编码的 STEP_NAME 加固定状态字(COMPLETED/FAILED/STOPPED)。写错一个字母,链就静默失效,连日志都难定位。











