単一の SQL クエリで複数の更新を行うにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/39792

  •  09-06-2019
  •  | 
  •  

質問

次の形式の SQL クエリがあります。

UPDATE foo
SET flag=true
WHERE id=?

ID のリストを含む PHP 配列もあります。次のように、解析以外にこれを達成する最良の方法は何ですか...

foreach($list as $item){  
    $querycondition = $querycondition . " OR " . $item;  
}

...そしてその出力を使用して、 WHERE 句?

役に立ちましたか?

解決

これは同じことを達成しますが、おそらく速度はあまり向上しませんが、見た目は良くなります。

mysql_query("UPDATE foo SET flag=true WHERE id IN (".implode(', ',$list).")");

他のヒント

IN 句を使用できるはずです (データベースが IN 句をサポートしていると仮定します)。

UPDATE foo SET flag=true WHERE id in (1, 2, 3, 5, 6)

IN ステートメントを使用します。キー値のカンマ区切りのリストを指定します。を使用すると簡単にそれを行うことができます implode 関数。

UPDATE foo SET flag = true WHERE id IN (1, 2, 3, 4, 5, ...)

あるいは、条件を使用することもできます。

UPDATE foo SET flag = true WHERE flag = false

またはサブクエリ:

UPDATE foo SET flag = true WHERE id IN (SELECT id FROM foo WHERE .....)

join/implode を使用して、最終的に次のようになるカンマ区切りのリストを作成します。

UPDATE foo SET flag=true WHERE id IN (1,2,3,4)

foreach ループ以外にそれを行う方法を見たことがありません。

ただし、何らかの方法で $list をユーザーから取得した場合は、プリペアド ステートメントを使用し、一度に 1 行ずつ更新することに固執する必要があります (プリペアド ステートメントで複数の行を更新する方法がないと仮定して)。それ以外の場合は、SQL インジェクションの可能性が広がります。

case ステートメントを使用して更新することもできますが、クエリを自分で作成する必要があります。

UPDATE foo
SET flag=CASE ID WHEN 5 THEN true ELSE flag END  
    ,flag=CASE ID WHEN 6 THEN false ELSE flag END 
WHERE id in (5,6)  

where は省略できますが、テーブル全体を更新する手間が省けます。

VB.NET コード:dim delimitedIdList as string = arrayToString(listOfIds)

dim SQL as string = " UPDATE foo SET flag=true WHERE id in (" + delimitedIdList + ")"

runSql(SQL)

項目数の上限がわかっている場合は、他の人が提案しているように、「IN」句を使用します。

UPDATE foo SET flag=true WHERE id in (1, 2, 3, 5, 6)

ただし、データベースによっては、句内の要素の数に制限がある場合があるという警告が 1 つあります。たとえば、oracle 7 または 8 (?) では、以前は 256 項目の制限がありました (これは、後のバージョンでは大幅に増加しました)
リストを反復処理する場合は、更新の 1 つが失敗した場合にロールバックできるようにトランザクションを使用します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top