从客户机调用 DB2 外部存储过程失败并出现CPF9810



在绿屏会话中,当我的库列表设置为 QGPL、QTEMP、VENDRLIB1、VENDRLIB2、VENDRLIB3 时,调用程序 MYLIB/TESTPRG 会起作用。我可以在绿屏命令行上执行call MYLIB/TESTPRG

我希望能够从我的 Windows 客户端运行此命令。我创建了一个外部存储过程 MYLIB/TESTPROC,外部名称为 MYLIB/TESTPRG,正如我在各种文章中看到的那样。我最初的问题是,我可以在绿屏会话中使用上面的库列表在 STRSQL 中成功执行此过程,但这是错误的。它不起作用。它只是说"触发程序或外部例程检测到错误"。抱歉信息错误。

当从客户端调用 MYLIB/TESTPROC 时(CALL MYLIB/TESTPROC),它会失败并显示CPF9810(找不到库 &1)。我通过 i 导航器 -> 运行 SQL 脚本连接到数据库。在连接 -> JDBC 设置中,我有默认 SQL 模式 ="使用服务器作业的库列表"并设置模式列表=QGPL,QTEMP,VENDRLIB1,VENDRLIB2,VENDRLIB3。然后我执行了CALL MYLIB/TESTPROC并得到了如上所述的消息。

有效的是当我运行程序时,即 在绿屏命令行上CALL MYLIB/TESTPRG

TESTPRG是一个不带参数的C程序。存储过程定义如下:

CREATE PROCEDURE MYLIB/TESTPROC
LANGUAGE C 
SPECIFIC MYLIB/TESTPROC 
NOT DETERMINISTIC 
NO SQL 
CALLED ON NULL INPUT 
EXTERNAL NAME 'MYLIB/TESTPRG' 
PARAMETER STYLE GENERAL ;

CPF9810 - Library &1 not found意味着某些东西正在尝试访问库&1(不管是什么,你没有告诉我们),并且键入的库不在系统上的任何地方。 &1 不是库的名称,它是一个替换变量,将在作业日志中显示库名称。查看作业日志中的实际库拼写。检查拼写。检查连接以确保正确指定了所有库。该消息将准确告诉您导致问题的库。

如果程序确实在正确设置库列表时在绿屏中工作,那么我希望问题出在您的连接中,它正在尝试设置库列表。不能将不存在的库添加到库列表中。这就是为什么它在绿屏中工作,您的库必须在那里正确输入,否则它不会在库列表中。如果您尝试将带有拼写错误的库添加到绿屏的库列表中,则会收到类似的错误(相同的文本,不同的错误代码)。

找出消息的全文(查看作业日志),您将看到引发错误的内容以及库是什么。提示,SQL 不太可能抛出错误,因为这些错误看起来都像 SQL#### 或 SQ#####。更可能是 CL 命令或其处理程序由发送 CPF 消息的 IBM 服务器调用。

正如您所发现的,您可以直接调用简单的程序,而无需根据 IBM 的以下文档定义外部 SQL 过程: https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_73/db2/rbafzcallsta.htm

我相信为简单程序创建自己的外部过程定义的建议主要是为了减少歧义。 如果你的程序和过程碰巧具有匹配的名称,你需要知道规则列表,以确定正在调用哪个

。 此外,外部函数的规则与外部存储过程不同,这些规则也会混淆。

根据我的评论,我通常在调用命令中使用库进行过程调用。

在使用 CALL PGM(MYLIB/TESTPROC) 的终端会话中。或者在使用 CALL MYLIB 的 SQL 会话中。测试过程。

这可以防止某人无意中将您的过程放在个人库或类似内容中。我通常不会在我的 SQL 客户端上指定会话库列表,而是接受系统库列表。

我答应接受道格拉斯·科林克的评论作为答案。然而,我做了很多实验,我不再确定我知道什么以及什么时候知道。我的问题与参数传递给 C 程序有关。如果我可以用一个简单的案例重现它,我会问另一个问题。

在Java程序中,可以使用以下方法设置库: ds.setLibraries("list of libraries");

例:

ds.setServerName("server1");
ds.setPortNumber(1780);
ds.setDatabaseName("DBTEST");
ds.setLibraries("*LIBL,DAT452BS,DAT452BP");

最新更新