SimBioT19
@SimBioT19
{{ user.about }}

Как сделать PDO + IN?

Как сделать запрос вида "UPDATE WHERE `id` IN ($sql)"
Нашёл кое-что, stackoverflow.com/questions/8991688/pdo-in-array-s...
но не ясно с bind`ом
Покажите пример!
У меня данный код не работает:
$query = $DB->prepare("UPDATE `Ttopic` SET `main`=:main, `main_id`=:theme,`type`='".$f['type']."' WHERE `id` IN ($q) limit 10");

$query->bindParam(':main', $main);
$query->bindParam(':theme', $theme);
if($query->execute($Ar)) echo 'ok';

По-моему с execute вообще неправильно
  • Вопрос задан
  • 7616 просмотров
Решения вопроса 1
orlov0562
@orlov0562 Куратор тега PHP
I'm cool!
Самый простой способ, взять ключи массива и по ним потом "прибиндить" данные, что-то типа:
$inValues = [1, 2, 3, 4];
	$inKeys = array_map(function($key){return ':var_'.$key;}, array_keys($inValues));
	
	$sql = 'SELECT * FROM `table` WHERE `field` IN ('.implode(',', $inKeys).')';
	
	echo $sql;
	
	$db = new PDO(...);
	$stmt = $db->prepare($sql);
	
	foreach($inValues as $key=>$val) {
		$stmt->bindParam(':var_'.$key, $val);
	}


с execute аналогично:

<?php

	$inValues = [1,2,3,4];
	
	$preparedInValues = array_combine(
		array_map(function($key) {
		   return ':var_'.$key;
		}, array_keys($inValues)),
		array_values($inValues)
	);
			
	$sql = 'SELECT * FROM `table` WHERE `field` IN ('.implode(',', array_keys($preparedInValues)).')';

	echo $sql;

	$db = new PDO(...);
	$stmt = $db->prepare($sql);
	$stmt->execute($preparedInValues);
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@heartdevil
плыву как воздушный шарик
Привет.

Вот вырезка

/* Execute a prepared statement using an array of values for an IN clause */
$params = array(1, 21, 63, 171);
/* Create a string for the parameter placeholders filled to the number of params */
$place_holders = implode(',', array_fill(0, count($params), '?'));

/*
    This prepares the statement with enough unnamed placeholders for every value
    in our $params array. The values of the $params array are then bound to the
    placeholders in the prepared statement when the statement is executed.
    This is not the same thing as using PDOStatement::bindParam() since this
    requires a reference to the variable. PDOStatement::execute() only binds
    by value instead.
*/
$sth = $dbh->prepare("SELECT id, name FROM contacts WHERE id IN ($place_holders)");
$sth->execute($params);


То есть, по сути, тебе можно вручную вот такую шнягу сделать
'WHERE id in (?,?,?,?,?,?,?)'

и собачить типизированные параметры

->bindParam(1, $id, PDO::PARAM_INT);
->bindParam(2, $id, PDO::PARAM_INT);
...

Но это за тебя сделает

вот эта штука

$place_holders = implode(',', array_fill(0, count($params), '?'));

насколько я понял.

тадам
Ответ написан
Комментировать
kimono
@kimono
Web developer
Честно, не проверял, но по вашей логике примерно следующее:
$values = [1, 2, 3];
$in_query = implode(',', array_fill(0, count($values), '?'));
$query = $DB->prepare(sprintf("UPDATE `Ttopic` SET `main`= ?, `main_id`= ?, `type`='".$f['type']."' WHERE `id` IN (%s) LIMIT 10", $in_query));
if($query->execute(array_merge([$main, $theme], $values)) echo 'ok';

Ну и конечно же `type`='".$f['type']."' в запросе это зло.
Ответ написан
Я для данной цели написал класс, который работает следующим образом
$stmt = false;//Требуется объявить так как передаётся в метод execute по ссылке
$params = array("ids"=>array(1,4,7));
$sql = "SELECT * FROM `users` WHERE `id` IN (:ids)";
nikolaevevgePDOIn::execute($pdo,$sql,$params,$stmt);

Сам код класса выложен тут: https://blog.ivru.net/?id=270
P.S. в моём случаи для формирования отчёта требовалось выполнить сразу ряд запросов в которых предполагалась передача массива значений в конструкцию IN(и даже нескольких массивов в несколько конструкций IN), поэтому применение данного класса вполне оправдано.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽
26 апр. 2024, в 07:47
2000 руб./за проект
26 апр. 2024, в 06:46
1000 руб./в час
26 апр. 2024, в 05:31
1000 руб./за проект