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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JAVA儲存過程(轉)Java儲存過程
- openGauss 支援儲存過程除錯儲存過程除錯
- plsqlDevloper 儲存過程的除錯SQLdev儲存過程除錯
- 恢復MySQL資料庫建立儲存過程是遇到錯誤MySql資料庫儲存過程
- vertica 如何實現儲存過程?儲存過程
- Oracle儲存過程中呼叫DBLink同義詞出現錯誤:PLS-00201: 必須宣告識別符號Oracle儲存過程符號
- jdbc使用call呼叫儲存過程報錯JDBC儲存過程
- [20180502]PLDEVELOP與儲存過程除錯.txtdev儲存過程除錯
- Oracle儲存過程乾貨(一):儲存過程基礎Oracle儲存過程
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- 儲存過程與儲存函式儲存過程儲存函式
- unidac儲存過程儲存過程
- firedac儲存過程儲存過程
- 呼叫儲存過程儲存過程
- mysql 儲存過程MySql儲存過程
- SQLSERVER儲存過程SQLServer儲存過程
- Oracle儲存過程Oracle儲存過程
- MySQL---------儲存過程MySql儲存過程
- 造數儲存過程儲存過程
- linux呼叫儲存過程Linux儲存過程
- Oracle儲存過程-1Oracle儲存過程
- 儲存過程——遊標儲存過程
- Winform呼叫儲存過程ORM儲存過程
- 儲存過程 傳 datatable儲存過程
- mysql儲存過程整理MySql儲存過程
- JdbcTemplate調儲存過程JDBC儲存過程
- MySQL之儲存過程MySql儲存過程
- oracle的儲存過程Oracle儲存過程
- 應用儲存過程執行報錯解決方案儲存過程
- Sql儲存過程分頁--臨時表儲存SQL儲存過程
- mybatis儲存過程返回listMyBatis儲存過程
- 資料庫儲存過程資料庫儲存過程
- mysql如何呼叫儲存過程MySql儲存過程
- Mysql 儲存過程的使用MySql儲存過程
- SQL 分頁儲存過程SQL儲存過程
- 原創:oracle 儲存過程Oracle儲存過程
- jsp中呼叫儲存過程JS儲存過程
- mongo 儲存過程詳解Go儲存過程
- Sqlserver中的儲存過程SQLServer儲存過程