2014-05-08 3 views
0

주어진 테이블의 여러 행을 한 번에 (또는 존재하지 않는 경우 삽입) 설정 및 사용자 ID 배열로 업데이트하려고합니다.하나의 쿼리에서 여러 행을 업데이트 (또는 삽입)

특정 계정의 특정 컴퓨터의 모든 사용자에 대해 settings 테이블에서 모든 행을 선택하는 방법에 대한 예입니다. 값을 삽입하거나 갱신해야하는 결과 세트입니다.

$stmt = $db->prepare("  
    SELECT settings.* 
    FROM 
     (SELECT account_id, computer_id 
      FROM computers 
      ORDER BY computer_id ASC LIMIT 0, ".$_SESSION['user']['licenses']." 
     ) as c 
     LEFT JOIN users 
      on users.computer_id = c.computer_id 
     LEFT JOIN accounts 
      on accounts.account_id = c.account_id 
     LEFT JOIN settings 
      on settings.user_id = users.user_id 
    WHERE accounts.account_id = ".$_SESSION['user']['account_id']." 
"); 

것은 내가 할 노력하고 무엇 : 나는/업데이트 배열에 나열된 만 사용자 ID에 대한 settings 테이블에 세 개의 열 (사용, 상태 및 USER_ID)를 삽입하려고 . 사용 및 상태 값은 모두 동일하지만 user_id는 각각 다릅니다.

$ 사용자 = 어레이 (12, 36, 43, 56, 76)

$ 결합 = 배열 ​​( 가 '활성화'=> 1 '상태'=> 2 'USER_ID'=> 어레이로부터 );

내 생각 프로세스가 올바른 경우 위에 나열된 내 문에서 가상 테이블을 만든 다음 중복 가상 업데이트를 사용하여 해당 가상 테이블의 결과에 삽입/업데이트 할 수 있습니까?

이것이 가능합니까? 그렇다면 예제, 팁 또는 올바른 방향을 가리 킵니까? 내가 일하는 방식은 주어진 배열에있는 각 사용자 ID에 대한 foreach 루프를 포함하므로 카운트에 따라 x 개의 쿼리가있게됩니다. 만약 내가 그걸 잘할 수있는 사람 한테 줄 수 있다면!

UPDATE :

좋아, 나는이 작동하지 않는 정의 된 값에 대한 시도이다 ... 지금은 완전히 혼란 스러워요 ... 그리고 나는 아직도 모든 user_id를 위해 그렇게 할 수있는 방법이 필요 내 배열. 내 전체 FROM 절을 새로운 참조로 '저장'할 필요가 없습니까?

$stmt = $db->prepare(" 
    INSERT INTO settings (user_id, enabled, status) 
    VALUES (:user_id, :enabled, :alert_user)  
    SELECT user_id, enabled, status 
    FROM 
     (SELECT account_id, computer_id 
      FROM computers 
      ORDER BY computer_id ASC LIMIT 0, ".$_SESSION['user']['licenses']." 
     ) as c 
     LEFT JOIN users 
      on users.computer_id = c.computer_id 
     LEFT JOIN accounts 
      on accounts.account_id = c.account_id 
     LEFT JOIN settings 
      on settings.user_id = users.user_id 
     WHERE accounts.account_id = ".$_SESSION['user']['account_id']." 
    ON DUPLICATE KEY UPDATE enabled = VALUES(enabled), status = VALUES(status) 
"); 

$binding = array(
    'enabled' => 1, 
    'alert_user' => 4, 
    'user_id' => 6 
    ); 

$stmt->execute($binding); 
+0

누구? 밤새도록 연구를 해보니 더 이상 불가능 해 보입니다. 설정 테이블의 값을 업데이트 할 수는 있지만 상황에 따라 테이블을 설정 테이블에 조인 할 방법이없는 것처럼 보입니다. 다른 테이블을 조인하는 것은 새로운 데이터를 실제로 업데이트하거나 삽입하기위한 적절한 권한을 보장하는 필수 요소입니다. – user756659

답변

1

네 생각은 맞습니다. ON DUPLICATE KEY UPDATE 절에

INSERT INTO settings (user_id, enabled, status) 
SELECT user_id, enabled, status 
FROM ... -- rest of your query here 
ON DUPLICATE KEY UPDATE enabled = VALUES(enabled), status = VALUES(status) 

VALUES(colname)가 dupliate이 없었다면 삽입되었을 값을 가져옵니다 : 그것은이 같은해야한다. 귀하의 의견에 따라 OK

는, 나는 이것이 당신이 원하는 것 같아요 :

INSERT INTO settings (user_id, enabled, status) 
SELECT :user_id, :enabled, :status 
FROM ... 
JOIN ... 
JOIN ... 
WHERE ... 
ON DUPLICATE KEY UPDATE enabled = VALUES(enabled), status = VALUES(status) 

수익을 모든 행에 가입하면이 삽입하거나 지정된 행을 업데이트합니다. 행을 찾지 못하면 삽입/업데이트가 수행되지 않습니다.

조인중인 테이블에 일치하는 항목이 없을 때 반환되는 것이 없도록하려면 왼쪽 조인이 아닌 내부 조인을 사용해야합니다.

+0

이 작업을 수행 할 수 없습니다 ...나는 여전히 틀린 일을해야만한다. – user756659

+0

'SELECT' 전에'VALUES (: user_id, : enabled, : alert_user)'를 제거하라. 이러한 변수를 사용하여 삽입 할 행을 찾으려면 SELECT 행의 WHERE 절에 있어야합니다. – Barmar

+0

INSERT에서 SELECT 된 데이터와 매개 변수를 어떻게 혼합 할 수 있는지에 대한 답변은 http://stackoverflow.com/questions/23535975/php-pdo-mysql-cant-insert-with-inner-join/23536105#23536105를 참조하십시오. – Barmar

관련 문제