我需要在单个事务中更新两个表。各个查询看起来像这样:
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。我还能做什么?
答案 0 :(得分:1)
如果您执行INSERT
或UPDATE
,您的客户端可以获取更改的行数。如何执行此操作取决于您的客户端,但对于多种编程语言,如果成功,则INSERT
会返回此编号。
如果您执行INSERT...ON DUPLICATE KEY UPDATE
,您也可以获取此号码,但这并不完全符合您的预期。如果插入/更新单行,则在INSERT
的情况下,您将收到1作为更改的行数;如果只有UPDATE
,则收到2,即使只有一行发生了更改。您可以使用此数字来决定客户端下一个要运行的查询。
不如单个交易好,但至少你摆脱了一个SELECT
。
答案 1 :(得分: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);