测试DBMS_SCHEDULER

本文提供了一个简单的 Oracle Scheduler 示例,包括创建存储过程、设置作业和调度。同时介绍了如何为作业分配资源,以及使用权限进行管理。此外,文章还提供了权限查询和分配的方法。

需要用到Oracle的job,于是看了文档,很长,和详细,可惜没有看到一个简单的从头至尾的例子。

 

27 Using the Scheduler

Oracle Database provides database job capabilities through Oracle Scheduler (the Scheduler). This chapter explains how touse the various Scheduler components, and discusses the following topics:

 

本地做了一个小测试,很简单。

-- 1. The procedure
create or replace procedure sp_test is
begin
  insert into testtab(ddl_txt)
  values ('a');
  commit;
end sp_test;
/

-- 2. The job and schedule.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
   job_name           =>  'test_job',
   job_type           =>  'STORED_PROCEDURE',
   job_action         =>  'sp_test',
   start_date         =>  sysdate,
   repeat_interval    =>  'FREQ=MINUTELY;INTERVAL=1',
   comments           =>  'test job');
END;
/

exec DBMS_SCHEDULER.ENABLE('test_job');

就可以了。

 

 ===== 后记

需要“MANAGE SCHEDULER”的系统权限

 

查看如下:

select *  from role_sys_privs where privilege = 'MANAGE SCHEDULER';

 

授权如下:

SQL> grant SCHEDULER_ADMIN to xxxx;
 
Grant succeeded
 
SQL>

SQL> select * from role_sys_privs a where a.privilege = 'MANAGE SCHEDULER';
 
ROLE                           PRIVILEGE                                ADMIN_OPTION
------------------------------ ---------------------------------------- ------------
SCHEDULER_ADMIN                MANAGE SCHEDULER                         YES
 
SQL>

 

 关于权限角色的查询,引用如下:

http://bbs.youkuaiyun.com/topics/350162742

 

--1.查看所有用户:
  select * from dba_users;
  select * from all_users;
  select * from user_users;
 
--2.查看用户或角色系统权限(直接赋值给用户或角色的系统权限):
  select * from dba_sys_privs;
  select * from user_sys_privs;
 
--3.查看角色(只能查看登陆用户拥有的角色)所包含的权限
 
sql>select * from role_sys_privs;
 
--4.查看用户对象权限:
  select * from dba_tab_privs;
  select * from all_tab_privs;
  select * from user_tab_privs;
 
--5.查看所有角色:
  select * from dba_roles;
 
--6.查看用户或角色所拥有的角色:
  select * from dba_role_privs;
  select * from user_role_privs;
 
--7.查看哪些用户有sysdba或sysoper系统权限(查询时需要相应权限)
 
select * from V$PWFILE_USERS
 
--注意:
--1、以下语句可以查看Oracle提供的系统权限
 
select name from sys.system_privilege_map
 
--2、查看一个用户的所有系统权限(包含角色的系统权限)
 
SELECT privilege
  FROM dba_sys_privs
 WHERE grantee = 'DATAUSER'
UNION
SELECT privilege
  FROM dba_sys_privs
 WHERE grantee IN (SELECT granted_role FROM dba_role_privs WHERE grantee = 'DATAUSER');

 

另有一个相关的:

http://blog.youkuaiyun.com/shuangyan5230/article/details/7186811

