JAVA儲存過程出現ORA-24345錯誤
寫了一個簡單的JAVA儲存過程,處理一個精度較大的數學問題,結果碰到了ORA-24345錯誤。
由於對JAVA不熟悉,JAVA儲存過程也很少使用,因此費了不少時間,總算寫了出來,但是在執行的時候發現了一個問題。
這個儲存過程是用來計算圓周率的取值的,相關演算法可以參考:http://yangtingkun.itpub.net/post/468/468870
關於儲存過程就不詳細描述了,下面直接看問題的產生:
SQL> create or replace and compile java source named "pi" as
2 import java.math.BigDecimal;
3 public class pi extends Object
4 {
5 public static String pi (int n)
6 {
7 BigDecimal result = new BigDecimal(1);
8 for (int i=n;i>0;i--)
9 {
10 BigDecimal temp = new BigDecimal(i);
11 result = new BigDecimal(2).add
12 (result.multiply
13 (temp.divide(new BigDecimal(1).add
14 (temp.multiply
15 (new BigDecimal(2))
16 ),102,BigDecimal.ROUND_HALF_UP)
17 )
18 );
19 }
20 return result.toString();
21 }
22 }
23 /
Java 已建立。
SQL> create or replace function f_pi (p_n in number) return varchar2 as
2 language java name 'pi.pi(int) return String';
3 /
函式已建立。
下面是呼叫結果:
SQL> select f_pi(10) from dual;
F_PI(10)
----------------------------------------------------------------------------------------------------
3.14084209564085725076437150740556313311731268387615136841143033093497489782319503681732783899966562
SQL> select f_pi(20) from dual;
F_PI(20)
----------------------------------------------------------------------------------------------------
3.14159211320774327955203808659259711079349608208228689356906807763678437061385664739133875908352702
SQL> select f_pi(50) from dual;
select f_pi(50) from dual
*
第 1 行出現錯誤:
ORA-24345: 出現截斷或空讀取錯誤
ERROR:
ORA-01002: 提取違反順序
未選定行
資料量比較小的時候沒有問題,一旦輸入引數值比較大,就會出現上面的這個錯誤。
測試還發現,如果將java儲存過程中的除法保留小數位數縮小一些,上面的查詢就可以得到結果,但是如果繼續增大資料量仍然會導致錯誤:
SQL> create or replace and compile java source named "pi" as
2 import java.math.BigDecimal;
3 public class pi extends Object
4 {
5 public static String pi (int n)
6 {
7 BigDecimal result = new BigDecimal(1);
8 for (int i=n;i>0;i--)
9 {
10 BigDecimal temp = new BigDecimal(i);
11 result = new BigDecimal(2).add
12 (result.multiply
13 (temp.divide(new BigDecimal(1).add
14 (temp.multiply
15 (new BigDecimal(2))
16 ),10,BigDecimal.ROUND_HALF_UP)
17 )
18 );
19 }
20 return result.toString();
21 }
22 }
23 /
Java 已建立。
SQL> select f_pi(100) from dual;
select f_pi(100) from dual
*
第 1 行出現錯誤:
ORA-29549: 類YANGTK.pi已更改, Java 會話狀態被清除
SQL> select f_pi(100) from dual;
F_PI(100)
----------------------------------------------------------------------------------------------------
3.14159265347479757400080071875069256317928871566570517689083488598820471276504302524793754286818752
SQL> select f_pi(200) from dual;
F_PI(200)
----------------------------------------------------------------------------------------------------
3.14159265347479757400080071875090016088532653926425891578738668564238870675937454358049319246851093
SQL> select f_pi(500) from dual;
select f_pi(500) from dual
*
第 1 行出現錯誤:
ORA-24345: 出現截斷或空讀取錯誤
ERROR:
ORA-01002: 提取違反順序
未選定行
開始認為是JAVA緩衝區的問題,不過當前系統的SGA和PGA的大小對於這個計算應該是綽綽有餘的:
SQL> SHOW SGA
Total System Global Area 603979776 bytes
Fixed Size 1249332 bytes
Variable Size 239079372 bytes
Database Buffers 356515840 bytes
Redo Buffers 7135232 bytes
SQL> SHOW PARAMETER SGA_TARGET
NAME TYPE VALUE
------------------------------------ ----------- ------------
sga_target big integer 576M
SQL> SHOW PARAMETER PGA
NAME TYPE VALUE
------------------------------------ ----------- ------------
pga_aggregate_target big integer 191M
查詢了一下錯誤文件:
ORA-24345: A Truncation or null fetch error occurred
Cause: A truncation or a null fetch error"
Action: Please ensure that the buffer size is long enough to store the returned data.
這個描述就比較清晰了,由於VARCHAR2長度的限制導致了JAVA儲存過程返回的結果沒有辦法傳遞給PL/SQL。
那麼只需要修改一下JAVA程式碼,返回適當長度的字串即可:
SQL> create or replace and compile java source named "pi" as
2 import java.math.BigDecimal;
3 public class pi extends Object
4 {
5 public static String pi (int n)
6 {
7 BigDecimal result = new BigDecimal(1);
8 for (int i=n;i>0;i--)
9 {
10 BigDecimal temp = new BigDecimal(i);
11 result = new BigDecimal(2).add
12 (result.multiply
13 (temp.divide(new BigDecimal(1).add
14 (temp.multiply
15 (new BigDecimal(2))
16 ),102,BigDecimal.ROUND_HALF_UP)
17 )
18 );
19 }
20 return result.toString().substring(0,102);
21 }
22 }
23 /
Java 已建立。
SQL> select f_pi(100) from dual;
select f_pi(100) from dual
*
第 1 行出現錯誤:
ORA-29549: 類YANGTK.pi已更改, Java 會話狀態被清除
SQL> select f_pi(100) from dual;
F_PI(100)
----------------------------------------------------------------------------------------------------
3.14159265358979323846264338327929528649084412679106662169776161333278097211785395952441592543372994
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-429853/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 儲存過程中DDL錯誤一例儲存過程
- java儲存過程Java儲存過程
- 儲存過程ORA-04068之錯誤解析儲存過程
- JAVA儲存過程(轉)Java儲存過程
- java操作儲存過程Java儲存過程
- 解決儲存過程擷取錯誤的問題儲存過程
- Java呼叫儲存過程(帶輸出引數)Java儲存過程
- oracle plsql儲存過程除錯出錯_PLS-00361OracleSQL儲存過程除錯
- java 呼叫oracle 儲存過程JavaOracle儲存過程
- 編寫JAVA儲存過程Java儲存過程
- java中呼叫儲存過程Java儲存過程
- plsqlDevloper 儲存過程的除錯SQLdev儲存過程除錯
- MySQL 建立儲存過程報錯MySql儲存過程
- oracle父儲存過程呼叫子儲存過程procedure與輸出引數Oracle儲存過程
- java中呼叫ORACLE儲存過程JavaOracle儲存過程
- 用java呼叫oracle儲存過程JavaOracle儲存過程
- 恢復MySQL資料庫建立儲存過程是遇到錯誤MySql資料庫儲存過程
- 查詢儲存過程報錯資訊儲存過程
- (轉)如何oracle除錯儲存過程Oracle除錯儲存過程
- openGauss 支援儲存過程除錯儲存過程除錯
- MySQL儲存過程詳解 mysql 儲存過程MySql儲存過程
- 儲存過程誤刪除的恢復儲存過程
- 儲存過程儲存過程
- vertica 如何實現儲存過程?儲存過程
- jdbc使用call呼叫儲存過程報錯JDBC儲存過程
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- MySQL儲存過程詳解 mysql 儲存過程linkMySql儲存過程
- Oracle儲存過程乾貨(一):儲存過程基礎Oracle儲存過程
- job中呼叫儲存過程,儲存過程使用AUTHID CURRENT_USER,還出現ORA-01031儲存過程
- PHP實現多儲存過程呼叫PHP儲存過程
- 儲存過程與儲存函式儲存過程儲存函式
- Oracle儲存過程Oracle儲存過程
- Mysql 儲存過程MySql儲存過程
- 使用儲存過程儲存過程
- sybase儲存過程儲存過程
- 管理儲存過程儲存過程
- 呼叫儲存過程儲存過程
- MySQL儲存過程的匯出說明MySql儲存過程