是否指定插入忽略..选择是否按顺序执行?



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 |
+------+

最新更新