oracle 10进制转36进制函数

在编写ctm脚本的时候需要用到10进制于36进制的互相转换。

36进制转10进制在shell中非常好实现。

echo $((36#00006sx1)) 就能将00006sx1转为317413 ,

但是10进制转36进制就没这么方便了,写了一个函数来进行转换。

create or replace function f_10to36(i int) return varchar is

ret varchar2(8);

var_m int;

var_s int;

begin

ret := ”;

var_s := i;

while var_s >= 36 loop

var_m := mod(var_s, 36);

if var_m < 10 then

ret := to_char(var_m) || ret;

else

ret := chr(var_m – 10 + 97) || ret;

end if;

var_s := trunc(var_s / 36);

end loop;

if var_s > 0 or (var_s = 0 and ret = ”) then

if var_s < 10 then

ret := to_char(var_s) || ret;

else

ret := chr(var_s – 10 + 97) || ret;

end if;

end if;

return lpad(ret, 8, ‘0’);

end f_10to36;

兔年快乐

兔年到了,我们家的兔宝宝也快出生了。一定要做个健康快乐的兔宝宝。
又是春节,终于体会到每逢春节倍思亲是啥意思。不好意思,我不善于表达,但亲爱的亲戚朋友们,真是想死你们了。

2010年终总结

今天是12月24,一拖再拖的datastage 认证,终于在今天通过,也是了了我一个心愿,本来计划10月份的,这一拖就是两个月,眼看2010年就要过去了,痛下决心终于在年前通过。

今年对我来讲也有很大一个改变,从开发转向运维。这其中的转变是巨大的,做实施就要面对无穷无尽的开发任务,不管想不想做,不管爱不爱做,到自己头上就要负责。

做运维这个有点不一样,很多时间是自己的,分行的问题想处理就自己处理,不想处理就转给需求组或者实施组处理,也可以给自己安排时间做一些自己想做的事情,的确,这个不像做实施,可以很容易的说我这周做了些什么,有时候做些分行的支持的工作,忙了一天回过头来好像这一天也没做什么事情。

如果给今天自己的表现打分的话,10分估计可以给自己打7分了,还是没克服自己的惰性,好多事情就一拖在拖不了了之。

使用SQL TRACE 排查ORA-06502: PL/SQL: numeric or value error 一解

四川行0728的外管作业报错,提示ORACLE错误
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 1
一般这种错误都是由于数值型的字段插入非数值产生。排查当日数据,检查各数值字段中是否有非数值数据,或者空格。
耗费两个小时排查程序中所有的数值型字段的加工,却一无所获,所有数值型字段的数据都是有效数字。

排查无解,只能使用sql trace 跟踪程序的运行。

在PRO*c 程序中增加

execute immediate ‘alter session set events ”10046 trace name context forever,level 12”’;

(注意需要使用DBA用户授予ODSBDATA用户ALTER SESSION ‘的权限,否则会报权限不足)

重新编译后运行,等待程序报错后前往数据库主机取得trace文件。
(文件位置可以使用sql查询 select value from v$parameter where name=’user_dump_dest’ ,文件名为进程号)

检查trace文件 在FETCH #39游标时程序报了错误ERROR #1:err=6502,错误时的绑定变量值为‘6011’,
BINDS #39:
kkscoacd
Bind#0
  oacdty=01 mxl=32(05) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=206001 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=800003f740020a00  bln=32  avl=04  flg=05
  value=”6011″
EXEC #39:c=0,e=120,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=1,tim=19473437793620
WAIT #39: nam=’db file sequential read’ ela= 9689 file#=53 block#=340863 blocks=1 obj#=1133089 tim=19473437803598
FETCH #39:c=0,e=10066,p=1,cr=2,cu=0,mis=0,r=1,dep=1,og=1,tim=19473437803713
ERROR #1:err=6502 tim=1994080031

从错误点往上寻找CURSOR #39 。得到游标的语句。
PARSING IN CURSOR #39 len=85 dep=1 uid=68 oct=3 lid=68 tim=19473437608957 hv=2456379465 ad=’3d82aa78′
SELECT  C_TRANS_CODE, D_TRANS_CODE FROM BM_SAFE_SPE_DSCRP_COD_DIM WHERE DSCRP_COD=:1
END OF STMT
PARSE #39:c=0,e=397,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,tim=19473437608950

程序中源码的程序为
EXECUTE IMMEDIATE   ‘SELECT  C_TRANS_CODE, D_TRANS_CODE FROM BM_SAFE_SPE_DSCRP_COD_DIM WHERE DSCRP_COD=:1 ‘
                              INTO  C_TRANS_CODE, D_TRANS_CODE
                              USING FDETAIL.SA_DSCRP_COD;

由于已知发生错误的绑定变量值为6011,手工执行sql

SELECT  C_TRANS_CODE, D_TRANS_CODE FROM BM_SAFE_SPE_DSCRP_COD_DIM WHERE DSCRP_COD=’6011′;

C_TRAN D_TRAN
—— ——
902010

返回值为902010,以及空值。根据trace文件的提示。游标的EXEC没有问题。错误发生在fetch过程中。即发生在将sql结果赋值给程序变量的过程中

检查程序中的变量定义。发现问题。定义长度为4位,而实际为6位。

  C_TRANS_CODE VARCHAR2(4);
  D_TRANS_CODE VARCHAR2(4);

修改长度后重新编译运行,作业成功。

询问四川行。原来昨日下午他们有应业务要求,将自动补录的配置表中的4位交易码改为6位。

ORA-06502: PL/SQL: numeric or value error

虽然numberic error 占大多数,但是像这个例子一样value error 也是其中的一部分。