简体   繁体   English

如何在参数化SQL查询中将字符串数组或字符串向量传递给IN子句?

[英]How to pass an array of strings or a string vector to an IN clause in a parameterized SQL query?

I have this code in my executeQueries.ec file 我的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_ ;

When I dbx the code and print empIds_ , I get this on console: 当我dbx代码并打印empIds_ ,我在控制台上得到了这个:

""04-Emp1","W2-Emp2""

Which means content of empIds_ is "04-Emp1","W2-Emp2" (quotes included). 这意味着empIds_的内容为"04-Emp1","W2-Emp2" (包括引号)。 The question is that the number of empIds can be anything from 1 to 100 or 500. For example it can even be: 问题是empIds的数量可以是1到100或500之间的任何值。例如,它甚至可以是:

"04-Emp1","W2-Emp2","04-Emp4","W2-Emp3","0A-Emp1","E2-Emp7"

Because of this I can not get my code to work. 因此,我无法使我的代码正常工作。 Can anybody help me to write this code with using "?" 有人可以帮助我使用“?”编写此代码吗? for parametrized query that can handle any number of empIds . 用于可以处理任意数量empIds参数化查询。 Please note that the content of empIds_ will always have double-quotes embedded in them. 请注意,empIds_的内容将始终嵌入双引号。 I do not know whether this is a good thing or bad but I cannot do anything to prevent it. 我不知道这是好事还是坏事,但我无能为力。

A Minor Diversion 次要转移

You have some syntactic problems in what you show us: 您在向我们展示的内容中有一些句法问题:

sprintf(sqlQuery,
"select distinct e.emp_id, e.join_date \
from employees e
where e.emp_id in (?) and e.dob <= '%s')");

That won't compile; 那不会编译; you'd need a second backslash after employees e . 您需要在employees e之后再加一个反斜杠。 I strong recommend avoiding backslash-newline in strings; 我强烈建议避免在字符串中使用反斜杠换行符; use string concatenation instead. 请改用字符串串联。

sprintf(sqlQuery, "select distinct e.emp_id, e.join_date from employees e "
                  "where e.emp_id in (?) and e.dob <= '%s')");

Note that there is just white space (comments would count as white space too) between the two parts of the string; 注意,字符串的两个部分之间只有空格(注释也算作空格)。 the C compiler concatenates such strings into a single string. C编译器将此类字符串连接为单个字符串。

Now the sprintf() call is syntactically correct at the C source level; 现在,在C源代码级别上, sprintf()调用在语法上是正确的; it is still semantically incorrect because it contains %s and you've not provided a string for it to copy. 它在语义上仍然不正确,因为它包含%s并且您尚未提供要复制的字符串。 You should presumably be using a placeholder ? 您应该使用占位符? for the date since you pass it to the $open statement as a second parameter (but there isn't actually a placeholder for it). 日期,因为您将其作为第二个参数传递给$open语句(但实际上没有占位符)。

You would then be able to avoid an explicit prepare operation by writing: 然后,您可以通过编写以下代码来避免显式的准备操作:

$ DECLARE empDataCursor FOR
    SELECT DISTINCT e.emp_id, e.join_date
      FROM employees e 
     WHERE e.emp_id IN ($empIds_) AND e.dob <= $dob_;

The Crux 症结

However, this isn't going to work for you, unfortunately. 但是,不幸的是,这对您不起作用。 The crux of your problem is you are trying to pass a string as a list of values for the IN clause. 问题的症结在于您试图将字符串作为IN子句的值列表传递。 It simply doesn't work like that. 它根本不能那样工作。 If you have one value, you need one placeholder ( ? ); 如果有一个值,则需要一个占位符( ? ); if you have two values, you need two placeholders, etc. 如果您有两个值,则需要两个占位符,依此类推。

So, we end up going back to a full prepared statement and substitute the empIds into the string: 因此,我们最后回到完整的准备好的语句,并将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...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM