2012-08-13 125 views
5

我必须使用IN运算符从数据库中选择一些行。我想用准备好的陈述来做。这是我的代码:MySQLi准备语句与IN运算符

<?php 
$lastnames = array('braun', 'piorkowski', 'mason', 'nash'); 
$in_statement = '"' . implode('", "', $lastnames) . '"'; //"braun", "piorkowski", "mason", "nash" 

$data_res = $_DB->prepare('SELECT `id`, `name`, `age` FROM `users` WHERE `lastname` IN (?)'); 
$data_res->bind_param('s', $in_statement); 
$data_res->execute(); 
$result = $data_res->get_result(); 
while ($data = $result->fetch_array(MYSQLI_ASSOC)) { 
    ... 
} 
?> 

但是,虽然所有的数据都存在于数据库中,但什么都不返回。

还有一个:如果我直接通过$in_statement查询并执行它,数据将被返回。所以问题出现在准备上。

我一直在谷歌寻找这个问题,但它并不成功。我的代码有什么问题?
感谢您的帮助!

+3

你不能在你的IN子句中使用单个参数。它需要是: '在哪里姓氏在(?,?,?,?)' – andrewsi 2012-08-13 17:01:58

+1

好吧,非常感谢!)它似乎有点麻烦。 – kpotehin 2012-08-13 17:04:28

回答

4

我最近为我的问题找到了解决方案。也许这不是最好的办法,但它很好!证明我错了:)

<?php 
$lastnames = array('braun', 'piorkowski', 'mason', 'nash'); 
$arParams = array(); 

foreach($lastnames as $key => $value) //recreate an array with parameters explicitly passing every parameter by reference 
    $arParams[] = &$lastnames[$key]; 

$count_params = count($arParams); 

$int = str_repeat('i',$count_params); //add type for each variable (i,d,s,b); you can also determine type of the variable automatically (is_int, is_float, is_string) in loop, but i don't need it 
array_unshift($arParams,$int); 

$q = array_fill(0,$count_params,'?'); //form string of question marks for statement 
$params = implode(',',$q); 

$data_res = $_DB->prepare('SELECT `id`, `name`, `age` FROM `users` WHERE `lastname` IN ('.$params.')'); 
call_user_func_array(array($data_res, 'bind_param'), $arParams); 
$data_res->execute(); 
$result = $data_res->get_result(); 
while ($data = $result->fetch_array(MYSQLI_ASSOC)) { 
    ... 
} 

$result->free(); 
$data_res->close(); 
?> 
2

准备语句是为了避免究竟你试图让它做:)

为了得到这个工作,你必须申请这一步是什么:

$escaped_lastnames = join(',', array_map(array($_DB, 'real_escape_string'), $lastnames)); 

它正确的琴弦映射为每个$lastnames项目上的数据库转义函数。完成后,将该值直接插入查询中,即不使用绑定参数。

+0

谢谢,杰克,但我找到了通过准备好的语句来做这个查询的方法。我使用call_user_func_array(数组($ data_res,'bind_param'),$ arParams);而不是常规的bind_param。 $ arParams完全包含变量类型和这些变量) – kpotehin 2012-08-15 10:50:34

+0

刚刚发布我的代码作为答案) – kpotehin 2012-08-15 11:13:18

+2

@ kpotehin当然,如果你真的必须(ab)使用准备好的语句,你当然可以:)亲自我看不到好处,除非它必须在一个php执行中运行多次 – 2012-08-15 11:38:29