程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 解決 DB2 UDB Java 存儲過程的常見問題(下)

解決 DB2 UDB Java 存儲過程的常見問題(下)

編輯:DB2教程

這個操作失敗並且顯示 SQL4304 rc=1 錯誤消息。為什麼呢?注意,EXTERNAL NAME 子句中的類名拼寫錯了(它應該是 SQL4304RC1!abend,缺少了 “L”)。要糾正這個錯誤,應該刪除這個過程,並且在 EXTERNAL NAME 子句中采用正確的拼寫來重新創建它。


清單 18. SQL4304 rc=1 示例:糾正 SQL4304 rc=1 錯誤
$ db2 drop procedure SQL4304RC1 
DB20000I The SQL command completed successfully. 
$ db2 -tvf CreateSP.ddl 
CREATE PROCEDURE SQL4304RC1 (IN INPUT int) 
SPECIFIC SQL4304RC1 
DYNAMIC RESULT SETS 1 
DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE DB2GENERAL 
NO DBINFO 
FENCED 
THREADSAFE 
MODIFIES SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'SQL4304RC1!abend' 
DB20000I The SQL command completed successfully. 
$ db2 "call SQL4304RC1(3)" 
 Result set 1 
 -------------- 
 ID   NAME   DEPT  JOB  YEARS SALARY  COMM 
 ------ --------- ------ ----- ------ --------- --------- 
   180 Abrahams   38 Clerk   3 12009.75  236.50 
   230 Lundquist   51 Clerk   3 13369.80  189.65 
 2 record(s) selected. 
 Return Status = 0

SQL4304 RC=2


清單 19. SQL4304 rc=2 示例:AIX 上的 SQL4304RC2.Java
$ javac SQL4304RC2.Java 
$ cp SQL4304RC2.class ~/sqllib/function 
$ db2 -tvf CreateSP_wrong.ddl 
CREATE PROCEDURE SQL4304RC2 (IN INPUT int) 
SPECIFIC SQL4304RC2 
DYNAMIC RESULT SETS 1 
DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE DB2GENERAL 
NO DBINFO 
FENCED 
THREADSAFE 
MODIFIES SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'SQL4304RC2!abend' 
DB20000I The SQL command completed successfully. 
$ db2 "call SQL4304RC2(3)" 
SQL4304N Java stored procedure or user-defined function "SHAKEBS.SQL4304RC2", 
specific name "SQL4304RC2" could not load Java class "SQL4304RC2", reason code 
"2". SQLSTATE=42724

這個操作失敗並且顯示 SQL4304 rc=2 錯誤消息。為什麼呢?因為 PARAMETER STYLE 是 DB2GENERAL,所以需要確保 Java 源代碼擴展 COM.ibm.db2.app.StoredProc。為了糾正這個問題,將 extends COM.ibm.db2.app.StoredProc 添加到存儲過程類名的末尾。


清單 20. SQL4304 rc=2 示例:SQL4304RC2.Java
1  //The simplest Java SP 
2  import Java.sql.*; 
3  import COM.ibm.db2.app.*; 
4   
5  public class SQL4304RC2 extends COM.ibm.db2.app.StoredProc 
6  { 
7   public void abend (int input) throws SQLException,Exception 
8   {  
9    int errorCode; 
10  
11    try 
12    { 
13     // get caller's connection to the database 
14     Connection con = DriverManager.getConnection("jdbc:default:connection"); 
15   
16     String query = "SELECT * FROM STAFF where YEARS = ?"; 
17 
18     PreparedStatement pstmt = con.prepareStatement(query); 
19     ResultSet rs = null; 
20     pstmt.setInt(1, input); 
21     rs = pstmt.executeQuery(); 
22   
23    } 
24    catch (SQLException sqle) 
25    { 
26     errorCode = sqle.getErrorCode(); 
27     throw new SQLException( errorCode + " FAILED - " + sqle.getMessage()); 
28    }  
29   } 
30  }

代碼中的第 5 行現在正確地擴展類。重新對代碼進行編譯,然後替換 sqllib/function 中的 .class 文件,並且重新執行存儲過程。

注意:導致 SQL4304 rc=2 錯誤消息的另一個常見錯誤是,存儲過程的主方法被聲明為 “public static” 方法。PARAMETER STYLE DB2GENERAL 過程不能聲明為 “static” 方法,像以上代碼的第 7 行那樣進行聲明才是正確的。


清單 21. SQL4304 rc=2 示例:糾正 SQL4304 rc=2 錯誤
$ javac SQL4304RC2.Java 
$ cp SQL4304RC2.class ~/sqllib/function 
$ db2 "call SQL4304RC2(3)" 
 Result set 1 
 -------------- 
 ID   NAME   DEPT  JOB  YEARS SALARY  COMM 
 ------ --------- ------ ----- ------ --------- --------- 
   180 Abrahams   38 Clerk   3 12009.75  236.50 
   230 Lundquist   51 Clerk   3 13369.80  189.65 
 2 record(s) selected. 
 Return Status = 0

SQL4306


清單 22. SQL4306 示例:INSERT.sqlj
D:\>sqlj INSERT.sqlj 
  
D:\>db2sqljcustomize -user cwylaw -passWord xxxxxxxxx -url 
  jdbc:db2://claw.torolab.ibm.com:50000/sample INSERT_SJProfile0 
[ibm][db2][jcc][sqlj] 
[ibm][db2][jcc][sqlj] Begin Customization 
[ibm][db2][jcc][sqlj] Loading profile: INSERT_SJProfile0 
[ibm][db2][jcc][sqlj] Customization complete for profile 
  INSERT_SJProfile0.ser 
[ibm][db2][jcc][sqlj] Begin Bind 
[ibm][db2][jcc][sqlj] Loading profile: INSERT_SJProfile0 
[ibm][db2][jcc][sqlj] Driver defaults(user may override): BLOCKING ALL 
  VALIDATE BIND STATICREADONLY YES 
