有没有办法在MySQL服务器上批量执行INSERT OR UPDATE
之类的查询?
INSERT IGNORE ...
不起作用,因为如果该字段已经存在,它将简单地忽略它而不插入任何内容。
REPLACE ...
无法使用,因为如果该字段已经存在,它将首先DELETE
,然后再INSERT
,而不是更新它。
INSERT ... ON DUPLICATE KEY UPDATE
可以使用,但不能批量使用。
所以我想知道是否有像INSERT ... ON DUPLICATE KEY UPDATE
这样的命令可以批量发布(同时多行)。
答案 0 :(得分:68)
你可以使用INSERT ... ON DUPLICATE KEY UPDATE插入/更新多行。 documentation有以下示例:
INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
或者我误解了你的问题?
答案 1 :(得分:18)
执行此操作的一种可能方法是创建临时表,将数据插入到该表中,然后使用连接执行1查询以插入不存在的记录,然后更新到存在的字段。基础知识就是这样的。
CREATE TABLE MyTable_Temp LIKE MyTable
LOAD DATA INFILE..... INTO MyTable_Temp
UPDATE MyTable INNER JOIN
MyTable_Temp
ON MyTable.ID=MyTable_Temp.ID
SET MyTable.Col1=MyTable_Temp.Col1, MyTable.Col2=MyTable_Temp.Col2.....
INSERT INTO MyTable(ID,Col1,Col2,...)
SELECT ID,Col1,Col2,...
FROM MyTable_Temp
LEFT JOIN MyTable
ON MyTable_Temp.ID = MyTable.ID
WHERE myTable.ID IS NULL
DROP TABLE MyTable_Temp
语法可能不准确,但这应该为您提供基础知识。此外,我知道它不漂亮,但它完成了工作。
<强>更新强>
我交换了插入和更新的顺序,因为首先执行insert会导致在调用更新时更新所有插入的行。如果首先更新,则仅更新现有记录。这应该对服务器的工作少一点,尽管结果应该是相同的。
答案 2 :(得分:2)
虽然这个问题已经得到了正确回答(MySQL确实通过ON DUPLICATE UPDATE使用预期的多值集语法来支持这个问题),但我想通过提供任何MySQL运行的演示来扩展它:< / p>
CREATE SCHEMA IF NOT EXISTS `test`;
DROP TABLE IF EXISTS test.new_table;
CREATE TABLE test.new_table (`Key` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`Key`)) ENGINE=InnoDB AUTO_INCREMENT=106 DEFAULT CHARSET=utf8;
SELECT * FROM test.new_table;
INSERT INTO test.new_table VALUES (1),(2),(3),(4),(5) ON DUPLICATE KEY UPDATE `Key`=`Key`+100;
SELECT * FROM test.new_table;
INSERT INTO test.new_table VALUES (1),(2),(3),(4),(5) ON DUPLICATE KEY UPDATE `Key`=`Key`+100;
SELECT * FROM test.new_table;
输出如下:
Empty set (0.00 sec)
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
+-----+
| Key |
+-----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+-----+
5 rows in set (0.00 sec)
Query OK, 10 rows affected (0.00 sec)
Records: 5 Duplicates: 5 Warnings: 0
+-----+
| Key |
+-----+
| 101 |
| 102 |
| 103 |
| 104 |
| 105 |
+-----+
5 rows in set (0.00 sec)
答案 3 :(得分:0)
尝试添加执行飞行前检查的插入触发器,并取消重复键上的插入(在更新现有行之后)。
不确定它是否适合批量插入,更不用说加载数据了,但这是我能想到的最好的。 : - )
答案 4 :(得分:0)
如果您使用的是Oracle或Microsoft SQL,则可以使用MERGE
。但是,MySQL与该语句没有直接关联。您提到的是单行解决方案,但正如您所指出的那样,它不会很好地进行批量处理。这是一篇关于Oracle和MySQL之间差异的博客文章,以及Oracle如何在MySQL中使用MERGE
做的事情:
http://blog.mclaughlinsoftware.com/2009/05/25/mysql-merge-gone-awry/
这不是一个漂亮的解决方案,它可能不是你想要的完整解决方案,但我相信这是最好的解决方案。