WEB开发网
开发学院数据库DB2 解决 DB2 UDB Java 存储过程的常见问题(下) 阅读

解决 DB2 UDB Java 存储过程的常见问题(下)

 2009-11-23 00:00:00 来源:WEB开发网   
核心提示:这个操作失败并且显示 SQL4304 rc=1 错误消息,为什么呢?注意,解决 DB2 UDB Java 存储过程的常见问题(下),EXTERNAL NAME 子句中的类名拼写错了(它应该是 SQL4304RC1!abend,缺少了 “L”),可以从上面的代码中删除第 23 行,重新编译存储过程

这个操作失败并且显示 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 类型
Zboolean
Bbyte
Cchar
Sshort
Iint
Jlong
Ffloat
Ddouble
L fully-qualified-class ;fully-qualified-class
[ typetype[]
( arg-types ) ret-typemethod 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

Tags:解决 DB UDB

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接