[ibm][db2][jcc][sqlj] Fixed driver options: DATETIME ISO DYNAMICRULES BIND 
[ibm][db2][jcc][sqlj] Binding package INSERT01 at isolation level UR 
[ibm][db2][jcc][sqlj] Binding package INSERT02 at isolation level CS 
[ibm][db2][jcc][sqlj] Binding package INSERT03 at isolation level RS 
[ibm][db2][jcc][sqlj] Binding package INSERT04 at isolation level RR 
[ibm][db2][jcc][sqlj] Bind complete for INSERT_SJProfile0 
D:\>jar -cvf INSERT.jar *.class *.ser 
added manifest 
adding: INSERT.class(in = 1192) (out= 684)(deflated 42%) 
D:\>db2 call sqlj.install_jar("file:///D:\INSERT.jar", 
'INSERTJAR') 
DB20000I The CALL command completed successfully. 
D:\>db2 -tvf Create.ddl 
CREATE PROCEDURE INSERT (IN INPUT CHAR(3)) 
SPECIFIC INSERT 
DYNAMIC RESULT SETS 0 
DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE Java 
NO DBINFO 
FENCED 
THREADSAFE 
MODIFIES SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'INSERT.INSERT' 
DB20000I The SQL command completed successfully. 
D:\>db2 call INSERT('abc') 
SQL4306N Java stored procedure or user-defined function "CWYLAW.INSERT", 
specific name "INSERT" could not call Java method "INSERT", 
signature "(LJava/lang/String;)V". SQLSTATE=42724

為什麼會產生這個 SQL4306 錯誤?請看看源代碼和 CREATE PROCEDURE 語句。注意,在 Java 代碼中,方法被聲明為:public static void iNSERT (String input)

注意小寫字母‘i’。


清單 23. SQL4306 示例:Windows 上的 INSERT.sqlj
//The simplest SQLJ SP 
import Java.sql.*; 
import sqlj.runtime.*; 
import sqlj.runtime.ref.*; 
 
public class INSERT 
{ 
 public static void iNSERT (String input) throws SQLException, Exception 
 
  { 
   #sql { INSERT INTO CWYLAW.StoreData (c) VALUES (:input) }; 
  }  
}


清單 24. SQL4306 示例:INSERT 過程所需的 StoreData 表的 CREATE TABLE 語句
CREATE TABLE StoreData (c char(3));

但是,在 CREATE PROCEDURE 語句中,EXTERNAL NAME 被聲明為 EXTERNAL NAME 'INSERT.INSERT'。注意大寫字母‘I’。所以,出現 SQL4306 錯誤的原因是源代碼中的 Java 方法名與 CREATE PROCEDURE 語句中的 EXTERNAL NAME 不匹配。要糾正這個問題,就要確保 Java 方法與 CREATE PROCEDURE 語句中的 EXTERNAL NAME 子句精確匹配。在這個例子中,我們選擇修改 CREATE PROCEDURE 語句而不是修改源代碼。


清單 25. SQL4306 示例:INSERT 存儲過程的正確的 CREATE PROCEDURE 語句
CREATE PROCEDURE INSERT (IN INPUT CHAR(3)) 
SPECIFIC INSERT 
DYNAMIC RESULT SETS 0 
DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE Java 
NO DBINFO 
FENCED 
THREADSAFE 
MODIFIES SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'INSERT.iNSERT' 
;

現在,INSERT 過程能夠成功運行了。


清單 26. 運行 INSERT 過程
D:\>db2 drop procedure INSERT 
DB20000I The SQL command completed successfully. 
D:\>db2 call sqlj.remove_jar('INSERTJAR') 
DB20000I The CALL command completed successfully. 
D:\>db2 call sqlj.install_jar("file:///D:\INSERT.jar", 'INSERTJAR') 
DB20000I The CALL command completed successfully. 
D:\>db2 -tvf Create.ddl 
CREATE PROCEDURE INSERT (IN INPUT CHAR(3)) 
SPECIFIC INSERT 
DYNAMIC RESULT SETS 0 
DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE Java 
NO DBINFO 
FENCED 
THREADSAFE 
MODIFIES SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'INSERT.iNSERT' 
DB20000I The SQL command completed successfully. 
D:\>db2 call INSERT('abc') 
 Return Status = 0 
  
D:\>db2 select * from StoreData 
C 
--- 
abc 
 1 record(s) selected.

還應該花點兒時間看看類型簽名的 JVM 表示,因為這可以幫助您在遇到 SQL4306 錯誤時識別出問題。SQL4306 錯誤的另一個常見原因是過程的參數與 Java 方法定義不匹配。在這個例子中,SQL4306 錯誤的末尾包含一個含義有點兒模糊的錯誤符號:


清單 27. SQL4306 錯誤顯示了 JVM 返回的 Java 類型
SQL4306N Java stored procedure or user-defined function "CWYLAW.INSERT", 
specific name "INSERT" could not call Java method "INSERT", signature 
"(LJava/lang/String;)V". SQLSTATE=42724

(Ljava/lang/String;)V 實際上是 JVM 返回的 Java 類型簽名。

