我正在尝试编写一个简单的 CL 程序来获取文件名参数并使用 COMMIT(*CHG) 和 DBGVIEW(*SOURCE) 运行文件中的 SQL。我收到 CPD018A:路径名称包含嵌入的空值:
Cause . . . . . : Path name /SQL/TRIGGERS/PCUSTOMERS_INSERT
???????????????????????????????????????????????????????????????????????.SQL
specified for SRCSTMF contains one or more embedded nulls (X'00'). Nulls are not allowed in a path name.
这是我的程序:
PGM PARM(&FILE)
DCL VAR(&FILE) TYPE(*CHAR) LEN(100)
RUNSQLSTM SRCSTMF('/SQL/' || %TRIM(&FILE) || '.SQL') +
DBGVIEW(*SOURCE)
ENDPGM
我调用该程序的方式如下:CALL CCSQL PARM('TRIGGERS/PCUSTOMERS_INSERT')
。
这可能只是解决真正问题的糟糕方法:我想在触发器中添加 SET OPTION
语句:
CREATE OR REPLACE TRIGGER QS36F.PCUSTOMERS_INSERT
INSTEAD OF INSERT ON QS36F.PCUSTOMERS
REFERENCING NEW AS N
FOR EACH ROW
MODE DB2SQL
SET OPTION DBGVIEW =*SOURCE -- this causes a failure when run through JDBC
BEGIN
...
我一直无法弄清楚如何让 SET OPTION 语句通过 JDBC,因此我每次都必须将语句复制到 iSeries Navigator 中。我认为我可以通过调用此 CL 程序的外部过程来改进此工作流程,以在调用流文件中的 SQL 之前处理预编译选项,但我无法使用我发送到过程的参数运行 CL(或者当我从命令行调用它)CALL MYLIB.CCSQL('TRIGGERS/PCUSTOMER_INSERT');
目前我距离最初的目标还很远...非常欢迎任何建议。如果这有帮助的话,我是一个 PHP/SQL 类型的人,试图在 iSeries 7.2 系统上实现它。
感谢您的阅读。
最佳答案
由于命令行解释器和文字值的特殊性,该调用不起作用。
- 参数始终通过引用传递,这意味着内存地址放置在堆栈上。
- 为字符串文字分配内存,就像它是 char(32) 一样;并用空格填充。除非文字较长,在这种情况下,内存将根据字符串的长度分配。
- 内存分配给数字参数,如 DEC(15,5)。
所以您会看到,正在分配 32 个字节,但您的程序正在查看 100 个字节。因此臭名昭著的“为什么我的 CL 程序参数中有垃圾”
三种解决方案
- 构建一个命令(*CMD 对象)前端,这将使命令行解释器能够准确知道您的参数有多长。
- 将参数更改为 char(32)
- 传递 101 个字节,第 101 个非空白
(像这样)
CALL CCSQL PARM('TRIGGERS/PCUSTOMERS_INSERT x')
关于ibm-midrange - CL : Path name contains embedded nulls (CPD018A),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41272541/