不带主键插入或更新(如果存在)

ton*_*099 4 php mysql

我有以下数据库MySQL表.

  • id(PK,AI)
  • 电子邮件
  • 国家
  • 上次登录

我在PHP中有一个常规查询,将其插入表中.但是,从逻辑上讲,如果此代码运行多次,则每次都会向数据库插入相同的行.

我希望我的检查和复制参考是email字段,如果电子邮件是相同的,请更新countrylastlogin.

我检查了类似问题的其他问题,建议的方法是使用ON DUPLICATE KEY这样的

INSERT INTO <table> (field1, field2, field3, ...) 
VALUES ('value1', 'value2','value3', ...)
ON DUPLICATE KEY UPDATE
field1='value1', field2='value2', field3='value3', ...
Run Code Online (Sandbox Code Playgroud)

但是,我的主键不是email字段,id而是我不想对它进行检查.

Tim*_*sen 6

一个选项是使email字段唯一,然后它应该与主键相同,至少在MySQL方面ON DUPLICATE KEY UPDATE:

ALTER TABLE yourTable ADD UNIQUE INDEX `idx_email` (`email`);
Run Code Online (Sandbox Code Playgroud)

然后:

INSERT INTO yourTable (email, country, lastlogin)
VALUES ('tony9099@stackoverflow.com', 'value2', 'value3')
ON DUPLICATE KEY UPDATE
    email='value1', country='value2', lastlogin='value3'
Run Code Online (Sandbox Code Playgroud)

如果tony9099@stackoverflow.com您的表中已存在该电子邮件,则更新将使用其他值启动.

从MySQL 文档:

如果指定ON DUPLICATE KEY UPDATE,并且插入的行将导致UNIQUE索引或PRIMARY KEY中出现重复值,则MySQL将执行旧行的UPDATE.

此方法不仅适用于主键,还适用于具有唯一索引的任何列.


Dir*_*iru 5

正如 Dan 所提到的,ROW_COUNT() 内置函数在标准配置下不支持此解决方案。

MySQL::ROW_COUNT()

对于 UPDATE 语句,默认情况下受影响的行值是实际更改的行数。如果在连接到 mysqld 时为 mysql_real_connect()指定CLIENT_FOUND_ROWS标志,则受影响的行值是“找到”的行数;也就是说,由 WHERE 子句匹配。

如果修改数据库架构不是一个选项,您可以使用以下方法:

UPDATE `table` SET `country`='value1', `lastlogin`='value1' WHERE `email`='value3'

IF ROW_COUNT()=0
    INSERT INTO `table` (`email`, `country`, `lastlogin`) VALUES ('value1', 'value2', 'value3')
Run Code Online (Sandbox Code Playgroud)

  • 如果更新语句不更改记录的值,则此方法不起作用。也就是说,如果 `email`='value3' 的记录已经包含 `country`='value1' 和 `lastlogin`='value1',则 ROW_COUNT() 函数返回零。该记录已经存在,但插入仍然发生。 (3认同)