这是ASE 15.7和ESQL / C.使用预准备语句更新CURSOR中的行:
EXEC SQL BEGIN DECLARE SECTION;
CS_IMAGE image[512];
EXEC SQL END DECLARE SECTION;
strcpy(image, "foo");
EXEC SQL PREPARE updt FROM "UPDATE image_test SET nettodaten = ? WHERE CURRENT OF hc_image_test";
EXEC SQL EXECUTE updt USING :image;
来自ASE的消息失败:
** SQLCODE=(-201)
** ASE Error
** Procedure *sq1625128094_1900377684ss* expects parameter
Invalid pointer param number 4, pointer value 0x(nil)
, which was not supplied.
这可能是什么原因?
更新1
我稍微修改了ESQL / C代码,看起来像这样:
strcpy(anweisung, "UPDATE image_test SET katkey = ?, nettodaten = ? WHERE CURRENT OF hc_image_test");
EXEC SQL PREPARE updt FROM :anweisung;
EXEC SQL EXECUTE updt USING :key, :blobfld;
EXEC SQL CLOSE hc_image_test;
错误保持与上面相同。但是,通过CPRE
查看生成的C代码可以看到一个有趣的细节:
/*
** SQL STATEMENT: 17
** EXEC SQL EXECUTE updt USING :key, :blobfld;
*/
{
_SQL_CT_HANDLES * _sql;
_sqlinitctx(&_sql, CS_CURRENT_VERSION, CS_TRUE, &sqlca, (long
*)NULL, (CS_CHAR *)NULL);
if (_sql != (_SQL_CT_HANDLES *) NULL)
{
_sql->stmtData.persistent = CS_FALSE;
_sql->stmttype = SQL_EXECUTE;
_sql->connName.lnlen = CS_UNUSED;
_sql->stmtName.fnlen = 4;
strcpy(_sql->stmtName.first_name, "updt");
if ((_sql->retcode = _sqlprolog(_sql)) == CS_SUCCEED)
{
_sql->retcode = ct_dynamic(_sql->conn.command,
CS_EXECUTE, "updt", 4, NULL, CS_UNUSED);
if (_sql->retcode == CS_SUCCEED)
{
_sql->dfmtCS_INT_TYPE.count = 0;
_sql->dfmtCS_INT_TYPE.status = CS_INPUTVALUE;
_sql->retcode = ct_param(_sql->conn.command,
&_sql->dfmtCS_INT_TYPE, &key, (CS_INT)
CS_UNUSED, (CS_SMALLINT) 0);
_sql->dfmtCS_INT_TYPE.status = 0;
}
_sql->retcode = ct_send(_sql->conn.command);
_sql->hastate = (_sql->retcode == CS_RET_HAFAILOVER);
_sql->retcode = _sqlResults(_sql);
_sql->retcode = _sqlepilog(_sql);
}
if (sqlca.sqlcode < 0)
{
error_handler();
}
正如上面所看到的,指向主变量CS_INT :key
的指针通过调用ct_param()
放入内部结构,但不是对主变量CS_IMAGE :blobfld
的任何引用。这就是为什么ASE抱怨缺少参数值,因为它在准备好的?
声明中看到两个问号UPDATE
。这在某种程度上看起来像是CPRE
编译器中的一个错误而不是ASE本身。
我通过我们的维护合同联系了SAP公司(发行号为390674/2018),一些工程师正在研究这个CPRE问题......
目前,我正在添加CPRE生成的C代码,在ct_send()调用之前,以下代码行将缺少的引用添加到IMAGE列:
/* additional code for host var :blobfld */
if (_sql->retcode == CS_SUCCEED)
{
_sql->dfmtCS_IMAGE_TYPE.count = 0;
_sql->dfmtCS_IMAGE_TYPE.maxlength = (CS_INT) 65535;
_sql->dfmtCS_IMAGE_TYPE.format = CS_FMT_UNUSED;
_sql->dfmtCS_IMAGE_TYPE.status = CS_INPUTVALUE;
_sql->retcode = ct_param(_sql->conn.command,
&_sql->dfmtCS_IMAGE_TYPE, blobfld, (CS_INT) ImageLengthField,
(CS_SMALLINT) 0);
_sql->dfmtCS_IMAGE_TYPE.status = 0;
}
/* end of additional code for host var :blobfld */
_sql->retcode = ct_send(_sql->conn.command);
...
一切正常。