表 2. Java VM 類型簽名 類型簽名 Java 類型 Z boolean B byte C char S short I int J long F float D double L fully-qualifIEd-class ; fully-qualifIEd-class [ type type[] ( arg-types ) ret-type method type

所以這個錯誤消息指出,DB2 試圖調用 Java 存儲過程 INSERT,這個過程的 Java VM 類型簽名是 (Ljava/lang/String;)V,其中 fully-qualifIEd-class 是 java/lang/String(即,輸入參數是類型 String),返回類型是 V,代表類型 void。這精確地匹配 Java 方法定義:

public static void iNSERT (String input)

現在,已經證實 Java VM 簽名是正確的,所以確定了問題不是 由於過程參數與 Java 方法定義不匹配而引起的。正如在前面發現的,EXTERNAL NAME 與 Java 方法定義不匹配是問題的原因。而且與前面一樣,可以通過重新發出正確的 CREATE PROCEDURE 語句來糾正這個問題。關於 Java VM 類型簽名的更多信息,請訪問以下 URL:

http://Java.sun.com/J2SE/1.4.2/docs/guide/jni/spec/types.Html

SQL20200

SQL20200 錯誤表示無法找到 JAR 文件。這往往意味著 JAR URL 是錯的,或者 DB2 無法找到 JAR 文件。在這個簡單的例子中,JAR 文件不存在,這造成了 SQL20200 錯誤:


清單 28. SQL20200 示例:AIX 上的 OUT_20200.Java
cwylaw@bugdbug:/home/cwylaw> javac Out_20200.Java 
cwylaw@bugdbug:/home/cwylaw> db2 connect to sample 
  Database Connection Information 
 Database server    = DB2/6000 8.2.3 
 SQL authorization ID  = CWYLAW 
 Local database alias  = SAMPLE 
cwylaw@bugdbug:/home/cwylaw> db2 "call 
sqlj.install_jar('file:/home/cwylaw/Out_20200.jar','OUT20200JAR')" 
SQL20200N The install or replace of "CWYLAW .OUT20200JAR" failed as 
"/home/cwylaw/Out_20200.jar" could not be located. 
SQLSTATE=46001

這個錯誤消息明確地指出無法找到 JAR 文件。在這種情況中,辦法很簡單。需要確保 JAR 文件名 Out_20200.jar 是正確的,並且這個文件在 /home/cwylaw/ 目錄中,然後再次安裝 JAR 文件。在這個例子中,在調用 sqlj.install_jar 例程安裝 JAR 文件之前沒有創建 JAR 文件。創建 JAR 文件並且再次安裝它。


清單 29. SQL20200 示例:通過創建 JAR 文件糾正問題
cwylaw@bugdbug:/home/cwylaw> ls 
Create.ddl    Out_20200.class Out_20200.Java 
cwylaw@bugdbug:/home/cwylaw> jar -cvf Out_20200.jar *.class 
adding: Out_20200.class (in=1466) (out=862) (deflated 41%) 
cwylaw@bugdbug:/home/cwylaw> ls 
Create.ddl    Out_20200.jar  Out_20200.class 
Out_20200.Java 
cwylaw@bugdbug:/home/cwylaw> db2 "call 
sqlj.install_jar('file:/home/cwylaw/Out_20200.jar','OUT20200JAR')" 
DB20000I The CALL command completed successfully.

SQL20201

SQL20201 的示例使用前面的 SQL4306 示例中使用過的 INSERT 存儲過程來演示 SQL20201 問題。在以下情況中會出現 SQL20201 錯誤:

試圖刪除並且重新創建存儲過程,但是在再次調用 sqlj.install_jar 之前沒有刪除 JAR 文件。

試圖刪除具有無效 JAR ID 的 JAR 文件。


清單 30. SQL20201 示例 1:在 Windows 上安裝 JAR 文件時出現的錯誤
D:\>db2 drop procedure INSERT 
DB20000I The SQL command completed successfully. 
D:\>db2 call sqlj.install_jar("file:///D:\INSERT.jar", 'INSERTJAR') 
SQL20201N The install, replace or remove of "CWYLAW .INSERTJAR" failed as 
the jar name is invalid. SQLSTATE=46002

對於第一種情況,必須先調用 sqlj.remove_jar,然後再調用 sqlj.install_jar 來再次安裝 JAR 文件。還可以簡單地調用 sqlj.replace_jar,用更新的類文件替換 JAR 文件。


清單 31. SQL20201 示例 1:通過首先刪除 JAR 文件或者簡單地替換 JAR 文件來糾正問題
D:\>db2 call sqlj.remove_jar('INSERTJAR') 
DB20000I The CALL command completed successfully. 
D:\>db2 call sqlj.install_jar("file:///D:\INSERT.jar", 'INSERTJAR') 
DB20000I The CALL command completed successfully.

或者簡單地調用 sqlj.replace_jar 來替換 JAR 文件:

D:\>db2 call sqlj.replace_jar("file:///D:\INSERT.jar", 'INSERTJAR') 
DB20000I The CALL command completed successfully.


清單 32. SQL20201 示例 2:在 Windows 上刪除 JAR 文件時發生的錯誤
D:\>db2 call sqlj.remove_jar('OUT20200') 
SQL20201N The install, replace or remove of "CWYLAW .OUT20200" failed 
  as the jar name is invalid. SQLSTATE=46002

以上錯誤消息指出 JAR ID CWYLAW.OUT20200 是無效的。確保提供正確的 JAR ID,並且再次嘗試刪除 JAR 文件。在這個例子中,正確的 JAR ID 是 OUT20200JAR,不是 OUT20200(參見前面的 SQL20200 例子)。所以,現在如果再次嘗試刪除 JAR,就會成功:


清單 33. SQL20201 示例 2:通過提供正確的 JAR ID 來糾正問題
D:\>db2 call sqlj.remove_jar('OUT20200JAR') 
DB20000I The CALL command completed successfully.

SQL20204

對於 SQL20204,最常見的問題是 CREATE PROCEDURE 中的 EXTERNAL NAME 不符合正確的格式。正確的格式如下:


清單 34. Java EXTERNAL NAME 格式
>>-'--+----------+--class_id--+-.-+--method_id--'-------------->< 
   '-jar_id :-'      '-!-'


清單 35. SQL20204 示例:Windows 上 SQL20204 錯誤的示例
D:\>db2 call sqlj.install_jar("file:///D:\Out_Language.jar",'OUTLANGUAGEJAR') 
DB20000I The CALL command completed successfully. 
D:\>db2 -tvf Create.ddl 
CREATE PROCEDURE OUT_LANGUAGE (OUT LANGUAGE CHAR(8)) 
SPECIFIC OUT_LANGUAGE 
DYNAMIC RESULT SETS 0 
DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE Java 
NO DBINFO 
FENCED 
THREADSAFE 
READS SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'OUT_LANGUAGE:Out_Language!outLanguage' 
DB21034E The command was processed as an SQL statement because it was not a 
valid Command Line Processor command. During SQL processing it returned: 
SQL20204N The user defined function or procedure "CWYLAW.OUT_LANGUAGE" was 
unable to map to a single Java method. LINE NUMBER=10. SQLSTATE=46008

在上面,EXTERNAL NAME 讓 DB2 尋找具有名稱 OUT_LANGUAGE 的 JAR ID,其中類名是 Out_Language,Java 方法是 outLanguage。但是 DB2 無法找到這個 Java 方法。為了處理這個問題,應該檢查:

是否為這個 OUT_LANGUAGE 存儲過程創建了 JAR 文件?如果創建了,那 JAR ID 名稱正確嗎?

類文件名正確嗎?類文件存在嗎?

Java 方法名正確嗎?

那麼,是什麼造成了這個 SQL20204 問題?看看 Out_Language.Java 文件中的源代碼片段:


清單 36. SQL20204 示例:Out_Language.java 中的類和 Java 方法定義
public class Out_Language { 
   public static void outLanguage(String[] outLanguage) 
...

從上面的代碼可以看出,類文件名是正確的(Out_Language)。Java 方法名也是正確的(outLanguage)。所以,最後要檢查的是 JAR ID 是否正確。注意,在前面的 sqlj.install_jar 步驟中,JAR 是用 JAR ID OUTLANGUAGEJAR 安裝的。但是,在 CREATE PROCEDURE 語句的 EXTERNAL NAME 子句中指定的是 OUT_LANGUAGE:Out_Language!outLanguage。也就是說,JAR ID 成了 OUT_LANGUAGE 而不是 OUTLANGUAGEJAR。要糾正這個問題,應該在 EXTERNAL NAME 子句中使用正確的 JAR ID:


清單 37. SQL20204 示例:OUT_LANGUAGE 過程的正確的 CREATE PROCEDURE 語句
D:\>db2 -tvf Create.ddl 
CREATE PROCEDURE OUT_LANGUAGE (OUT LANGUAGE CHAR(8)) 
SPECIFIC OUT_LANGUAGE 
DYNAMIC RESULT SETS 0 
DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE Java 
NO DBINFO 
FENCED 
THREADSAFE 
READS SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'OUTLANGUAGEJAR:Out_Language!outLanguage' 
DB20000I The SQL command completed successfully.

SQL0449

SQL0449 錯誤與 SQL20204 的情況非常相似。如果出現了 SQL0449 錯誤,大多數時候是因為 EXTERNAL NAME 子句的格式無效。


清單 38. SQL449 示例:無效的 EXTERNAL NAME
D:\>db2 connect to sample 
  Database Connection Information 
 Database server    = DB2/NT 8.2.2 
 SQL authorization ID  = CWYLAW 
 Local database alias  = SAMPLE 
D:\>db2 -tvf Create.ddl 
CREATE PROCEDURE OUT_LANGUAGE (OUT LANGUAGE CHAR(8)) 
SPECIFIC OUT_LANGUAGE 
DYNAMIC RESULT SETS 0 
DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE Java 
NO DBINFO 
FENCED 
THREADSAFE 
READS SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'Out_Language:outLanguage' 
DB21034E The command was processed as an SQL statement because it was not a 
valid Command Line Processor command. During SQL processing it returned: 
SQL0449N The statement defining routine "CWYLAW.OUT_LANGUAGE" contains an 
invalidly formatted library/function identification in the EXTERNAL NAME 
clause. LINE NUMBER=10. SQLSTATE=42878

這個錯誤消息指出 EXTERNAL NAME 子句是一個格式無效的字符串。正如前面 SQL20202 示例中討論的,正確的 Java EXTERNAL NAME 格式如下:


清單 39. Java EXTERNAL NAME 格式
>>-'--+----------+--class_id--+-.-+--method_id--'-------------->< 
   '-jar_id :-'      '-!-'

出現這個錯誤是因為‘:’只用於分隔 JAR ID 與類 ID。它不能用於分隔類 ID 與方法 ID。在這個例子中,我們希望讓 DB2 尋找類 Out_Language 中的 Java 方法 outLanguage。因此,要糾正這個問題,應該使用‘!’或‘.’替代‘:’。


清單 40. SQL449 示例:具有有效 EXTERNAL NAME 的正確 CREATE PROCEDURE 語句
D:\>db2 -tvf Create.ddl 
CREATE PROCEDURE OUT_LANGUAGE (OUT LANGUAGE CHAR(8)) 
SPECIFIC OUT_LANGUAGE 
DYNAMIC RESULT SETS 0 
DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE Java 
NO DBINFO 
FENCED 
THREADSAFE 
READS SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'Out_Language!outLanguage' 
DB20000I The SQL command completed successfully. 
D:\>db2 call out_language(?) 
 Value of output parameters 
 -------------------------- 
 Parameter Name : LANGUAGE 
 Parameter Value : Java 
 return Status = 0

現在,CREATE PROCEDURE 語句成功了,存儲過程成功運行。

SQL0444

對於 SQL0444,涉及 Java 存儲過程的常見問題包括:

SQL0444 RC=4 —— 這常常表示無法找到庫或路徑。在大多數情況下,在 fixpak 升級之後安裝或替換 JAR 文件時,或試圖構建 Java 存儲過程時可能產生這個錯誤。

解決方案: 針對數據庫運行 db2updv8 或者針對實例運行 db2iupdt(或者同時采用這兩個操作)。發生 SQL0444 RC=4 錯誤是因為在 fixpak 升級之後數據庫需要更新到當前的 fixpak 級別,而且實例鏈接需要刷新。

SQL0444 RC=9 —— 在執行 Java 存儲過程時可能發生這個錯誤。大多數時候,這是由於內存不足。

解決方案: 檢查 ulimit 設置,還要檢查實例的 DBM CFG 參數以及數據庫的 DB CFG 參數。可能需要調整這些參數,讓更多的內存供運行 Java 存儲過程使用。要檢查的一些重要參數是:

java_heap_sz —— 最大 Java 解釋器堆大小配置參數

query_heap_sz —— 查詢堆大小配置參數

aslheapsz —— 應用程序支持層堆大小配置參數

在大多數情況下,可能需要增加 Java_heap_sz 和 query_heap_sz,但是降低 aslheapsz。

SQL0440

SQL0444 錯誤表示無法找到具有匹配的參數的過程。這個錯誤不表示嚴重的問題,在運行時這常常發生。有兩個原因:

沒有通過發出 CREATE PROCEDURE 語句在當前服務器上定義過程。因此 DB2 無法定位這個過程。

解決方案: 發出 CREATE PROCEDURE 語句。

調用過程時參數的數量不正確。即,提供的輸入或輸出參數的數量不正確,或者某個參數的數據類型不正確。因此,DB2 無法找到具有匹配的參數的過程。

解決方案: 檢查 CREATE PROCEDURE 語句,確保傳遞的輸入和輸出參數的數量和數據類型都正確。

下面是第二種情況的例子,即在運行時傳遞給過程的參數數量不正確。這個例子使用 DB2 產品附帶的示例存儲過程 OUT_LANGUAGE 和 ALL_DATA_TYPES。在 UNIX 平台上,源代碼在 /instance_home/sqllib/samples/java/jdbc/SpServer.java 中,對應的 CREATE PROCEDURE 語句在 /instance_home/sqllib/samples/java/jdbc/SpCreate.db2 中,其中的 instance_home 是數據庫實例的主目錄。在 Windows 上,這些文件的默認位置是 C:\Program Files\IBM\SQLLIB\samples\java\jdbc\SpServer.java 和 C:\Program Files\IBM\SQLLIB\samples\Java\jdbc\SpCreate.db2。


清單 41. SQL0440 示例:在 Windows 上調用 OUT_LANGUAGE() 和 ALL_DATA_TYPES 過程
D:\>db2 call out_language() 
SQL0440N No authorized routine named "OUT_LANGUAGE" of type "PROCEDURE" 
having compatible arguments was found. SQLSTATE=42884 
D:\>db2 call all_data_types (32000, 2147483000, 21478483000, 100000, 2500000) 
SQL0440N No authorized routine named "ALL_DATA_TYPES" of type "PROCEDURE" 
having compatible arguments was found. SQLSTATE=42884

我們來看看為什麼會返回 SQL0440。先看一下 CREATE PROCEDURE 語句,確定每個存儲過程所需要的參數。


清單 42. SQL0440 示例:OUT_LANGUAGE 和 ALL_DATA_TYPES 過程的 CREATE PROCEDURE 語句
CREATE PROCEDURE OUT_LANGUAGE (OUT LANGUAGE CHAR(8)) 
SPECIFIC JDBC_OUT_LANGUAGE 
DYNAMIC RESULT SETS 0 
DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE Java 
NO DBINFO 
FENCED 
THREADSAFE 
READS SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'SpServer.outLanguage' 
CREATE PROCEDURE ALL_DATA_TYPES ( 
 INOUT small SMALLINT, 
 INOUT intIn INTEGER, 
 INOUT bigIn BIGINT, 
 INOUT realIn REAL, 
 INOUT doubleIn DOUBLE, 
 OUT charOut CHAR(1), 
 OUT charsOut CHAR(15), 
 OUT varcharOut VARCHAR(12), 
 OUT dateOut DATE, 
 OUT timeOut TIME) 
SPECIFIC JDBC_ALL_DAT_TYPES 
DYNAMIC RESULT SETS 0 
NOT DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE Java 
NO DBINFO 
FENCED 
THREADSAFE 
READS SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'SpServer.allDataTypes'

從 CREATE PROCEDURE 語句可以看出:

OUT_LANGUAGE 過程需要一個 char 類型的輸出參數。

ALL_DATA_TYPES 過程需要 5 個輸入/輸出參數和 5 個輸出參數,參數類型如上所示。

對於輸入參數,提供具有正確數據類型的正確值。對於每個輸出參數,使用一個‘?’。對於輸入/輸出參數,因為它們用於輸入和輸出兩種用途,所以要像對待輸入參數那樣提供正確的值。因此,應該像下面這樣調用這些過程:


清單 43. SQL0440 示例:正確地調用 OUT_LANGUAGE 和 ALL_DATA_TYPES 過程
D:\>db2 call out_language(?) 
 Value of output parameters 
 -------------------------- 
 Parameter Name : LANGUAGE 
 Parameter Value : Java 
 Return Status = 0 
D:\>db2 call all_data_types (32000, 2147483000, 21478483000, 100000, 
2500000, ?, ?, ?, ?, ?) 
 Value of output parameters 
 -------------------------- 
 Parameter Name : SMALL 
 Parameter Value : 16000 
 Parameter Name : INTIN 
 Parameter Value : 1073741500 
 Parameter Name : BIGIN 
 Parameter Value : 10739241500 
 Parameter Name : REALIN 
 Parameter Value : +5.00000E+004 
 Parameter Name : DOUBLEIN 
 Parameter Value : +1.25000000000000E+006 
 Parameter Name : CHAROUT 
 Parameter Value : S 
 Parameter Name : CHARSOUT 
 Parameter Value : SCOUTTEN 
 Parameter Name : VARCHAROUT 
 Parameter Value : MARILYN 
 Parameter Name : DATEOUT 
 Parameter Value : 09/27/2005 
 Parameter Name : TIMEOUT 
 Parameter Value : 11:30:16 
 Return Status = 0

關於如何從命令行處理程序(CLP)調用過程的更多信息,請訪問:http://publib.boulder.ibm.com/infocenter/db2help/index.JSP?topic=/com.ibm.db2.udb.doc/ad/t0007055.htm。

SQL1042

盡管錯誤消息 “SQL1042C An unexpected system error occurred” 聽起來非常嚴重,但是不必擔心。常常能夠糾正這個問題。當看到這個 SQL1042 錯誤時,一定要檢查 db2diag.log,因為這個日志文件常常包含有用的信息,可以指出造成問題的原因。最常見的問題是:

安裝 JAR 文件時的 SQL1042

解決方案 1: 檢查是否執行了適合平台的所有 Java 設置步驟。在 UNIX 平台上出現這個問題很可能是因為對於 HPUX 和 Linux 需要特殊的 Java 設置步驟。還要檢查並且確保創建了正確的符號鏈接,指向適合平台的 Java 共享庫。

解決方案 2: 檢查是否存在權限問題,造成 DB2 不能訪問 /sqllib/function/jar 目錄。出現 SQL1042 還可能是因為無效的路徑名或不可訪問的網絡路徑。

調用存儲過程時的 SQL1042

解決方案 1: 檢查 ASLHEAPSZ 和/或 QUERY_HEAP_SZ 參數。

解決方案 2: 檢查 DB2_FMP_COMM_HEAPSZ 注冊表變量。


清單 44. SQL1042 示例 1:在安裝 JAR 文件期間造成 SQL1042 的權限問題
cwylaw@bugdbug:/home/cwylaw> javac Out_20200.Java 
cwylaw@bugdbug:/home/cwylaw> jar -cvf Out_20200.jar *.class 
cwylaw@bugdbug:/home/cwylaw> db2 connect to sample 
  Database Connection Information 
 Database server    = DB2/6000 8.2.3 
 SQL authorization ID  = CWYLAW 
 Local database alias  = SAMPLE 
 
 
cwylaw@bugdbug:/home/cwylaw> db2 "call 
sqlj.install_jar('file:/home/cwylaw/Out_20200.jar','OUT20200')" 
SQL1042C An unexpected system error occurred. SQLSTATE=58004

需要檢查 db2diag.log 來獲得更多信息。


清單 45. SQL1042 示例 1:在安裝 JAR 文件期間造成 SQL1042 的權限問題。相關的 db2diag.log 條目
2005-09-29-11.32.42.602876-240 E102575C539    LEVEL: Warning (OS) 
PID   : 214958        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-265        APPID: *LOCAL.cwylaw.050929151244 
FUNCTION: DB2 UDB, oper system services, sqlomkdirp, probe:100 
CALLED : OS, -, unspecifIEd_system_function 
OSERR  : EACCES (13) "The file Access permissions do not allow 
the specifIEd action." 
DATA #1 : File name, 39 bytes 
/home/cwylaw/sqllib/function/jar/CWYLAW 
 
2005-09-29-11.32.42.627442-240 I103115C588    LEVEL: Error 
PID   : 214958        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-265        APPID: *LOCAL.cwylaw.050929151244 
FUNCTION: DB2 UDB, oper system services, sqlomkdirp, probe:10 
MESSAGE : directory: 
DATA #1 : Hexdump, 39 bytes 
0x2FF11FB0 : 2F68 6F6D 652F 6377 796C 6177 2F73 716C  /home/cwylaw/sql 
0x2FF11FC0 : 6C69 622F 6675 6E63 7469 6F6E 2F6A 6172  lib/function/jar 
0x2FF11FD0 : 2F43 5759 4C41 57             /CWYLAW 
2005-09-29-11.32.42.627837-240 I103704C440    LEVEL: Error 
PID   : 214958        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-265        APPID: *LOCAL.cwylaw.050929151244 
FUNCTION: DB2 UDB, oper system services, sqlomkdirp, probe:20 
MESSAGE : permissions: 
DATA #1 : Hexdump, 4 bytes 
0x2FF11E4C : 0000 01FD                 ... 
2005-09-29-11.33.35.148685-240 E104145C539    LEVEL: Warning (OS) 
PID   : 214958        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-291        APPID: *LOCAL.cwylaw.050929153332 
FUNCTION: DB2 UDB, oper system services, sqlomkdirp, probe:100 
CALLED : OS, -, unspecifIEd_system_function 
OSERR  : EACCES (13) "The file Access permissions do not allow the 
specifIEd action." 
DATA #1 : File name, 39 bytes 
/home/cwylaw/sqllib/function/jar/CWYLAW 
2005-09-29-11.33.35.149550-240 I104685C588    LEVEL: Error 
PID   : 214958        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-291        APPID: *LOCAL.cwylaw.050929153332 
FUNCTION: DB2 UDB, oper system services, sqlomkdirp, probe:10 
MESSAGE : directory: 
DATA #1 : Hexdump, 39 bytes 
0x2FF11FB0 : 2F68 6F6D 652F 6377 796C 6177 2F73 716C  /home/cwylaw/sql 
0x2FF11FC0 : 6C69 622F 6675 6E63 7469 6F6E 2F6A 6172  lib/function/jar 
0x2FF11FD0 : 2F43 5759 4C41 57             /CWYLAW 
2005-09-29-11.33.35.149928-240 I105274C440    LEVEL: Error 
PID   : 214958        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-291        APPID: *LOCAL.cwylaw.050929153332 
FUNCTION: DB2 UDB, oper system services, sqlomkdirp, probe:20 
MESSAGE : permissions: 
DATA #1 : Hexdump, 4 bytes 
0x2FF11E4C : 0000 01FD

從 db2diag.log 中可以看到,無法訪問 /home/cwylaw/sqllib/function/jar/CWYLAW 目錄。這是 JAR 文件的默認位置,其中的 CWYLAW 是這個例子中的實例名。現在,應該檢查 /home/cwylaw/sqllib/function/jar/CWYLAW 目錄上的權限,找到錯誤的設置。下面的例子顯示 /function/jar 目錄的讀寫權限已經被刪除。要糾正這個問題,應該將權限改回默認設置:


清單 46. SQL1042 示例 1:糾正在安裝 JAR 文件期間造成 SQL1042 的權限問題
cwylaw@bugdbug:/home/cwylaw/sqllib/function> ls -al | grep jar 
d--x-wx--x  3 cwylaw  build      512 Sep 28 12:36 jar 
cwylaw@bugdbug:/home/cwylaw/sqllib/function> chmod +rw jar 
cwylaw@bugdbug:/home/cwylaw/sqllib/function> ls -al | grep jar 
drwxrwxr-x 3 cwylaw  build      512 Sep 28 12:36 jar 
cwylaw@bugdbug:/home/cwylaw/sqllib/function> db2 "call 
  sqlj.install_jar('file:/home/cwylaw/Out_20200.jar','OUT20200')" 
DB20000I The CALL command completed successfully.


清單 47. SQL1042 示例 2:不正確的 ASLHEAPSZ 和/或 QUERY_HEAP_SZ
cwylaw@bugdbug:/home/cwylaw> db2 "call out_language(?)" 
SQL1042C An unexpected system error occurred. SQLSTATE=58004

查看 db2diag.log 中時間戳與問題發生的時間匹配的相關條目。


清單 48. SQL1042 示例 2:不正確的 ASLHEAPSZ 和/或 QUERY_HEAP_SZ。相關的 db2diag.log 條目
2005-09-28-23.09.01.831251-240 I32479C640     LEVEL: Error 
PID   : 180988        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-16         APPID: *LOCAL.cwylaw.050929030901 
FUNCTION: DB2 UDB, routine_infrastructure, sqlerGetFMPIPC, probe:70 
MESSAGE : InsufficIEnt memory available for IPC communication with the 
     db2fmp process. Use the DB2_FMP_COMM_HEAPSZ registry variable 
     to adjust the amount of memory available for fenced routines. 
DATA #1 : Hexdump, 4 bytes 
0x2FF14260 : 0000 0000                 ... 
2005-09-28-23.09.01.837606-240 E33120C586     LEVEL: Error 
PID   : 180988        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-16         APPID: *LOCAL.cwylaw.050929030901 
FUNCTION: DB2 UDB, routine_infrastructure, sqlerGetFMPIPC, probe:70 
MESSAGE : ADM11002E InsufficIEnt shared memory available for 
     communication with the db2fmp process. Use the 
     DB2_FMP_COMM_HEAPSZ registry variable to increase the amount 
     of shared memory available for fenced routines. 
 
2005-09-28-23.09.01.840540-240 I33707C493     LEVEL: Severe 
PID   : 180988        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-16         APPID: *LOCAL.cwylaw.050929030901 
FUNCTION: DB2 UDB, routine_infrastructure, sqlerGetFMPIPC, probe:60 
RETCODE : ZRC=0x8B0F003B=-1961951173=SQLO_NOMEM_UND 
     "No memory available in 'Undefined Heap'" 
     DIA8300C A memory heap error has occurred. 
 
2005-09-28-23.09.01.893785-240 I34201C446     LEVEL: Severe 
PID   : 180988        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-16         APPID: *LOCAL.cwylaw.050929030901 
FUNCTION: DB2 UDB, routine_infrastructure, sqlerAddFmpToPool, probe:20 
MESSAGE : DiagData 
DATA #1 : Hexdump, 4 bytes 
0x2FF143F0 : FFFF FBEE                 ... 
2005-09-28-23.09.01.939694-240 I34648C640     LEVEL: Error 
PID   : 180988        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-16         APPID: *LOCAL.cwylaw.050929030901 
FUNCTION: DB2 UDB, routine_infrastructure, sqlerGetFMPIPC, probe:70 
MESSAGE : InsufficIEnt memory available for IPC communication with the 
     db2fmp process. Use the DB2_FMP_COMM_HEAPSZ registry variable 
     to adjust the amount of memory available for fenced routines. 
DATA #1 : Hexdump, 4 bytes 
0x2FF14260 : 0000 0000                 ...

注意,db2diag.log 指出內存不足,而且建議調整 DB2_FMP_COMM_HEAPSZ 變量。在開始調整任何當前設置之前,檢查兩個常常導致 SQL1042 錯誤的配置參數 ASLHEAPSZ 和 QUERY_HEAP_SZ。


清單 49. SQL1042 示例 2:當出現 SQL1042 時的 ASLHEAPSZ 和 QUERY_HEAP_SZ 值
Application support layer heap size (4KB)  (ASLHEAPSZ) = 20000 
Max requester I/O block size (bytes)     (RQRIOBLK) = 32767 
Query heap size (4KB)          (QUERY_HEAP_SZ) = 20000

ASLHEAPSZ 的默認值是 15,QUERY_HEAP_SZ 的默認值是 1000。評估這些值對於您的環境是否太高或者太低了。在大多數情況下,要麼是 QUERY_HEAP_SZ 太低,致使 DB2 無法執行存儲過程中的查詢,要麼是 ASLHEAPSZ 太高,致使沒有足夠的內存來分配大型 ASLHEAPSZ。在這個例子中,ASLHEAPSZ 太高,所以下面的例子將它降低到 2000。另外還將 QUERY_HEAP_SZ 降低到 2000,因為示例 OUT_LANGUAGE 存儲過程只包含一個非常簡單的查詢。現在,存儲過程成功運行了。


清單 50. SQL1042 示例 2:通過降低 ASLHEAPSZ 和 QUERY_HEAP_SZ 來糾正問題
cwylaw@bugdbug:/home/cwylaw> db2 update dbm cfg using ASLHEAPSZ 2000 
DB20000I The UPDATE DATABASE MANAGER CONFIGURATION command completed 
successfully. 
SQL1362W One or more of the parameters submitted for immediate modification 
were not changed dynamically. ClIEnt changes will not be effective until the 
next time the application is started or the TERMINATE command has been issued. 
Server changes will not be effective until the next DB2START command. 
cwylaw@bugdbug:/home/cwylaw> db2 update dbm cfg using QUERY_HEAP_SZ 2000 
DB20000I The UPDATE DATABASE MANAGER CONFIGURATION command completed 
successfully. 
SQL1362W One or more of the parameters submitted for immediate modification 
were not changed dynamically. ClIEnt changes will not be effective until the 
next time the application is started or the TERMINATE command has been issued. 
Server changes will not be effective until the next DB2START command. 
cwylaw@bugdbug:/home/cwylaw> db2stop 
SQL1064N DB2STOP processing was successful. 
cwylaw@bugdbug:/home/cwylaw> db2start 
SQL1063N DB2START processing was successful. 
cwylaw@bugdbug:/home/cwylaw> db2 connect to sample 
  Database Connection Information 
 Database server    = DB2/6000 8.2.3 
 SQL authorization ID  = CWYLAW 
 Local database alias  = SAMPLE 
cwylaw@bugdbug:/home/cwylaw> db2 "call out_language(?)" 
 Value of output parameters 
 -------------------------- 
 Parameter Name : LANGUAGE 
 Parameter Value : Java 
 Return Status = 0

如果將 DB2_FMP_COMM_HEAPSZ 設置為 0,那麼也會發生 SQL1042 錯誤。這樣的設置會阻止調用任何防護例程。


清單 51. SQL1042 示例 3:DB2_FMP_COMM_HEAPSZ=0。相關的 db2diag.log 條目
2005-09-28-23.26.05.803665-240 I88569C412     LEVEL: Warning 
PID   : 184868        TID : 1      PROC : db2sysc 
INSTANCE: cwylaw        NODE : 000 
FUNCTION: DB2 UDB, base sys utilitIEs, sqleInitSysCtlr, probe:92 
DATA #1 : String, 146 bytes 
Warning! DB2_FMP_COMM_HEAPSZ is set to 0. 
This means no fmps (including Health Monitor) and automatic 
maintenance features of DB2 will be started. 
... 
2005-09-28-23.26.20.134728-240 I89996C486     LEVEL: Error 
PID   : 180134        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-7         APPID: *LOCAL.cwylaw.050929032612 
FUNCTION: DB2 UDB, routine_infrastructure, sqlerGetFMPIPC, probe:65 
MESSAGE : Can not run fenced routines (including Health Monitor) and 
     automatic maintenance features of DB2 because 
     DB2_FMP_COMM_HEAPSZ = 0. 
 
2005-09-28-23.26.20.139210-240 E90483C515     LEVEL: Error 
PID   : 180134        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-7         APPID: *LOCAL.cwylaw.050929032612 
FUNCTION: DB2 UDB, routine_infrastructure, sqlerGetFMPIPC, probe:65 
MESSAGE : ADM11001E DB2 did not create a memory segment for running 
     fenced routines. This was specifIEd by the use of 
     DB2_FMP_COMM_HEAPSZ registry variable. 
2005-09-28-23.26.20.142093-240 I90999C379     LEVEL: Severe 
PID   : 180134        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-7         APPID: *LOCAL.cwylaw.050929032612 
FUNCTION: DB2 UDB, routine_infrastructure, sqlerGetFMPIPC, probe:8 
RETCODE : ZRC=0x00000000=0=PSM_OK "Unknown" 
2005-09-28-23.26.20.142601-240 I91379C446     LEVEL: Severe 
PID   : 180134        TID : 1      PROC : db2agent (SAMPLE) 
INSTANCE: cwylaw        NODE : 000     DB  : SAMPLE 
APPHDL : 0-7         APPID: *LOCAL.cwylaw.050929032612 
FUNCTION: DB2 UDB, routine_infrastructure, sqlerAddFmpToPool, probe:20 
MESSAGE : DiagData 
DATA #1 : Hexdump, 4 bytes 
0x2FF14410 : FFFF FBEE                 ...

要糾正這個問題,可以將 DB2_FMP_COMM_HEAPSZ 設置為合適的值,或者不設置它(這樣它會使用默認值)。


清單 52. SQL1042 示例 3:不正確的 DB2_FMP_COMM_HEAPSZ=0。糾正這個問題
cwylaw@bugdbug:/home/cwylaw> db2set -all 
[i] DB2_FMP_COMM_HEAPSZ=0 
[i] DB2COMM=TCPIP 
[g] DB2SYSTEM=BUGDBUG 
[g] DB2DBDFT=SAMPLE 
[g] DB2COMM=TCPIP 
[g] DB2ADMINSERVER=db2asv8 
[g] DB2AUTOSTART=YES 
cwylaw@bugdbug:/home/cwylaw> db2set DB2_FMP_COMM_HEAPSZ= 
cwylaw@bugdbug:/home/cwylaw> db2set -all 
[i] DB2COMM=TCPIP 
[g] DB2SYSTEM=BUGDBUG 
[g] DB2DBDFT=SAMPLE 
[g] DB2COMM=TCPIP 
[g] DB2ADMINSERVER=db2asv8 
[g] DB2AUTOSTART=YES 
cwylaw@bugdbug:/home/cwylaw> db2 terminate 
DB20000I The TERMINATE command completed successfully. 
cwylaw@bugdbug:/home/cwylaw> db2stop 
SQL1064N DB2STOP processing was successful. 
cwylaw@bugdbug:/home/cwylaw> db2start 
SQL1063N DB2START processing was successful. 
cwylaw@bugdbug:/home/cwylaw> db2 connect to sample 
  Database Connection Information 
 Database server    = DB2/6000 8.2.3 
 SQL authorization ID  = CWYLAW 
 Local database alias  = SAMPLE 
cwylaw@bugdbug:/home/cwylaw> db2 "call out_language(?)" 
 Value of output parameters 
 -------------------------- 
 Parameter Name : LANGUAGE 
 Parameter Value : Java 
 Return Status = 0 
cwylaw@bugdbug:/home/cwylaw>

SQL1131


清單 53. SQL1131 示例:Windows 上的 SQL1131.Java
D:\>javac SQL1131.Java 
D:\>copy SQL1131.class "C:\Program Files\IBM\SQLLIB\Function" 
    1 file(s) copIEd. 
D:\>db2 -tvf Create.ddl 
CREATE PROCEDURE SQL1131 (IN INPUT CHAR(10)) 
SPECIFIC SQL1131 
DYNAMIC RESULT SETS 1 
DETERMINISTIC 
LANGUAGE Java 
PARAMETER STYLE Java 
NO DBINFO 
FENCED 
THREADSAFE 
MODIFIES SQL DATA 
PROGRAM TYPE SUB 
EXTERNAL NAME 'SQL1131!abend' 
; 
DB20000I The SQL command completed successfully. 
D:\>db2 call SQL1131('Mgr') 
SQL1131N DARI (Stored Procedure) process has been terminated abnormally. 
SQLSTATE=38503

這個操作失敗並且顯示 SQL1131N 錯誤。為什麼呢?這可能有許多原因。ASLHEAPSZ 或 QUERY_HEAP_SZ 可能不夠大,這兩個配置參數是在數據庫管理器配置文件中定義的。如果編寫存儲過程的方式使它所在的 JVM 終止,那麼它也會拋出這個錯誤。為了判斷非正常終止的原因,db2diag.log 有時包含有價值的信息,包括一個堆棧跟蹤,其中包含 Java 存儲過程最後執行的一系列調用,可以利用這些信息判斷失敗的原因。

在這個例子中,檢查 Java 存儲過程代碼來找出問題。


清單 54. SQL1131 示例:SQL1131.Java
1   //The simplest Java SP 
2   import Java.sql.*; 
3  
4   public class SQL1131 
5   { 
6    public static void abend (String input, ResultSet[] rsout) throws 
        SQLException, Exception 
7    { 
8 
9        
10    int errorCode; 
11 
12    try 
13    { 
14     // get caller's connection to the database 
15     Connection con = 
        DriverManager.getConnection("jdbc:default:connection"); 
16 
17     String query = "SELECT * FROM STAFF WHERE JOB = ?"; 
18 
19     PreparedStatement pstmt = con.prepareStatement(query); 
20     pstmt.setString(1, input); 
21     rsout[0] = pstmt.executeQuery(); 
22 
23     Java.lang.Runtime.getRuntime().exit(0); 
24 
25    }     
26    catch (SQLException sqle) 
27    { 
28     errorCode = sqle.getErrorCode(); 
29     throw new SQLException( errorCode + " FAILED" ); 
30    } 
31 
32    } 
33   }

在上面的代碼中,第 23 行將終止當前運行的 JVM,這會造成存儲過程 “非正常終止”。可以看到,這是發生這種錯誤的明顯例子(有點兒過度簡化了)。要糾正這個問題,可以從上面的代碼中刪除第 23 行,重新編譯存儲過程,並且將新的類文件轉移到 sqllib\function 文件夾。


清單 55. SQL1131 示例:糾正 SQL1131 錯誤
D:\>javac SQL1131.Java 
D:\>copy SQL1131.class "C:\Program Files\IBM\SQLLIB\Function" 
Overwrite C:\Program Fils\IBM\SQLLIB\Function\SQL1131.class? (Yes/No/All): Y 
    1 file(s) copIEd. 
D:\>db2 call SQL1131('Mgr') 
 Result set 1 
 -------------- 
 ID   NAME   DEPT  JOB  YEARS SALARY  COMM 
 ------ --------- ------ ----- ------ --------- --------- 
   10 Sanders    20 Mgr    7 18357.50     - 
   30 Marenghi   38 Mgr    5 17506.75     - 
   50 Hanes     15 Mgr    10 20659.80     - 
   100 Plotz     42 Mgr    7 18352.80     - 
   140 Fraye     51 Mgr    6 21150.00     - 
   160 Molinare   10 Mgr    7 22959.20     - 
   210 Lu      10 Mgr    10 20010.00     - 
   240 DanIEls    10 Mgr    5 19260.25     - 
   260 Jones     10 Mgr    12 21234.00     - 
   270 Lea      66 Mgr    9 18555.50     - 
   290 Quill     84 Mgr    10 19818.00     - 
 11 record(s) selected. 
 Return Status = 0

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved