2013-10-13 4 views
0

я хочу использовать транзакции с этим запросомУдалить из с переменным числом аргументов

DELETE FROM tbl WHERE id IN(?, ?, ?) 

Но число идентификаторов является переменной. Иногда у меня есть 2, иногда 5 и т. Д.

Могу ли я переписать его по-другому, поэтому он принимает один аргумент ?, который содержит все ID?

Код:

$pdo->beginTransaction(); 
$st = $pdo->prepare('DELETE FROM tbl WHERE id IN(?, ?, ?)'); 

foreach(...){ 

    $st->execute(array($id1, $id2, $id3)); 
    // but here I may have only 2 IDs to pass, or 5 etc. 
} 

$pdo->commit(); 

ответ

2

Вы можете использовать что-то вроде этого:

$questionmarks = str_repeat("?,", count($_POST['foos'])-1) . "?";  
$query = "DELETE from `employee_customeraccount` WHERE `id` IN ($questionmarks)"; 
$st = $db->prepare($query); 
+0

спасибо, но я не думаю, что вы понимаете. Я только хочу подготовить запрос один раз, поэтому он не может измениться ... – Alex

+0

@Alex Вы не можете использовать тот же подготовленный оператор для разных номеров идентификаторов. –

+0

@Alex +1 Вам нужно только подготовить его один раз. Затем просто привяжите и выполните для каждого элемента, который у вас есть. Поместите все исполнения внутри транзакции, и вы получите почти оптимальную производительность для любой СУБД. –

1

Говоря о "проблеме XY" вы спросили,

Могу ли я переписать его по-разному, так это принимает сингл? аргумент, содержащий все идентификаторы?

No.

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

Но если говорить о проблеме реального вы сталкиваетесь,

Там, очевидно, может быть решение или два. Хотя, как и все XY-askers, вы опускаете самые важные детали, мы можем только догадываться. Скажем, вы можете сохранить все идентификаторы, а затем удалить все из них сразу после цикла, но до фиксации.

Или просто подготовьте свои удаления каждый раз. Не ахти какое дело.

1

Используйте фиксированное количество параметров, например 10 в DELETE FROM tbl WHERE id IN (?,?,?,?,?, ?,?,?,?,?). Подготовьте этот запрос и выполнить его несколько раз порциями по 10 параметров:

for ($offset = 0; $offset < count($yourIdArray); $offset += 10) { 
    $params = array_slice($yourIdArray, $offset, 10); 
    if (count($params) < 10) 
     $params = array_pad($params, 10, $params[0]); 
    $st->execute(...); 
} 

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

(Примечание: У меня нет PHP доступны и я не РНР парень Так что берите выше, как псевдо-код.).

Я не уверен, если подход отрывов параметров в операторах/запросов имеет смысл с Sqlite/PHP, который я бы не ожидал иметь кеш запросов/операторов или высокую стоимость предварительного запроса/утверждения. Я сам использовал этот подход в базах данных Oracle, прежде всего, чтобы избежать «загрязнения кэша запросов/операторов», которое возникло бы из-за наличия запросов/операторов с различным количеством параметров.

+0

Какой кеш запросов для запроса DML вы говорите? –

+0

Sqlite даже не выиграет от этого подхода, даже если у него был кеш запросов, поскольку он не является «запросом». Я отредактирую ответ. Как и в стороне, драйвер JDBC Oracle имеет кэш-память оператора, что, вероятно, неверно для Sqlite/PHP. См. Http://stackoverflow.com/questions/3772038/does-the-compiled-prepared-statement-in-the-database-driver-still-require-compil – halfbit

Смежные вопросы