2012-02-22 18 views
3

何百行も同時に更新できますか?複数の行を1つのクエリで更新する

同様:UPDATE table SET a = ? WHERE b = ? AND c = 1

が、多くの行の 。

?パラメータは、私が this answerを読んでいますが、CASEを使用して、私はそれを行うことができるとは思わない...


は今、私はこのような何かを持っている...

配列です。

foreach($values as $key => $value) 
    $res = $pdo->prepare('UPDATE table SET a = ? WHERE b = ? AND c = 1'); 
    $res->execute(array($value, $key)); 
} 
+0

を意味していますか? –

+0

CASEを使用できないのはなぜですか? – DarkAjax

+0

クエリは膨大なものになるので... – Alex

答えて

6

クエリを1回実行するには、CASEassemble the parameters programmaticallyを使用する必要があります。 SQLはバリデーショナルなプリペアドステートメントをサポートしておらず、simple valuesのみをパラメータ化できます。

また、一度に1つの行のデータしか取得せず、ループ内でクエリを実行するように文を定義します。繰り返し実行とは、準備された文がこのような場合にどのように使用されるように設計されているかです。

try { 
    $query = $db->prepare('UPDATE table SET a = ? WHERE b = ? AND c = 1'); 
    foreach ($as as $i => $a) { 
     $query->execute(array($a, $bs[$i])); 
    } 
} catch (PDOException $e) { 
    ... 
} 
+0

ケースステートメントを作成しても、SQLインジェクション用のプリペアドステートメントを利用することができますか、または「古い時代」の各入力をエスケープする必要がありますか? – JM4

+0

@ JM4:パラメータ化する必要があるものによって異なります。プリペアドステートメントは関数に類似しているが、値のみ(列名などではない)をパラメータ化することができる。それが必要なすべてのものであれば、準備された声明はうまくいくでしょう。しかし、サンプルコードに似たソリューションをお勧めします。全体的に単純です。関数とは異なり、プリペアドステートメントへの引数は一般的には再利用できませんので、別のパラメータを持たせて値を繰り返す必要がありますが、エラーが発生しやすくなります。 – outis

4

指定したリンクで説明されているようにCASEメソッドを使用しますが、必要な値で動的にクエリを構築してください。

これは、すでに行っているのと同じforループで構築されますが、繰り返しごとにデータベースにクエリするのではなく、1つのクエリで終了します。

+0

これは唯一の欠点です(それは私自身の推奨事項です)。これは、単一行のステートメントでそうでないように、準備されたステートメントで入力データをエスケープすることができないということです。 – JM4

2

もう一つの方法は、このような何か一時テーブルにあなたのキーと値のペア(すべて一度に)を挿入することです:あなたは、彼らがペアで

UPDATE table t 
SET t.a = (SELECT p.a FROM tmp p WHERE p.b = t.b) 
WHERE t.b IN (SELECT p.b FROM tmp p) AND t.c = 1 
関連する問題