【问题标题】:Mysql8 fail to upsert generated uuidMysql 8 无法 upsert 生成的 uuid
【发布时间】:2021-10-11 11:43:29
【问题描述】:

我有一个包含 2 列的 mysql8 表:ID(Int) AND UUID(Varchar36):

CREATE TABLE `upsert_test` (
  `ID` int unsigned DEFAULT NULL COMMENT 'id;',
  `UUID` varchar(36) DEFAULT NULL
) ENGINE=InnoDB;

我需要在没有唯一索引的情况下模仿upsert 的行为,最后我得到了以下 sql 命令,它适用于 mysql 5.7:

INSERT INTO upsert_test
SELECT 1 AS ID, UUID() AS "UUID"
FROM upsert_test
WHERE ID=1
HAVING COUNT(*)=0;

但是升级到mysql8.0后,只插入了一个空UUID,如流:

mysql> SELECT * FROM upsert_test;
+------+------+
| ID   | UUID |
+------+------+
|    1 | NULL |
+------+------+
1 row in set (0.00 sec)

如果我执行select 子命令,我会得到一个有效的 UUID(这个查询实际上是在插入任何数据之前执行的):

mysql> SELECT 1 AS ID, UUID() AS "UUID"
    -> FROM upsert_test
    -> WHERE ID=1
    -> HAVING COUNT(*)=0;
+----+--------------------------------------+
| ID | UUID                                 |
+----+--------------------------------------+
|  1 | a1fbea94-f6c4-11eb-903c-0242ac110002 |
+----+--------------------------------------+
1 row in set (0.00 sec)

而且它就是无法插入。 如果我忽略 HAVING 部分:

mysql> INSERT INTO upsert_test
    -> SELECT 2 AS ID, UUID() AS "UUID";
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM upsert_test;
+------+--------------------------------------+
| ID   | UUID                                 |
+------+--------------------------------------+
|    1 | NULL                                 |
|    2 | 033e03f7-f6c5-11eb-903c-0242ac110002 |
+------+--------------------------------------+
2 rows in set (0.00 sec)

我们可以看到插入了一个有效的 UUID。

我整个下午都在为这个问题苦苦挣扎,只是无法弄清楚问题是什么。

【问题讨论】:

  • 似乎您已经有一个列,所以HAVING COUNT(*)=0 将阻止插入。试试HAVING COUNT(*)=1
  • 我试过HAVING COUNT(*)=1,但我认为这不是问题所在。新行确实插入没有失败(因为执行插入命令之前表中没有数据),但是插入的UUID是NULL
  • WHERE ID=1 HAVING COUNT(*) = 0; 部分的预期用途是什么?
  • 我需要upsert数据(如果ID=1所在的行存在,则不应插入新行),由于某些原因我无法使用unique-index (唯一索引列中会有空值)。 @mechanical_meat

标签: mysql upsert


【解决方案1】:

有人在stackexchange上回答了这个问题,所以我只是复制并粘贴到这里:

您需要一个子选择来获得包含两个值的有效行

    CREATE TABLE `upsert_test` (
      `ID` int unsigned DEFAULT NULL COMMENT 'id;',
      `UUID` varchar(36) DEFAULT NULL
    ) 
    INSERT INTO upsert_test
    SELECT *  FROM
    (SELECT 1 AS ID, UUID() AS "UUID"
    FROM upsert_test
    WHERE ID=1
    HAVING COUNT(*)=0) t1;
    SELECT * FROM upsert_test

    ID | UUID                                
    -: | :-----------------------------------
     1 | 63b0fa5b-f6d1-11eb-871d-00163e64f9cc

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-24
    • 2012-03-11
    • 2016-07-31
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 2017-06-25
    • 2013-11-16
    相关资源
    最近更新 更多