MariaDBINSERT IGNORE... SELECT
语法在 https://mariadb.com/kb/en/insert/处定义。
我还依赖于以下假设:在这种情况下,每个INSERT
都将按照SELECT
子句结果集的顺序执行。
测试用例:
DROP TEMPORARY TABLE IF EXISTS index_and_color;
CREATE TEMPORARY TABLE index_and_color (`index` INT PRIMARY KEY, color TEXT);
INSERT IGNORE INTO index_and_color SELECT 5, "Red" UNION ALL SELECT 5, "Blue";
SELECT * FROM index_and_color;
直观地,我看到SELECT
子句结果集中的"第一"行有(5, "Red")
,然后"第二"行被忽略,包含与"Blue"相同的键。
据我所知,这是未定义的行为,因为实现相同文档的另一台服务器可以按不同的顺序处理行。
我在这里的使用确实依赖于未定义的行为吗?
什么是"未定义的行为"是UNION ALL
查询返回的行的顺序。如果您想要稳定的结果,请使用ORDER BY
子句:
INSERT IGNORE INTO index_and_color (`index`, color)
SELECT 5 `index`, 'Red' color UNION ALL SELECT 5, 'Blue' ORDER BY color;
SQL 语句SELECT * FROM index_and_color
应该完全按照您的要求给出:给定表中的所有数据行。
如果希望结果集按特定顺序传递,则需要添加ORDER BY
子句,否则可能会按索引排序,或者基于优化程序期望以最快速度生成数据的任何算法进行排序。
例如::
CREATE TABLE t1 (a int, b int, index(a));
INSERT INTO t1 VALUES (2,1),(1,2);
/* Here we get the order from last insert statement */
SELECT a,b FROM t1;
MariaDB [test]> select a,b from t1;
+------+------+
| a | b |
+------+------+
| 2 | 1 |
| 1 | 2 |
+------+------+
/* Here we get the another order since the optimizer will deliver results from index */
SELECT a FROM t1;
+------+
| a |
+------+
| 1 |
| 2 |
+------+