oracle -- 授权 SCHEDULER

  1. --授权 SCHEDULER和JOB  
  2. GRANT SCHEDULER_ADMIN TO username;  
  3.   
  4. GRANT CREATE JOB TO scott;  
  5.   
  6. GRANT ALTER myjob1 TO scott;  
  7.   
  8. GRANT MANAGE SCHEDULER TO adam;  
  9.   
  10.   
  11. Grant SELECT_CATALOG_ROLE to username;  
  12. GRANT SCHEDULER_ADMIN TO username;   
  13. grant create job to username;  
  14. grant create PROCEDURE to username;  
  15. grant CREATE TRIGGER to username;  
  16. grant CREATE View to username;  
  17. grant EXECUTE ANY PROCEDURE to username;  
  18. grant MANAGE SCHEDULER to username;  
  19.   
  20.   
  21. -- 开始一个JOB  
  22. BEGIN  
  23.   
  24. DBMS_SCHEDULER.CREATE_JOB (  
  25.   
  26.    job_name            =>  'TEST_JOB',  
  27.   
  28.    job_type            =>  'STORED_PROCEDURE',    --job的类型是执行sql语句  
  29.   
  30.    job_action          =>  'PROC_TEST',  
  31.   
  32.    start_date          =>   sysdate,  
  33.   
  34.    repeat_interval     =>  'freq = minutely; interval=1',   --每分钟执行一次  
  35.   
  36.    enabled             =>   true,  
  37.   
  38.    comments            =>  'MY JOB');  
  39.   
  40. END;  
  41.   
  42. /  
  43.   
  44. -- 运行JOB  
  45.   
  46. exec dbms_scheduler.enable ('TEST_JOB');  
  47.   
  48. -- 删除JOB  
  49. BEGIN  
  50.   
  51. DBMS_SCHEDULER.DROP_JOB (           --删除job;多个job间用逗号隔开  
  52.   
  53.    job_name   =>  'TEST_JOB',  
  54.   
  55.    force      =>  TRUE);  
  56.   
  57. END;  
  58.   
  59.   
  60.   
  61.   
  62. ----------------------------------------------------  
  63. -- 创建调度,每隔1个小时调度一次  
  64. BEGIN  
  65.   
  66. DBMS_SCHEDULER.CREATE_SCHEDULE (           --创建计划任务  
  67.   
  68.   schedule_name     => 'KK_SCHEDULE',  
  69.   
  70.   repeat_interval   => 'FREQ=HOURLY; INTERVAL=1',    --执行间隔:每1小时  
  71.   
  72.   comments          => 'Every 1 HOURS');  
  73.   
  74. END;  
  75.   
  76. /  
  77.   
  78. -- 创建job 并把它加入到scheduler里面  
  79. BEGIN  
  80.   
  81. DBMS_SCHEDULER.CREATE_JOB (        
  82.   
  83.    job_name                 =>  'JOB_CLLCX',  
  84.   
  85.    job_type                 =>  'STORED_PROCEDURE',  
  86.   
  87.    job_action               =>  'PROC_CLLTJ',  
  88.   
  89.    schedule_name            =>  'KK_SCHEDULE');  
  90.   
  91. END;  
  92.   
  93. /  
  94.   
  95.   
  96. --  查询JOB  
  97. select job_name, schedule_name from user_scheduler_jobs;  
  98.   
  99. -- JOB是否运行  
  100. SELECT JOB_NAME, STATE FROM DBA_SCHEDULER_JOBS WHERE JOB_NAME = 'JOB_CLLCX';  
  101.   
  102. -- 运行JOB  
  103. BEGIN  
  104.   
  105. DBMS_SCHEDULER.ENABLE ('JOB_CLLCX');   /* sys.jobclass1下的所有jobs都会被enable */  
  106.   
  107. END;  

--DBMS_SCHEDULER 运行信息
select job_name,state,enabled,to_char(last_start_date,'yyyy-mm-dd hh24:mi:ss'), schedule_name
from dba_scheduler_jobs;
 
--DBMS_SCHEDULER运行成功与否信息
SELECT log_id, job_name, status,TO_CHAR(ACTUAL_START_DATE,'yyyy-mm-dd HH24:MI:ss') start_date,
           TO_CHAR (log_date, 'yyyy-mm-dd HH24:MI:ss') log_date
      FROM dba_scheduler_job_run_details
     WHERE job_name = 'GATHER_STATS_JOB'
     order by 4 DESC;
 
