• ORACLE通过JOB定时创建序列


    http://blog.csdn.net/cuihaiyang/article/details/7872982

    因为业务需要每月需要增加一个序列,想到了使用job定时创建,每次创建一年的。写此job的过程中遇到一些问题,在此记录一下。

    第一步:写创建序列(sequence)的存储过程。代码如下:

    [sql] view plain copy
     
    1. create or replace procedure pro_create_seq(sequencePrefix in varchar2)   
    2. is  
    3. strYear varchar2(4);  
    4. strMonth varchar2(6);  
    5. strSql varchar2(500);  
    6. begin  
    7.   select to_char(sysdate,'yyyy') into strYear from dual;  
    8.   for i in 1..12 loop  
    9.     strMonth:=strYear||lpad(i,2,'0');--组装月份,形如:201201  
    10.     strSql:='create sequence '||sequencePrefix||strMonth||' start with 1 increment by 1 MINVALUE 0 MAXVALUE 99999999999 ';  
    11.     execute immediate strSql;  
    12.   end loop;  
    13. end pro_create_seq;  

    创建存储过程成功,但测试该报错了:

    SQL> exec pro_create_seq('FACTORY_NOTICE_INFO_DB_');
     
    begin pro_create_seq('FACTORY_NOTICE_INFO_DB_'); end;
     
    ORA-01031: 权限不足
    ORA-06512: 在 "YCPS.PRO_CREATE_SEQ", line 16
    ORA-06512: 在 line 2

    在网上搜索解决方法发现原来是在存储过程中ROLE无效,需要显示授权。见http://topic.csdn.net/u/20110507/21/8fb89cfa-30b4-41d0-9ebf-57ea74057960.html?27630

    即有两种解决方法:

    1、通过GRANT CREATE SEQUENCE TO YCPS;来显示给用户授权
    2、修改存储过程,加入Authid Current_User时存储过程可以使用role权限。

    我采用了第二种方法,即加入Authid Current_User,修改后的存储过程如下:

    [sql] view plain copy
     
    1. create or replace procedure pro_create_seq(sequencePrefix in varchar2)   
    2. <span style="color:#ff0000;">Authid Current_User</span> --赋予role权限  
    3. is  
    4. strYear varchar2(4);  
    5. strMonth varchar2(6);  
    6. strSql varchar2(500);  
    7. begin  
    8.   select to_char(sysdate,'yyyy') into strYear from dual;--取年份,形如:2012  
    9.   for i in 1..12 loop  
    10.     strMonth:=strYear||lpad(i,2,'0');--组装月份,形如:201201  
    11.     strSql:='create sequence '||sequencePrefix||strMonth||' start with 1 increment by 1 MINVALUE 0 MAXVALUE 99999999999 ';  
    12.     execute immediate strSql;  
    13.   end loop;  
    14. end pro_create_seq;  

    SQL> exec pro_create_seq('FACTORY_NOTICE_INFO_DB_');
     
    PL/SQL procedure successfully completed

    执行成功。

    第二步:创建job,定时调用存储过程来创建sequence

    [sql] view plain copy
     
    1. variable job1 number;  
    2.  begin  
    3.  dbms_job.submit(:job1,'PRO_CREATE_SEQ(''FACTORY_NOTICE_INFO_DB_'');PRO_CREATE_SEQ(''FACTORY_NOTICE_INFO_XB_'');',sysdate,'add_months(TRUNC(SYSDATE,''yyyy''),12)');  
    4.  commit;  
    5.  end;  

    SQL> variable job1 number;
    SQL>  begin
      2   dbms_job.submit(:job1,'PRO_CREATE_SEQ(''FACTORY_NOTICE_INFO_DB_'');PRO_CREATE_SEQ(''FACTORY_NOTICE_INFO_XB_'');',sysdate,'add_months(TRUNC(SYSDATE,''yyyy''),12)');
      3   commit;
      4   end;
      5  /
     
    PL/SQL procedure successfully completed
    job1
    ---------
    84
     
    SQL> begin
      2  dbms_job.run(84);
      3  end;
      4  /
     
    begin
    dbms_job.run(84);
    end;
     
    ORA-12011: 无法执行 1 作业
    ORA-06512: 在 "SYS.DBMS_IJOB", line 637
    ORA-06512: 在 "SYS.DBMS_JOB", line 284
    ORA-06512: 在 line 3 

    可见,job创建成功了,但执行出错。查询ORA-12011错误的说明如下:

    ORA-12011: execution of string jobs failed
    Cause: An error was caught in dbms_ijob.run from one or more jobs which were due to be run.
    Action: Look at the alert log for details on which jobs failed and why.
     
    SQL> select value from v$diag_info where name='Diag Trace';
     
    VALUE
    --------------------------------------------------------------------------------
    /u01/app/oracle/diag/rdbms/ycps/ycps1/trace

    上面查找到alert log的路径,日志文件内容如下:

    Thu Aug 16 14:30:57 2012
    Errors in file /u01/app/oracle/diag/rdbms/ycps/ycps1/trace/ycps1_ora_2622362.trc:
    ORA-12012: 自动执行作业 84 出错
    ORA-01031: 权限不足
    ORA-06512: 在 "YCPS.PRO_CREATE_SEQ", line 15
    ORA-06512: 在 line 1

    可见,仍然是权限问题。然而通过exec pro_create_seq('FACTORY_NOTICE_INFO_DB_');调用存储过程却可以执行,很让人费解。后来在http://topic.csdn.net/u/20100611/11/deec0f8f-0749-4478-acba-114a84300360.html说需要显式授权,也就是前面提到的方法2,于是测试了一下,竟然成功了:

    SQL> conn sys/oracle@psdb as sysdba
    Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 
    Connected as SYS
     
    SQL> grant create sequence to ycps;
     
    Grant succeeded
     
    SQL> conn ycps/ycps@psdb
    Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 
    Connected as ycps
     
    SQL> begin
      2  dbms_job.run(84);
      3  end;
      4  /
     
    PL/SQL procedure successfully completed
    看来Authid Current_User的使用是有局限的,在通过存储过程来执行DDL语句时需要注意授权问题

  • 相关阅读:
    实验室资质认定评审准则和要素及要点
    如何进行内审?
    实验室比对结果评价的3种方法
    第一次如何申请CNAS实验室认可资质
    风险评估的实施步骤
    Servlet
    CMMI_SCAMPY评估方法
    PHP_2
    PHP_1
    java中String与StringBuilder的区别
  • 原文地址:https://www.cnblogs.com/ziq711/p/8084741.html
Copyright © 2020-2023  润新知