在MySQL中添加记录时插入或更新或跳过

时间:2017-07-21 07:53:47

标签: mysql sql

CREATE TABLE `my_db`.`my_table` (
  `key` INT NOT NULL AUTO_INCREMENT,
  `insert_dt` DATETIME(5) NOT NULL,
  `md5_hash` VARCHAR(32) NOT NULL,
  `col0` DATETIME(5) NOT NULL,
  `col1` VARCHAR(10) NOT NULL,
  `col2` VARCHAR(5) NOT NULL,
  `col3` NVARCHAR(50) NULL,
  `col4` NVARCHAR(50) NULL,
  `col5` NVARCHAR(50) NULL,
  `col6` NVARCHAR(50) NULL,
  PRIMARY KEY (`key`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4;
  • md5_hash是col1col6的MD5哈希值(我刚添加它,所以我不比较所有6列的值,希望它能让我的生活更轻松)。
  • col1 + col2 + col3 + col4的组合应该是唯一的(我可以为这4个添加md5哈希列,如果这会让我的生活更轻松)< / LI>

我想:

  • 如果表格中存在md5_hash,请跳过(不要插入/更新)
  • 如果col1 + col2 + col3 + col4的合并已经存在,则更新记录
  • 如果md5_hash不存在,则插入新的

我目前使用以下查询,我在这里找到了SKIP / INSERT,它的效果很好:

INSERT INTO `my_db`.`my_table`
  ( `insert_dt`, `md5_hash`, `col0`, `col1`, `col2`, ... )
SELECT * FROM 
  ( SELECT ? as `insert_dt`, ? as `md5_hash`, ? as `col0`, ? as `col1`, ? as `col2`, ... ) AS tmp
WHERE NOT EXISTS (
    SELECT `md5_hash` FROM `my_db`.`my_table` WHERE `md5_hash` = ?
) LIMIT 1;

看起来我可以执行INSERT / UPDATE(如果我为col1添加UNIQUE约束+ col2 + col3 + col4

INSERT INTO `my_db`.`my_table`
  (`insert_dt`, `md5_hash`, `col0`, `col1`, `col2`, ...)
VALUES
  (?, ?, ?, ?, ?, ...)
ON DUPLICATE KEY UPDATE
  insert_dt = VALUES(insert_dt),
  md5_hash  = VALUES(md5_hash),
  col0  = VALUES(col0),
  col5  = VALUES(col5),
  col6  = VALUES(col6)

但我如何将两者合并?

1 个答案:

答案 0 :(得分:1)

您可以通过检查md5-hash是否等于当前值然后&#34;更新&#34;来执行此操作。具有当前值的列。

您需要md5_hashcol1, col2, col3, col4上的唯一索引。

然后你可以使用

INSERT INTO `my_table`
  (`insert_dt`, `md5_hash`, `col0`, `col1`, `col2`, ...)
VALUES
  (?, ?, ?, ?, ?, ...)
ON DUPLICATE KEY UPDATE
  insert_dt = if(md5_hash = VALUES(md5_hash), insert_dt, VALUES(insert_dt)),
  col0 = if(md5_hash = VALUES(md5_hash), col0, VALUES(col0)),
  col5 = if(md5_hash = VALUES(md5_hash), col5, VALUES(col5)),
  col6 = if(md5_hash = VALUES(md5_hash), col6, VALUES(col6)),
  md5_hash = VALUES(md5_hash);

如果md5_hash上的唯一键被违反,md5_hash = VALUES(md5_hash)on duplicate key update将简单地更新&#34;具有当前值的所有列,这意味着它会跳过更新。从技术上讲,MySQL甚至会将此行视为未更新(例如,在计算受影响的行或(不)执行触发器时),这意味着它实际上会跳过它们。

如果违反col1 ... col4上的唯一键,而md5_hash上的唯一键({1}},md5_hash != VALUES(md5_hash)on duplicate key update将使用新值更新列。< / p>

如果没有违反唯一密钥(因此特别是md5_hash尚不存在),它将照常插入行。

请注意,md5_hash最后更新。这是必要的,因为MySQL会逐列更新并使用新列值进行连续比较(因此不会更新这些列)。