关于ORA-01438: value larger than specified precision allowed for this column

前两天发现查询库上有一个物化视图报错:

Errors in file /home/oracle/admin/cxdb/bdump/cxdb1_j001_7420.trc:
ORA-12012: error on auto execute of job 138
ORA-12008: error in materialized view refresh path
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2251
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2457
ORA-06512: at "SYS.DBMS_IREFRESH", line 685
ORA-06512: at "SYS.DBMS_REFRESH", line 195

查看跟踪文件信息:

*** ACTION NAME:() 2012-06-10 15:06:04.898
*** MODULE NAME:() 2012-06-10 15:06:04.898
*** SERVICE NAME:(SYS$USERS) 2012-06-10 15:06:04.898
*** CLIENT ID:() 2012-06-10 15:06:04.898
*** SESSION ID:(811.63207) 2012-06-10 15:06:04.898
*** 2012-06-10 15:06:04.898
ORA-12012: error on auto execute of job 138
ORA-12008: error in materialized view refresh path
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2251
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2457
ORA-06512: at "SYS.DBMS_IREFRESH", line 685
ORA-06512: at "SYS.DBMS_REFRESH", line 195
ORA-06512: at line 1
里面也没有发现详细的那个字段长度或精度不够的信息。

物化视图中涉及到的number类型的且有精度的字段都是这样的:

,CAST(a4.fact_weight * a1.pieces/a4.pieces AS NUMBER(12,2))        AS fact_weight                              -- 实际重量
 ,CAST(a4.billing_weight * a1.pieces/a4.pieces AS NUMBER(12,2))     AS billing_weight                         -- 计费重量
,CAST(a4.total_volume * a1.pieces/a4.pieces AS NUMBER(12,2))       AS total_volume

查看物化视图的基表的对应的字段的长度也是number(12,2),因此按照这样,理应是不会有记录的值超过基表这几个字段的长度或精度的。因为在插入前,都用cast截取了,但是这个物化视图每次刷新的时候还是报这个错误。

为了查出究竟是哪些记录的长度或精度超过了number(12,2),按照基表的结构新建了一张表,写一个plsql块,将物化视图的查询语句insert  xxx select xxxxx 到新建的表里,并将异常的记录抛出来。最后查出有一条记录的total_volume 字段值的整数位是11位的,小数位是1位。而number(12,2)的整数位是10位的,而cast函数在运算的过程中并没有将11的整数cast为10位的长度,因此报这个错误,也即其实并不是在插入的时候报这个错误,而是在查询时就已经报错了。这个物化视图是有之前的一个标准视图改造过来的,在此之前,标准视图从未报过这个错误,但是我仔细分析过,并不是标准视图没有报这个错误,只是用户在查询数据是没有读到这一行数据,只是在系统中查询的是查询结果集的前1~2百行数据,如果当用户读到这行数据时,一定也会报这个错误。

为了验证cast在查询时就报这个错,测试如下例子:

SQL> SELECT CAST(123456.1  AS NUMBER(7,2)) FROM dual;
 
SELECT CAST(123456.1  AS NUMBER(7,2)) FROM dual
 
ORA-01438: value larger than specified precision allowed for this column

证明了以上的观点是正确的,因此将物化视图这几个字段的格式改为如下:

,CAST(a4.fact_weight * a1.pieces/a4.pieces AS NUMBER(18,6))        AS fact_weight                              -- 实际重量
,CAST(a4.billing_weight * a1.pieces/a4.pieces AS NUMBER(18,6))     AS billing_weight                         -- 计费重量
,CAST(a4.total_volume * a1.pieces/a4.pieces AS NUMBER(18,6))       AS total_volume

重新刷新物化视图的数据,没有报这个错误了。问题解决。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12129601/viewspace-732688/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12129601/viewspace-732688/

你可能感兴趣的:(关于ORA-01438: value larger than specified precision allowed for this column)