我在executeQueries.ec文件中有这段代码
sprintf(sqlQuery,
"select distinct e.emp_id, e.join_date \
from employees e
where e.emp_id in (?) and e.dob <= '%s')");
$prepare empDataStmt from $sqlQuery;
if (sqlca.sqlcode)
{
fprintf(stderr, "Error %d in prepare empDataStmt%s\n",
sqlca.sqlcode, sqlQuery);
return 0;
}
$declare empDataCursor cursor for incptDatesStmt;
if (pcs_sql_check("Error in declaring empDataCursor Stmt"))
{
return 1;
}
$open empDataCursor using $empIds_,dob_ ;
当我dbx代码并打印empIds_
时,我在控制台上得到了这个:
""04-Emp1","W2-Emp2""
这意味着empIds_的内容为"04-Emp1","W2-Emp2"
(包括引号)。
问题是empIds
的数量可以是1到100或500。
例如,它甚至可以是:
"04-Emp1","W2-Emp2","04-Emp4","W2-Emp3","0A-Emp1","E2-Emp7"
因此我无法使用我的代码。任何人都可以帮我用“?”编写这段代码对于可以处理任意数量的empIds
的参数化查询。请注意,empIds_的内容将始终嵌入双引号。我不知道这是好事还是坏事,但我无法阻止它。
答案 0 :(得分:0)
您向我们展示的内容存在一些语法问题:
sprintf(sqlQuery,
"select distinct e.emp_id, e.join_date \
from employees e
where e.emp_id in (?) and e.dob <= '%s')");
那不会编译;在employees e
之后你需要第二个反斜杠。我强烈建议在字符串中避免使用反斜杠换行符;改为使用字符串连接。
sprintf(sqlQuery, "select distinct e.emp_id, e.join_date from employees e "
"where e.emp_id in (?) and e.dob <= '%s')");
请注意,字符串的两个部分之间只有空格(注释也会计为空格); C编译器将这些字符串连接成一个字符串。
现在,sprintf()
调用在C源代码级别在语法上是正确的;它仍然在语义上不正确,因为它包含%s
,并且您没有提供要复制的字符串。您可能应该使用占位符?
作为日期,因为您将其作为第二个参数传递给$open
语句(但实际上并没有占位符)。
然后您可以通过编写以下内容来避免显式的准备操作:
$ DECLARE empDataCursor FOR
SELECT DISTINCT e.emp_id, e.join_date
FROM employees e
WHERE e.emp_id IN ($empIds_) AND e.dob <= $dob_;
然而,不幸的是,这对你不起作用。您的问题的关键是您正在尝试将字符串作为IN子句的值列表传递。它根本不起作用。如果您有一个值,则需要一个占位符(?
);如果你有两个值,你需要两个占位符,等等。
因此,我们最终回到完整的预备语句并将empIds替换为字符串:
int reqlen;
reqlen = snprintf(sqlQuery, sizeof(sqlQuery), "SELECT DISTINCT e.emp_id, e.join_date"
" FROM employees e WHERE e.emp_id IN (%s) AND e.dob <= '%s'",
empIds_, dob_);
if (reqlen >= sizeof(sqlQuery))
...truncated SQL...larger sqlQuery needed...
$ PREPARE empDataStmt FROM $sqlQuery;
...SQL error check...
$ DECLARE empDataCursor FOR empDataStmt;
...SQL error check...
$ OPEN empDataCursor; /* No USING clause! */
...SQL error check...
...code as before...