从客户端调用 DB2 外部存储过程失败并显示 CPF9810

Posted

技术标签:

【中文标题】从客户端调用 DB2 外部存储过程失败并显示 CPF9810【英文标题】:DB2 external stored procedure fails with CPF9810 when called from client 【发布时间】:2019-08-23 09:30:12 【问题描述】:

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

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

当从客户端 (CALL MYLIB/TESTPROC) 调用 MYLIB/TESTPROC 时,它会失败并显示 CPF9810(找不到库 &1)。我通过 i Navigator -> Run SQL Scripts 连接到数据库。在 Connection -> JDBC Settings 我有 Default SQL schema = 'Use library list of server job' 并设置 Schema list=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 ;

【问题讨论】:

在 IBM Data Studio 中有一个屏幕,您可以在其中设置库列表。我将其设置为与 i Navigator 完全相同,但出现相同的错误。在这两种情况下,我都知道正在使用库列表,因为如果我删除了其中一个必要的库,那么运行时错误将是找不到给定的对象。 请注意,到目前为止,我并没有尝试从我自己的代码中调用该过程。我尝试了两个由 IBM 开发的命名查询工具。另外,我的过程没有参数。 为什么不在调用 CALL PGM(MYLIB/TESTPROC) 中添加库? 该消息未指定未找到的库的名称。顺便说一句,TESTPROC 是一个存储过程。 我最初的问题是存储过程在 STRSQL 中工作。它没有。我的问题是,正如我在示例中看到的那样,通过外部 sproc 调用程序对我不起作用。我已经相应地更新了问题。 【参考方案1】:

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

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

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

【讨论】:

【参考方案2】:

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

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

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

【讨论】:

【参考方案3】:

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

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

这可以防止有人无意中将您的程序放入个人库等。我通常不会在我的 SQL 客户端上指定会话库列表,而是接受系统库列表。

【讨论】:

【参考方案4】:

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

【讨论】:

这不是问题的答案。我会认为这是对您的问题的评论。如果您觉得这比 cmets 部分中的内容“更重要”,您应该编辑您的问题以包含它。

以上是关于从客户端调用 DB2 外部存储过程失败并显示 CPF9810的主要内容,如果未能解决你的问题,请参考以下文章

DB2 不指定Schema调用存储过程失败 SQLCODE=-440, SQLSTATE=42884

从外部 UDF 调用 db2ReadLog

cobol 上的外部存储过程 db2

DB2 外部存储过程(JAVA)

使用spring从db2数据库调用存储过程到java代码

通过 JMeter 调用 DB2 存储过程时出现语法错误