zoukankan      html  css  js  c++  java
  • 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语句时需要注意授权问题

  • 相关阅读:
    PHP 使用 GET 传递数组变量
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 二进制数数
    Java实现 蓝桥杯 算法训练 二进制数数
    Java实现 蓝桥杯 算法训练 二进制数数
  • 原文地址:https://www.cnblogs.com/ziq711/p/8084741.html
Copyright © 2011-2022 走看看