3

我需要在一个事务中更新两个表。单个查询如下所示:

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

现在我首先在 t1 上运行 SELECT,以确定语句 1 是否会在 t1 上导致插入或更新。然后我在事务中运行语句 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;

不幸的是,在 MySQL 5.0 中没有多表 INSERT... ON DUPLICATE KEY UPDATE。我还能做什么?

4

2 回答 2

1

如果您执行 anINSERT或 an UPDATE,您的客户端能够获取更改的行数。如何执行此操作取决于您的客户,但对于多种编程语言,INSERT如果成功,您将返回此数字。

如果你执行INSERT...ON DUPLICATE KEY UPDATE,你也可以获取这个数字,但它并不完全符合你的预期。如果您插入/更新单行,您将收到 1 作为更改的行数(在 an 的情况下)INSERT和 2 在 an 的情况下UPDATE,即使只有一行发生了更改。您可以使用此数字来决定客户端接下来要运行哪个查询。

不如单笔交易好,但至少你摆脱了一个SELECT.

于 2010-03-22T14:41:25.740 回答
0

好的,所以我已经弄清楚并以我喜欢的方式完成了:

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

第三个查询可以重写以引用来自 t1 的值,如下所示:

INSERT INTO t2 (col1, col2)
   SELECT col1, col2 FROM t1 WHERE col1 = val1
ON DUPLICATE KEY UPDATE
   t2.col2 = t2.col2 + VALUES(col2);
于 2010-03-25T08:44:53.497 回答