2010-03-22 2 views
3

단일 트랜잭션 내에서 두 테이블을 업데이트해야합니다. 위의 쿼리는 다음 삽입을 발생하면 내가 두 번째 테이블에 다음 문을 실행해야동일한 MySQL 트랜잭션에서 종속 테이블을 업데이트하는 방법은 무엇입니까?

1. INSERT INTO t1 (col1, col2) 
    VALUES (val1, val2) 
    ON DUPLICATE KEY 
     UPDATE col2 = val2; 

: 개별 쿼리는 다음과 같이 보일, 그렇지 않으면

2. INSERT INTO t2 (col1, col2) 
    VALUES (val1, val2) 
    ON DUPLICATE KEY 
     UPDATE col2 = col2 + val2; 

3. UPDATE t2 
     SET col2 = col2 - old_val2 + val2 
    WHERE col1 = val1; 
    -- old_val2 is the value of 
     t1.col2 before it was updated 

지금은 명령문 1이 t1에 삽입 또는 갱신을 일으킬 것인지 판별하기 위해 먼저 t1에 SELECT를 실행합니다. 그런 다음 트랜잭션 내에서 1과 2와 3 중 하나를 실행합니다. 하나의 거래 내에서이 모든 것을 수행 할 수있는 방법은 무엇입니까?

UPDATE t2, t1 
    set t2.col2 = t2.col2 - t1.col2 
WHERE t1.col1 = t2.col2 
    and t1.col1 = val1; 

INSERT INTO t1 (col1, col2) 
VALUES (val1, val2) 
ON DUPLICATE KEY 
    UPDATE col2 = val2; 

INSERT INTO t2, t1 (t2.col1, t2.col2) 
VALUES (t1.col1, t1.col2) 
ON DUPLICATE KEY 
    UPDATE t2.col2 = t2.col2 + t1.col2 
WHERE t1.col1 = t2.col2 
    and t1.col1 = val1; 

불행하게도, 5.0에서 DUPLICATE KEY UPDATE ON ... 더 멀티 테이블 INSERT가 없습니다 :

내가 생각 된 접근 방식은 다음과 같다. 내가 뭘 할 수 있을까?

답변

0

좋아, 나는이 알아 낸 내가 좋아하는 방식으로 이루어있어 :

세 번째 쿼리는 같은 T1에서 값을 참조하기 위해 다시 작성 될 수
UPDATE t2, t1 
    SET t2.col2 = t2.col2 - t1.col2 
WHERE t1.col1 = t2.col2 
    AND t1.col1 = val1; 

INSERT INTO t1 (col1, col2) VALUES (val1, val2) 
ON DUPLICATE KEY UPDATE 
    col2 = val2; 

INSERT INTO t2 (col1, col2) VALUES (val1, val2) 
ON DUPLICATE KEY UPDATE 
    col2 = col2 + VALUES(col2); 

:

INSERT INTO t2 (col1, col2) 
    SELECT col1, col2 FROM t1 WHERE col1 = val1 
ON DUPLICATE KEY UPDATE 
    t2.col2 = t2.col2 + VALUES(col2); 
1

INSERT 또는 UPDATE을 실행하면 클라이언트가 변경된 행 수를 반입 할 수 있습니다. 이렇게하는 방법은 클라이언트에 따라 다르지만, 여러 프로그래밍 언어의 경우이 번호는 성공한 경우 INSERT에 의해 반환됩니다.

INSERT...ON DUPLICATE KEY UPDATE을 실행하면이 숫자를 가져올 수도 있지만 정확히 예상 한 것은 아닙니다. 단일 행을 삽입/갱신하는 경우 변경된 행이 하나만 있더라도 INSERT의 경우 변경된 행 수와 UPDATE의 경우 2가 수신됩니다. 이 번호를 사용하여 다음에 실행할 쿼리를 클라이언트 측에서 결정할 수 있습니다.

하나의 트랜잭션만큼 좋지는 않지만 최소한 하나를 제거하십시오. SELECT.

+0

글쎄, 어쨌든 # 3에서 old_val2를 얻으려면 SELECT를해야합니다. –

관련 문제