Передайте несколько значений в переменной GET с использованием PDO [duplicate]

Используйте следующую строку. showDiv() будет вызывать функцию сразу после выполнения этой строки.

$('a.test').bind("click", showDiv);
66
задан Dominique 5 October 2015 в 11:11
поделиться

8 ответов

Это то же самое, что было задано в этом вопросе: Могу ли я привязать массив к условию IN ()?

Ответ заключался в том, что для переменной в [in], вам нужно будет построить запрос самостоятельно.

Однако вы можете использовать список, разделенный запятыми, с помощью find_in_set , хотя для больших наборов данных это будет иметь значительное влияние на производительность, поскольку каждое значение в таблице должно быть отлито для типа char.

Например:

select users.id
from users
join products
on products.user_id = users.id
where find_in_set(cast(products.id as char), :products)

Или, в качестве третьего варианта вы можете создать определенную пользователем функцию, которая разбивает список разделенных запятыми (см. http://www.slickdev.com/2008/09/15/mysql-query-real-values -из-разделитель разделенных-строковые идентификаторы / [/ д2]). Вероятно, это лучший вариант для трех, особенно если у вас много запросов, которые полагаются на предложения in(...).

33
ответ дан Community 16 August 2018 в 12:09
поделиться
  • 1
    Geez, PDO - такая аккуратная библиотека, но упускает некоторые из основных функций. Немного постыдно. – hd82 19 October 2009 в 03:07
  • 2
    Если у вас есть небольшой набор данных, вы можете уйти с find_in_set (я обновил ответ на примере), или вы можете попробовать пользовательскую функцию для разбора списка разделенных запятыми. (Извините, что продолжал добавлять идеи, ха-ха, после того, как я опубликовал ссылку на другой вопрос, подумал я, «есть способ сделать это ...») – James McNellis 19 October 2009 в 03:21
  • 3
    Спасибо за хедз-ап FIND_IN_SET. Действительно спас мой день. Но я обнаружил, что он работает без необходимости выполнять CAST, поэтому find_in_set (products.id,: products) достаточно. – Andy 2 May 2012 в 07:11
  • 4
    Очень полезный ответ. Можете ли вы добавить версию ответа на вопрос, с которым вы связались? Увидев, что он получил больше голосов и, скорее всего, появится в верхней части результатов поиска. – Blazemonger 3 October 2012 в 20:59
  • 5
    Я просто добавлю одно: когда вы привязываете param: products к строке, он НЕ МОЖЕТ ИМЕТЬ любые пробелы, например. 1,2,3,4 верен, но 1, 2, 3, 4 НЕ. – R Picheta 1 December 2016 в 18:12

Лучшая подготовленная инструкция, которую вы, вероятно, могли бы найти в подобной ситуации, похожа на следующее:

SELECT users.id
FROM users
JOIN products
ON products.user_id = users.id
WHERE products IN (?,?,?,?,?,?,?,?)

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

7
ответ дан Asaph 16 August 2018 в 12:09
поделиться
  • 1
    Логическое решение, когда вы знаете, сколько переменных нужно связывать, но оно становится немного беспорядочным, когда у вас есть неопределенное количество параметров. – hd82 19 October 2009 в 03:09
  • 2
    @ hd82: Ну, тогда вы должны умно объединить sprintf и подсчитать. – Boldewyn 19 January 2011 в 18:09

вам нужно предоставить такое же количество? s в IN как количество значений в вашем массиве $ values ​​

, это можно сделать легко, создав массив? s как

 $in = join(',', array_fill(0, count($values), '?'));

и использовать этот массив $ в вашем разделе IN

. Это будет динамически предоставлять вам индивидуальный массив из-за вашего измененного массива $ values ​​

5
ответ дан ashsam786 16 August 2018 в 12:09
поделиться

Вы можете сделать это очень легко. Если у вас есть массив значений для вашего оператора IN () EG:

$test = array(1,2,3);

Вы можете просто сделать

$test = array(1,2,3);
$values = count($test);
$criteria = sprintf("?%s", str_repeat(",?", ($values ? $values-1 : 0)));
//Returns ?,?,?
$sql = sprintf("DELETE FROM table where column NOT IN(%s)", $criteria);
//Returns DELETE FROM table where column NOT IN(?,?,?)
$pdo->sth = prepare($sql);
$pdo->sth->execute($test);
1
ответ дан fyrye 16 August 2018 в 12:09
поделиться
  • 1
    Это уже упоминалось в ответе Асафа выше и не работает, если вы используете именованные параметры, так как вы не можете их смешивать. – cincodenada 6 September 2013 в 21:51

Хороший способ справиться с этой ситуацией - использовать str_pad , чтобы поместить ? для каждого значения в запросе SQL. Затем вы можете передать массив значений (в вашем случае $values) в качестве аргумента для выполнения:

$sql = '
SELECT users.id
FROM users
JOIN products
ON products.user_id = users.id
WHERE products.id IN ('.str_pad('',count($values)*2-1,'?,').')
';

$sth = $dbh->prepare($sql);
$sth->execute($values);
$user_ids = $sth->fetchAll();

Таким образом, вы получаете больше преимуществ от использования подготовленных операторов, а не вставляете значения непосредственно в SQL.

PS. Результаты возвращают повторяющиеся идентификаторы пользователей, если продукты с указанными идентификаторами разделяют идентификаторы пользователей. Если вам нужны только уникальные идентификаторы пользователей, я предлагаю изменить первую строку запроса на SELECT DISTINCT users.id

27
ответ дан ghbarratt 16 August 2018 в 12:09
поделиться
  • 1
    человек, это гений! :-D – David John Welsh 26 November 2012 в 11:32
  • 2
    @Nalum: поскольку второй параметр str_pad - это длина «прокладки», который находится в символах. Поскольку для каждого значения требуется знак вопроса и запятая между ними, это работает count($values)*2-1. В противном случае вы можете использовать что-то вроде str_repeat('?,',count($values)-1).'?', если хотите. – ghbarratt 3 June 2013 в 09:54
  • 3
    Я предпочитаю использовать implode(',', array_fill(1,count($values),'?')), потому что меньше вероятность ошибок по отдельности, и вам не нужно обрабатывать последний элемент по-разному. – Bill Karwin 13 February 2014 в 21:35
  • 4
    вы также можете использовать str_repeat () для этого, это, вероятно, самый эффективный из перечисленных методов: rtrim( str_reapeat('?,', count($values)), ',') – ivanhoe 24 July 2014 в 07:47
  • 5
    @Dominique Вы неправильно читаете код. Он не ставит переменные непосредственно внутри запроса. Это действительно точка решения. Он помещает & quot; & quot; для каждой переменной, чтобы PDO мог подготовить фактическое утверждение. Да, нам нравятся гарантии PDO, и это решение представляет собой способ их использования. – ghbarratt 6 November 2015 в 18:17

Пожалуйста, попробуйте вот так:

WHERE products IN(REPLACE(:products, '\'', ''))

С уважением

-1
ответ дан Kopendrex 16 August 2018 в 12:09
поделиться
  • 1
    Этот вопрос задавали и отвечали 5 лет назад, и этот ответ не решает проблему. – OGHaza 27 June 2014 в 15:02

Если выражение основано на пользовательском вводе без привязки значений с помощью bindValue (), экспериментальный SQL не может быть отличным выбором. Но вы можете сделать это безопасным, проверив синтаксис ввода с REGEXP MySQL.

Например:

SELECT *
FROM table
WHERE id IN (3,156)
AND '3,156' REGEXP '^([[:digit:]]+,?)+$'
1
ответ дан Peter O. 16 August 2018 в 12:09
поделиться

Ниже приведен пример привязки неизвестного количества столбцов записи к значениям для вставки.

public function insert($table, array $data)
{
    $sql = "INSERT INTO $table (" . join(',', array_keys($data)) . ') VALUES ('
        . str_repeat('?,', count($data) - 1). '?)';

    if($sth = $this->db->prepare($sql))
    {
        $sth->execute(array_values($data));
        return $this->db->lastInsertId();
    }
}

$id = $db->insert('user', array('name' => 'Bob', 'email' => 'foo@example.com'));
0
ответ дан Xeoncross 16 August 2018 в 12:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: