首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 计算机考试 > 认证考试 > ORACLE/CIW认证 >

Oracle通过job定时创建表(2)

2009-02-19 
在项目中,经常会遇到需要定时完成的任务,比如定时更新数据,定义统计数据生成报表等等,其实这些事情都可以使用Oracle的Job来完成。

    第三步:异常情况处理
  JOB不能运行情况处理
  1.先来了解一下JOB的参数说明:与job相关的参数一个是job_queue_processes,这个是运行JOB时候所起的进程数,当然系统里面JOB大于这个数值后,就会有排队等候的,最小值是0,表示不运行JOB,最大值是36,在OS上对应的进程时SNPn,9i以后OS上管理JOB的进程叫CJQn.可以使用下面这个SQL确定目前有几个SNP/CJQ在运行。
  select * from v$bgprocess,这个paddr不为空的snp/cjq进程就是目前空闲的进程,有的表示正在工作的进程。
  另外一个是job_queue_interval,范围在1——3600之间,单位是秒,这个是唤醒JOB的process,因为每次snp运行完他就休息了,需要定期唤醒他,这个值不能太小,太小会影响数据库的性能。
  2.诊断:先确定上面这两个参数设置是否正确,特别是第一个参数,设置为0了,所有JOB就不会跑,确认无误后,我们继续向下。
  3.使用下面的SQL察看JOB的的broken,last_date和next_date,last_date是指最近一次job运行成功的结束时间,next_date是根据设置的频率计算的下次执行时间,根据这个信息就可以判断JOB上次是否正常,还可以判断下次的时间对不对,SQL如下:
  select * from dba_jobs
  有时候我们发现他的next_date是4000年1月1日,说明job要不就是在running,要不就是状态是break(broken=Y),如果发现JOB的broken值为Y,找用户了解一下,确定该JOB是否可以broken,如果不能broken,那就把broken值修改成N,修改再使用上面的SQL察看就发现他的last_date已经变了,JOB即可正常运行,修改broken状态的SQL如下:
  declare
  BEGIN
  DBMS_JOB.BROKEN(<JOB_ID>,FALSE);
  END;
  4.使用下面的SQL查询是否JOB还在Running
  select * from dba_jobs_running
  如果发现JOB已经Run了很久了还没有结束,就要查原因了。一般的JOB running时会锁定相关的相关的资源,可以查看一下v$access和v$locked_object这两个view,如果发现其他进程锁定了与JOB相关的Object,包括PKG/Function/Procedure/Table等资源,那么就要把其他进程删除,有必要的话,把JOB的进程也删除,再重新跑看看结果。
  5.如果上面都正常,但是JOB还不run,怎么办?那我们要考虑把JOB进程重启一次,防止是SNP进程死了造成JOB不跑,指令如下:
  alter system set job_queue_processes=0 ——关闭job进程,等待5——10秒钟
  alter system set job_quene_processes=5 ——恢复原来的值
   附录:Oracle存储过程基本语法
  1.基本结构
  CREATE or REPLACE PROCEDURE 存储过程名字
  (
  参数1 IN NUMBER,
  参数2 IN NUMBER
  ) IS
  变量1 INTEGER :=0;
  变量2 DATE;
  BEGIN
  END 存储过程名字
  2.SELECT INTO STATEMENT
  将select查询的结果存入到变量中,可以同时将多个列存储多个变量中,必须有一条
  记录,否则抛出异常(如果没有记录抛出NO_DATA_FOUND)
  例子:
  BEGIN
  SELECT col1,col2 into 变量1,变量2 FROM typestruct where xxx;
  EXCEPTION
  WHEN NO_DATA_FOUND THEN
  xxxx;
  END;
  ...
  3.IF 判断
  IF V_TEST=1 THEN
  BEGIN
  do something
  END;
  END IF;
  4.while 循环
  WHILE V_TEST=1 LOOP
  BEGIN
  XXXX
  END;
  END LOOP;
  5.变量赋值
  V_TEST := 123;
  6.用for in 使用cursor
  ...
  IS
  CURSOR cur IS select * FROM xxx;
  BEGIN
  FOR cur_result in cur LOOP
  BEGIN
  V_SUM :=cur_result.列名1+cur_result.列名2
  END;
  END LOOP;
  END;
  7.带参数的cursor
  CURSOR C_USER(C_ID NUMBER) IS select NAME FROM USER WHERE TYPEID=C_ID;
  OPEN C_USER(变量值);
  LOOP
  FETCH C_USER INTO V_NAME;
  EXIT FETCH C_USER%NOTFOUND;
  do something
  END LOOP;
  CLOSE C_USER;
  8.用pl/sql developer debug
  连接数据库后建立一个Test WINDOW
  在窗口输入调用SP的代码,F9开始debug,CTRL+N单步调试
  通过一个实际的例子学习Oracle存储过程
  ——创建存储过程
  CREATE or REPLACE PROCEDURE xxxxxxxxxxx_p
  (
  --参数IN表示输入参数,OUT表示输入参数,类型可以使用任意Oracle中的合法类型。
  is_ym IN CHAR
  )
  AS
  --定义变量
  vs_msg VARCHAR2(4000); --错误信息变量
  vs_ym_beg CHAR(6); --起始月份
  vs_ym_end CHAR(6); --终止月份
  vs_ym_sn_beg CHAR(6); --同期起始月份
  vs_ym_sn_end CHAR(6); --同期终止月份
  --定义游标(简单的说就是一个可以遍历的结果集)
  CURSOR cur_1 IS
  SELECT area_code,CMCODE,SUM(rmb_amt)/10000 rmb_amt_sn,SUM(usd_amt)/10000 usd_amt_sn
  FROM BGD_AREA_CM_M_BASE_T
  WHERE ym >= vs_ym_sn_beg
  AND ym <= vs_ym_sn_end
  GROUP BY area_code,CMCODE;
  BEGIN
  --用输入参数给变量赋初值,用到了Oralce的SUBSTR TO_CHAR ADD_MONTHS TO_DATE 等很常用的函数。
  vs_ym_beg := SUBSTR(is_ym,1,6);
  vs_ym_end := SUBSTR(is_ym,7,6);
  vs_ym_sn_beg := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_beg,’yyyymm’), -12),’yyyymm’);
  vs_ym_sn_end := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_end,’yyyymm’), -12),’yyyymm’);
  --先删除表中特定条件的数据。
  DELETE FROM xxxxxxxxxxx_T WHERE ym = is_ym;
  --然后用内置的DBMS_OUTPUT对象的put_line方法打印出影响的记录行数,其中用到一个系统变量SQL%rowcount
  DBMS_OUTPUT.put_line(’del上月记录=’||SQL%rowcount||’条’);
  INSERT INTO xxxxxxxxxxx_T(area_code,ym,CMCODE,rmb_amt,usd_amt)
  SELECT area_code,is_ym,CMCODE,SUM(rmb_amt)/10000,SUM(usd_amt)/10000
  FROM BGD_AREA_CM_M_BASE_T
  WHERE ym >= vs_ym_beg
  AND ym <= vs_ym_end
  GROUP BY area_code,CMCODE;
  DBMS_OUTPUT.put_line(’ins当月记录=’||SQL%rowcount||’条’);
  --遍历游标处理后更新到表。遍历游标有几种方法,用for语句是其中比较直观的一种。
  FOR rec IN cur_1 LOOP
  UPDATE xxxxxxxxxxx_T
  SET rmb_amt_sn = rec.rmb_amt_sn,usd_amt_sn = rec.usd_amt_sn
  WHERE area_code = rec.area_code
  AND CMCODE = rec.CMCODE
  AND ym = is_ym;
  END LOOP;
  COMMIT;
  --错误处理部分。OTHERS表示除了声明外的任意错误。SQLERRM是系统内置变量保存了当前错误的详细信息。
  EXCEPTION
  WHEN OTHERS THEN
  vs_msg := ’ERROR IN xxxxxxxxxxx_p(’||is_ym||’):’||SUBSTR(SQLERRM,1,500);
  ROLLBACK;
  --把当前错误记录进日志表。
  INSERT INTO LOG_INFO(proc_name,error_info,op_date)
  VALUES(’xxxxxxxxxxx_p’,vs_msg,SYSDATE);
  COMMIT;
  RETURN;
  END;

 


3COME考试频道为您精心整理,希望对您有所帮助,更多信息在http://www.reader8.com/exam/

热点排行