我在 OS 7.4 上运行它。
CREATE PROCEDURE MYLIB.MYSQLPROCEDURE1(PARM1 IN INT)
LANGUAGE SQL
SPECIFIC MYQ001
BEGIN
END;
如果我使用“RUNSQLSTM”运行它,代码将被编译并运行,并且使用 CRTSQLCI 和 CRTCMOD 的假脱机文件创建程序 MYQ001,没有错误。
一旦我使用带有 *NOGEN 的 CRTSQLCI 手动执行此操作,这就会给我一个代码:-
CRTSQLCI OBJ(MYLIB/MYQ001) SRCFILE(MYLIB/QSQLSRC) SRCMBR(MYQ001) COMMIT(*NONE) OPTION(*NOGEN) CLOSQLCSR(*ENDMOD) TOSRCFILE(QTEMP/QCSRC)
当我尝试通过上面的代码提供在 QTEMP/QCSRC 中生成的代码以创建模块时:-
CRTSQLCI OBJ(MYLIB/MYQ001) SRCFILE(QTEMP/QCSRC) SRCMBR(MYQ001) COMMIT(*NONE) OBJTYPE
(*MODULE) OUTPUT(*PRINT)
CLOSQLCSR(*ENDMOD) TOSRCFILE(QTEMP/QMODSRC)
我收到“SQL 预编译失败”消息。
SQL0011 30 58 Position 1 Comment not closed.
SQL5008 30 57 Position 11 Right parenthesis or right brace not found.
SQL0011 30 58 Position 1 Comment not closed.
SQL0053 10 No SQL statements found.
为什么这一切都使用 RUNSQLSTM 而不是 CRTSQLCI?
如果有任何帮助解决,即使是这样说也是不可能的,我将不胜感激?
问候, 杰姆地毯
我想我理解你的困惑。您似乎认为 RUNSQLSTM 正在调用 CRTSQLCI 和 CRTCMOD,甚至可能是 CRTSRVPGM,而 CRTSQLCI 只是针对您在 RUNSQLSTM 中键入的 SQL 源运行。这一切都是错误的。
这些程序的作用:
RUNSQLSTM - SQL 客户端将 SQL 语句传递给 DB2 for i 数据库进行解释和执行。
CRTSQLCI - 将嵌入式 SQL 代码转换为本机 C 代码的 C 预编译器。这会调用其中一个 C 编译器来生成模块或程序对象。
CRTCMOD - 生成模块的 C 编译器。这个没有 SQL 预编译器。
CRTSRVPGM - 摄取模块以构建服务程序的链接器。
请注意,虽然 CRTSQLCI 将嵌入式 SQL 转换为本机 C 代码,但您键入 RUNSQLSTM 的 SQL 格式不正确,因此 CRTSQLCI 无法将其转换为本机 C 代码。还有一整本其他手册告诉您如何使用嵌入式 SQL 编写 C 代码。这就是 CRTSQLCI 所需要的。它看起来一点也不像独立的 SQL 语句。 在 C 和 C++ 应用程序中编写 SQL 语句
所以发生了什么?为什么每个可以连接到 DB2 for i 的 SQL 客户端都可以创建和编译 DB2 for i 例程?他们是否都必须将存储过程代码转换为带有嵌入式 SQL 的 C 代码并将其传递给 CRTSQLCI?不,他们都没有。 SQL 客户端只需将原始 SQL 传递给 DB2 for i。服务器本身知道如何使用传递给预编译器的嵌入式 SQL 生成 C 代码。预编译器然后将嵌入的 sql 语句转换为本机 C 代码,然后将生成的源代码传递给 C 编译器,最后 DB2 将生成的模块传递给 CRTSRVPGM 以将其转换为服务程序。最终的服务程序名称存储在 SQL 目录中,以便将来可以直接执行对例程的调用。
看来你少了几个步骤。但是如果你了解 C,你可以用 C 编写一个 shell,允许你插入几乎任何你想要的 SQL 存储过程,然后使用 CRTSQLCI 将它编译成一个程序,然后执行生成的程序对象来创建服务程序。
或者如果你了解 RPG,你可以用它来做同样的事情。但是,不是使用 CRTSQLCI,而是使用 CRTSQLRPGI 来创建程序对象。
或者,您可以只使用 RUNSQLSTM,因为这将在一个步骤中完成所有这些。
完全不清楚 CRTSQLCI 与您的 SQL 代码有什么关系。 它意味着完全不同的东西。
Create SQL ILE C Object (CRTSQLCI) 命令调用结构化查询语言 (SQL) 预编译器预编译包含 SQL 语句的 C 源代码,生成临时源代码成员,然后可选地调用 ILE C 编译器创建模块,创建程序,或创建服务程序。 创建 SQL ILE C 对象 (CRTSQLCI)
需要编译包含嵌入式SQL的C代码。例如:
#include "stdio.h"
#include "sqlcli.h"
#include "sql.h"
main (int argc, char *argv[] )
{
EXEC SQL INCLUDE SQLCA;
char vname[20];
EXEC SQL SELECT vname INTO :vname FROM video WHERE videnum=10;
printf("%s", vname);
}
在你的情况下,使用 RUNSQLSTM 是正确的
运行 SQL 语句 (RUNSQLSTM) 命令处理结构查询语言 (SQL) 语句的源文件。 运行 SQL 语句 (RUNSQLSTM)
仍然不确定这是非重复...但是
首先...
预编译器的输出被设计为由常规编译器处理。所以你不应该使用
CRTSQLCI
你应该使用CRTCMOD
.
其次,确保
QTEMP/QCSRC
不存在或者如果它存在它有足够大的行长度,从你发布的错误看来预编译器输出的一些行可能已被截断。
老实说,我从来没有听说过 RUNSQLSTM 使用 CRTSQLCI——在我看来这些是完全不同的东西。 当您需要像这样的参数化 SQL 查询时,我可以理解 RUNSQLSTM 和 CRTQMQRY/STRQMQRY/DLTQMQRY 组合之间的选择:
CREATE OR REPLACE PROCEDURE &ALIB.CLEAR_USER_QUEUE
(
IN USER_QUEUE VARCHAR(10),
IN USER_QUEUE_LIBRARY VARCHAR(10) DEFAULT '*LIBL',
IN KEY_DATA VARCHAR(256) DEFAULT NULL,
IN KEY_ORDER CHARACTER(2) DEFAULT NULL
)
SPECIFIC &ALIB.QSQCLRUSRQ
LANGUAGE RPGLE
NOT DETERMINISTIC
NO SQL
PARAMETER STYLE SQL
EXTERNAL NAME &EXTNAME
NOT FENCED
PROGRAM TYPE SUB
然后我们使用包含
的CL程序DLTQMQRY QMQRY(QTEMP/USRQCLR_P)
MONMSG MSGID(CPF2105)
CRTQMQRY QMQRY(QTEMP/USRQCLR_P) SRCFILE(&ASRC/&SRCF) SRCMBR(USRQCLR_P) REPLACE(*YES)
STRQMQRY QMQRY(QTEMP/USRQCLR_P) SETVAR(('ALIB' &ALIB) ('EXTNAME' ('''' !< &ALIB !<-
'/USRQSQLSRV(SQL_USRQClear)''')))
DLTQMQRY QMQRY(QTEMP/USRQCLR_P)
MONMSG MSGID(CPF2105)
因此,我们有机会使用从 CL 程序参数传递给 SQL 表达式的参数。