--查询执行时间情况
select t1.window_name,t1.repeat_interval,t1.duration from dba_scheduler_windows t1,dba_scheduler_wingroup_members t2
 where t1.window_name=t2.window_name and t2.window_group_name='MAINTENANCE_WINDOW_GROUP';
 
--修改执行时间
begin
dbms_scheduler.set_attribute('WEEKEND_WINDOW','REPEAT_INTERVAL','freq=daily;byday=SAT;byhour=0;byminute=0;bysecond=0');
dbms_scheduler.set_attribute('WEEKEND_WINDOW','DURATION','+002 00:00:00');
end;

 

<think>我们正在解决DBMS_SCHEDULER对象无效状态的问题,并需要参考ORA错误代码。根据用户问题,他们遇到了dbms_scheduler对象无效状态,并可能伴随ORA错误代码。由于用户提到了“ORA-错误代码”,但没有提供具体的错误码,我们需要考虑常见的与dbms_scheduler对象无效相关的错误。常见错误:1.ORA-06564:objectstringisinvalid这可能是调度程序对象(如作业、程序、计划等)无效。2.ORA-27475:"string.string"mustbeajob可能示指定的对象不是作业类型。3.ORA-27476:"string.string"mustbeaprogram类似,指定对象不是程序类型。4.ORA-27478:"string.string"mustbeaschedule指定对象不是计划类型。此外,调度程序对象无效通常是因为对象在创建后由于依赖关系变化(如或视图被删除或修改)而变得无效。解决方案:步骤1:识别无效对象查询视图`DBA_SCHEDULER_JOBS`(对于作业)、`DBA_SCHEDULER_PROGRAMS`(对于程序)等,查找`STATUS`为'INVALID'的对象。步骤2:重新编译对于无效的作业(JOB),可以使用`DBMS_SCHEDULER.SET_ATTRIBUTE`来重新设置属性(如重新指定程序、计划等)或尝试重新编译。但是,对于作业,没有直接的重新编译命令。通常需要重建作业,或者修复其依赖关系。另外,我们可以尝试使用`ALTERTYPECOMPILE`(如果对象类型无效)或者对于PL/SQL对象使用`ALTERPACKAGECOMPILE`。步骤3:如果无效是由依赖的对象无效引起的,那么需要先解决依赖对象的无效问题。步骤4:对于作业,可以尝试使用`DBMS_SCHEDULER.CREATE_JOB`(如果作业无效,可能需要先删除再重建,但注意删除作业会导致历史记录丢失,且需要确保作业可以安全重建)。但是,更常见的方法是:-先检查作业对应的程序(PROGRAM)是否有效。如果程序无效,那么需要先修复程序。-程序可能依赖于存储过程、函数等,如果这些底层对象无效,则重新编译这些对象。具体操作:1.查询无效的调度程序对象:```sqlSELECTOWNER,OBJECT_NAME,OBJECT_TYPEFROMDBA_OBJECTSWHERESTATUS='INVALID'ANDOBJECT_TYPEIN('JOB','PROGRAM','SCHEDULE');--注意:实际上作业在DBA_OBJECTS中对应的是OBJECT_TYPE为'JOB',但注意区分DBMS_SCHEDULERDBMS_JOB的作业(DBMS_SCHEDULER的作业对应的是SCHEDULER_JOB)。--更准确的是查询DBA_SCHEDULER_JOBS等视图。SELECTOWNER,JOB_NAME,'JOB'FROMDBA_SCHEDULER_JOBSWHEREENABLED='TRUE'ANDSTATE='BROKEN';--或者检查STATUS列,但是注意DBA_SCHEDULER_JOBS视图并没有STATUS列,而是有STATE列(可能的值包括'DISABLED','BROKEN','RUNNING'等)?实际上,无效通常现为BROKEN或FAILED。--实际上,我们可以直接查询DBA_SCHEDULER_JOBS的STATE列,如果为'BROKEN',则示损坏(无效)。SELECTOWNER,JOB_NAME,STATEFROMDBA_SCHEDULER_JOBSWHERESTATE='BROKEN';```2.如果作业无效(状态为BROKEN),则尝试重新启用:```sqlBEGINDBMS_SCHEDULER.DISABLE(name=>'job_name',force=>TRUE);DBMS_SCHEDULER.ENABLE(name=>'job_name');END;```3.如果重新启用不行,则尝试设置作业的日志级别,然后运行作业看错误:```sql--设置日志级别BEGINDBMS_SCHEDULER.SET_ATTRIBUTE(name=>'job_name',attribute=>'LOGGING_LEVEL',value=>DBMS_SCHEDULER.LOGGING_FULL);END;/--然后运行作业BEGINDBMS_SCHEDULER.RUN_JOB(job_name=>'job_name',use_current_session=>FALSE);END;/--查询日志SELECTLOG_ID,OPERATION,STATUS,ADDITIONAL_INFOFROMDBA_SCHEDULER_JOB_LOGWHEREJOB_NAME='job_name'ANDOPERATION='RUN';```4.如果作业无效是因为程序无效,则重新编译程序:```sqlBEGINDBMS_SCHEDULER.SET_ATTRIBUTE(name=>'program_name',attribute=>'VALID',value=>TRUE);--无效,没有直接VALID属性--实际上,程序无效时,需要重新编译其依赖的存储过程或函数。END;```由于调度程序对象无效通常是由于底层依赖无效,所以更推荐先修复底层依赖。步骤5:重新编译底层无效对象(如存储过程、函数等)查询DBA_ERRORS视图可以获取错误信息,或者直接尝试重新编译无效对象:```sql--重新编译所有无效的存储过程、函数、包等BEGINFORinvalidIN(SELECTOBJECT_TYPE,OBJECT_NAMEFROMDBA_OBJECTSWHERESTATUS='INVALID'ANDOWNER='<owner>'ANDOBJECT_TYPEIN('PACKAGE','PACKAGEBODY','PROCEDURE','FUNCTION','TYPE','TYPEBODY'))LOOPBEGINEXECUTEIMMEDIATE'ALTER'||invalid.OBJECT_TYPE||''||invalid.OBJECT_NAME||'COMPILE';EXCEPTIONWHENOTHERSTHENNULL;--处理编译错误,可能需要进一步检查END;ENDLOOP;END;```但是,请注意:如果重新编译后作业还是无效状态,则可能需要重新设置作业的程序或重新创建作业。步骤6:如果作业仍然无效,考虑删除并重新创建作业。注意:删除前记录作业的定义(查询DBA_SCHEDULER_JOBS获取作业定义)。特别地,如果用户遇到了一个具体的ORA错误代码,我们可以更针对性地解决。如果没有提供,那么以上为一般步骤。我们还要注意用户之前提供的引用中有一个错误码ORA-10911,但那是关于本地管理的SYSTEM空间的位图修改问题,与当前问题无关。因此,基于以上,我们给出一般解决方案。由于无法得知具体的错误代码,我们只能给出通用步骤。另外,如果用户在执行以上操作时遇到ORA错误,则需要具体分析。参考引用:Oracle官方文档关于DBMS_SCHEDULER部分[^1]。以下提供详细步骤:1.查询损坏(BROKEN)状态的调度程序作业:```sqlSELECTOWNER,JOB_NAME,STATEFROMDBA_SCHEDULER_JOBSWHERESTATE='BROKEN';```2.对于每个损坏的作业,尝试禁用然后启用:```sqlBEGINDBMS_SCHEDULER.DISABLE('owner.job_name',TRUE);--force=TRUE示强制禁用,即使作业正在运行DBMS_SCHEDULER.ENABLE('owner.job_name');END;```3.如果上述操作无效,则检查作业依赖的程序、计划等对象:```sql--查看作业使用的程序SELECTJOB_NAME,PROGRAM_NAMEFROMDBA_SCHEDULER_JOBSWHEREOWNER='owner'ANDJOB_NAME='job_name';--查看程序的状态SELECTPROGRAM_NAME,STATE,ENABLEDFROMDBA_SCHEDULER_PROGRAMSWHEREOWNER='owner'ANDPROGRAM_NAME='program_name';--如果程序无效(例如STATE为BROKEN),则考虑重新创建程序或修复程序依赖的代码。```4.运行作业并查看日志:```sqlBEGINDBMS_SCHEDULER.SET_ATTRIBUTE('owner.job_name','LOGGING_LEVEL',DBMS_SCHEDULER.LOGGING_FULL);DBMS_SCHEDULER.RUN_JOB('owner.job_name');END;/--等待作业运行完成,然后查看日志SELECTLOG_DATE,STATUS,ERROR#,ERROR_MSGFROMDBA_SCHEDULER_JOB_RUN_DETAILSWHEREJOB_NAME='job_name'ORDERBYLOG_DATEDESC;```5.根据错误信息(如错误代码)进一步解决。如果用户能够提供具体的ORA错误代码,我们可以更精确地定位问题。相关问题:1.如何查询DBMS_SCHEDULER作业的详细定义?2.如果重新编译作业依赖的存储过程后,作业仍然无效,应该怎么办?3.如何防止DBMS_SCHEDULER作业由于依赖对象改变而失效?</think> ### DBMS_SCHEDULER对象无效状态的解决方案 当DBMS_SCHEDULER对象(作业、程序、调度等)出现无效状态时,通常是由于以下原因: 1. **对象依赖失效**:作业依赖的存储过程/函数被修改或失效 2. **权限变更**:执行用户失去所需权限 3. **元数据损坏**:系统字典出现不一致 4. **对象引用丢失**:关联的、视图被删除或修改 #### 🔧 解决步骤: 1. **识别无效对象** ```sql SELECT owner, job_name, state FROM dba_scheduler_jobs WHERE state = 'BROKEN'; ``` 2. **检查错误信息** ```sql SELECT errors FROM dba_scheduler_jobs WHERE job_name = 'YOUR_JOB_NAME'; ``` 3. **重新编译依赖对象** ```sql ALTER PROCEDURE your_procedure COMPILE; ``` 4. **重建调度器对象** ```sql -- 禁用后重新启用 BEGIN DBMS_SCHEDULER.DISABLE('YOUR_JOB_NAME'); DBMS_SCHEDULER.ENABLE('YOUR_JOB_NAME'); END; ``` 5. **完全重建作业** ```sql -- 1. 导出作业定义 SELECT dbms_metadata.get_ddl('PROCOBJ', 'YOUR_JOB_NAME') FROM dual; -- 2. 删除后重建 BEGIN DBMS_SCHEDULER.DROP_JOB('YOUR_JOB_NAME'); -- 根据导出的DDL重建作业 END; ``` 6. **检查权限问题** ```sql GRANT EXECUTE ON required_package TO job_owner; ``` #### 🚨 常见ORA错误处理: - **ORA-27475 "string.string must be a job"** ```sql EXEC DBMS_SCHEDULER.SET_ATTRIBUTE('JOB_NAME', 'RESTARTABLE', FALSE); ``` - **ORA-27465 "job_class string not found"** ```sql BEGIN DBMS_SCHEDULER.CREATE_JOB_CLASS('NEW_CLASS'); DBMS_SCHEDULER.SET_ATTRIBUTE('JOB_NAME', 'JOB_CLASS', 'NEW_CLASS'); END; ``` - **ORA-06564 "object string is invalid"** 需重新编译依赖对象: ```sql ALTER PACKAGE owner.package_name COMPILE BODY; ``` > **注意**:操作前备份相关对象定义,生产环境建议先在测试环境验证。如遇复杂情况(如元数据损坏),建议联系Oracle支持[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值