1

我的 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 代码和 printempIds_时,我在控制台上得到了这个:

""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_ 的内容将始终嵌入双引号。我不知道这是好事还是坏事,但我不能做任何事情来阻止它。

4

1 回答 1

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...
于 2012-05-04T19:49:43.553 回答