2010-03-22 8 views
3

J'ai besoin de mettre à jour deux tables dans une seule transaction. Les requêtes individuelles ressemblent à ceci:Comment mettre à jour une table dépendante dans la même transaction MySQL?

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

Si la requête ci-dessus provoque un insert alors je dois exécuter l'instruction suivante sur la deuxième table:

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

autrement,

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

En ce moment, je lance d'abord un SELECT sur t1, pour déterminer si l'instruction 1 provoquera une insertion ou une mise à jour sur t1. Ensuite, je cours l'instruction 1 et l'un ou l'autre de 2 et 3 dans une transaction. Quelles sont les façons dont je peux faire tout cela dans une même transaction?

L'approche que je pensais est la suivante:

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; 

Malheureusement, il n'y a pas INSERT multi-table ... Duplicate KEY UPDATE dans MySQL 5.0. Que pouvais-je faire d'autre?

Répondre

0

Ok, donc j'ai cet a compris et fait d'une manière que je l'aime:

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); 

La troisième requête peut être réécrite pour se référer à des valeurs de t1 comme tel:

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

Si vous exécutez un INSERT ou un UPDATE, votre client peut extraire le nombre de lignes modifiées. Comment faire cela dépend de votre client, mais pour plusieurs langages de programmation, ce numéro est retourné par votre INSERT s'il a réussi. Si vous exécutez INSERT...ON DUPLICATE KEY UPDATE, vous pouvez aussi aller chercher ce numéro, mais ce n'est pas exactement ce que vous attendez. Si vous insérez/mettez à jour une seule ligne, vous recevez 1 comme le nombre de lignes qui ont changé dans le cas d'un INSERT et 2 dans le cas d'un UPDATE, même si une seule ligne a été modifiée. Vous pouvez utiliser ce numéro pour décider du côté client de la requête à exécuter ensuite.

Pas aussi agréable qu'une seule transaction, mais au moins vous vous débarrassez d'un SELECT.

+0

Eh bien, je dois tout de même faire un SELECT pour obtenir old_val2 dans la déclaration # 3. –

Questions connexes