修改驅動解決SqlRowSet的Invalid scale size. Cannot be less than zero異常的處理辦法
Posted on 2009-10-09 17:18 在路上... 閱讀(1885) 評論(1) 編輯 收藏 所屬分類: JAVA相關參考:http://blog.csdn.net/horsefaced/archive/2007/08/16/1746888.aspx
這個異常源自于oracle驅動面對一個數值型的返回字段時,在得到指定的字段小數點右邊的數值數量時(Gets the designated column's number of digits to right of the decimal point.這個是原文),居然會返回-127,而oracle本身的cacheRowSet實現不允許這種情況出現,于是就會報標題所說的異常。
對于一般的做法,需要修改很多地方,包括ResultSet的decorate類,還有Spring的SqlRowSetResultSetExtractor
所謂頭痛醫頭,腳痛醫腳,這里提供一種方法直接從oracle jdbc驅動入手,徹底從源頭上修改掉該問題:
反編譯ojdbc14.jar(Oracle 9i驅動為例)
目標方法:
public int getScale(int paramInt)
throws SQLException
{
int i = getValidColumnIndex(paramInt);
return this.statement.getDBDescription()[i].scale;
}
使用javassist編寫一段代碼:
public void crackOracleDriver() {
ClassPool pool = ClassPool.getDefault();
try {
pool.insertClassPath("E:\\allproject\\bpmtrans\\lib\\ojdbc14.jar");
CtClass cc = pool.get("oracle.jdbc.driver.OracleResultSetMetaData");
System.out.println(cc);
CtClass[] param = new CtClass[1] ;
param[0]=pool.get("int");
CtMethod a = cc.getDeclaredMethod("getScale",param);
System.out.println(a);
a.setBody("{int i = getValidColumnIndex($1);\n" +
" int res=statement.getDBDescription()[i].scale;\n" +
"return res<0?0:res; }");
cc.writeFile("c:\\");

} catch (Exception e) {
e.printStackTrace();
}
}
將生成的class置換原來的class,大功告成!
這個所謂的精度,一般來說,修改了應該沒有多大問題的
這個異常源自于oracle驅動面對一個數值型的返回字段時,在得到指定的字段小數點右邊的數值數量時(Gets the designated column's number of digits to right of the decimal point.這個是原文),居然會返回-127,而oracle本身的cacheRowSet實現不允許這種情況出現,于是就會報標題所說的異常。
對于一般的做法,需要修改很多地方,包括ResultSet的decorate類,還有Spring的SqlRowSetResultSetExtractor
所謂頭痛醫頭,腳痛醫腳,這里提供一種方法直接從oracle jdbc驅動入手,徹底從源頭上修改掉該問題:
反編譯ojdbc14.jar(Oracle 9i驅動為例)
package oracle.jdbc.driver;
public class OracleResultSetMetaData
目標方法:
public int getScale(int paramInt)
throws SQLException
{
int i = getValidColumnIndex(paramInt);
return this.statement.getDBDescription()[i].scale;
}
使用javassist編寫一段代碼:



















將生成的class置換原來的class,大功告成!
這個所謂的精度,一般來說,修改了應該沒有多大問題的