단일 SQL 쿼리에서 여러 업데이트를 어떻게 수행합니까?
문제
다음 형식을 사용하는 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 절을 사용할 수 있어야 합니다(데이터베이스가 이를 지원한다고 가정).
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가 어떤 식으로든 사용자로부터 얻은 경우 준비된 문을 사용하고 한 번에 한 행만 업데이트해야 합니다(누군가가 준비된 문으로 여러 행을 업데이트할 수 있는 방법이 없다고 가정).그렇지 않으면 SQL 주입이 발생할 수 있습니다.
사례 설명으로 업데이트를 방해할 수 있지만 쿼리는 직접 작성해야 합니다.
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 코드:희미한 delimitedIdList as string = arrayToString(listOfIds)
문자열로 희미한 SQL = " 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)
하지만 한 가지 경고는 DB에 따라 절의 요소 수에 제한이 있을 수 있다는 것입니다.예를 들어 oracle 7 또는 8(?)은 256개 항목으로 제한되었습니다(이는 이후 버전에서 크게 늘어났습니다).
목록을 반복하는 경우 트랜잭션을 사용하면 업데이트 중 하나가 실패할 경우 롤백할 수 있습니다.