PDO IN () Оператор массива И заполнитель - PullRequest
13 голосов
/ 24 января 2012

Я нашел этот код в SO, который отлично подходит для совместного использования PDO и оператора IN ().

$values = explode(',', $values) ; # 1,4,7

$placeholders = rtrim(str_repeat('?, ', count($values)), ', ') ;
$query = "SELECT * FROM table WHERE id IN ($placeholders)";

$stm = $db->prepare($query) ;
$stm->execute($values) ;

Однако, как я могу смешать другое дополнение к запросу, чтобы запрос выглядел какэто:

$query = "SELECT * FROM table WHERE id IN ($placeholders) AND product=?";
$stm = $db->prepare($query) ;
$stm->execute(array($values,$product)) ; //error happens when adding product placeholder

Я думал, что это будет работать, но я получаю:

Предупреждение: PDOStatement :: execute () [pdostatement.execute]: SQLSTATE [HY093]: Неверный номер параметра: количество связанных переменных не соответствует количеству токенов в строке 3 (строка $ stm)

Есть идеи, как заставить это вести себя так, как задумано?

ОБНОВЛЕНО выполнить в массив, все еще не работает ..

Ответы [ 5 ]

8 голосов
/ 24 января 2012

Решение

Это должно работать, если $values является массивом:

$query = "SELECT * FROM table WHERE id IN ($placeholders) AND product=?";
$stm->execute(array_merge($values, array($product)));

Объяснение

execute() ожидает, что будет предоставлен один параметр - в данном случае массив. Добавляя array_merge($values, array($product)), вы создаете один массив с добавлением $product в конце, поэтому запрос должен работать правильно.

Смотрите демонстрацию здесь: http://ideone.com/RcClX

5 голосов
/ 24 января 2012
$stm->execute($values,$product) ; //error happens when adding product placeholder

Проблема здесь в том, что execute нужен массив single .Вы не можете передавать несколько массивов, и, что еще хуже, вы не можете вкладывать массивы.

У нас уже есть очень хороший массив $values, поэтому давайте повторно используем его после , когда вы создадите заполнительстрока.

$values = explode(',', $values) ; # 1,4,7

$placeholders = rtrim(str_repeat('?, ', count($values)), ', ') ;
$query = "SELECT * FROM table WHERE id IN ($placeholders) AND product=?";

// New!
$values[] = $product;

$stm = $db->prepare($query);
$stm->execute($values);
1 голос
/ 03 июня 2015

И другим решением может быть (если вам нравится: param_name = $ value, как у меня):

$params = array(
     ':product' =>  $product
);
$_in_params = array();
foreach ( $_in_values as $idx_in => $value_in)
{
    $_in_params[] = ':param_in_'.$idx_in;
    $params[':param_in_'.$idx_in] = $value_in;
}

$query .= "SELECT * FROM table WHERE id IN (".join(',',$_in_params).") AND product=:product";

Я не уверен, что это лучшее и наиболее оптимальное решение,но это немного более читабельно для человека :) И это может быть полезно, если у вас большой сложный запрос, и вы хотите отладить его

(мне любопытно, если у кого-то есть хороший аргумент, почемуНЕ делать таким образом)

0 голосов
/ 04 января 2017

Версия заполнителей, если она вам нужна

$values = [1, 4, 7, 8];
$placeholders =  preg_filter('/^/', ':prefix_', array_keys($values)));
$query = 'SELECT * FROM table WHERE id IN ( '. implode(', ', $placeholders) . ')';

$stmt = $db->prepare($query);

if (count($values) > 0) {
    foreach ($values as $key => $current_value) {
        $stmt->bindValue($placeholders[$key] , $current_value, PDO::PARAM_STR);
    }
}

$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
0 голосов
/ 24 января 2012

Вы забыли подготовить его ^ _ ^

$query = "SELECT * FROM table WHERE id IN ($placeholders) AND product=?";
$stm = $db->prepare($query) ;
$stm->execute($values,$product) ; //p00f

И помимо этого execute() должен иметь только один параметр

Таким образом, вышеприведенный не будет работать ВСЕ !

См. DOCs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...