是否可以有一个 MySQL 查询并根据是否存在一行选择插入或更新?

Is it possible to have one MySQL query and depending if a row exists choose INSERT or UPDATE?

我正在做一个项目,目前遇到了一个问题。我有一个 table 记录玩家访问数据。每个玩家都有自己的唯一ID和他们去过的地方的名称,包括访问日期和次数。

示例行: TestUser Server12 2020-10-25 12:00:00 25

现在速度是这个问题的一部分,因为我需要它相对快,因为我正在对多达 70 名玩家进行比较。我认为批量查询会更好,因为它会显着减少执行时间,但是,问题在于如何检查特定对 table 中的行是否存在 (user and server),如果不插入新行,如果是,则在访问计数增量 (+1)

后使用当前日期值更新当前现有行

我知道 INSERT ON DUPLICATE KEY,但是这不起作用,因为它使用主键查找行,我使用播放器唯一 ID 和服务器名称。

所以我的问题是,是否有任何方法可以执行一个查询,如果该行不存在则执行插入或使用这两个指定的列更新现有行。

我之前的解决方案:

Select 检查是否存在的语句:

$"SELECT Count(*) FROM `visited` WHERE playerid='{playerID}' AND server_name='{serverName}'"

然后根据 select 结果执行以下操作之一: 插入:

INSERT INTO visited (playerid, server_name, visit_count, last_visit_date) " +
                    $"VALUES ('{playerID}', '{v}', IFNULL(visit_count,0)+1, '{DateTime.Now:MM/dd/yyyy hh:mm:ss tt}')

更新:

UPDATE visited SET visit_count=IFNULL(visit_count,0)+1, last_visit_date='{DateTime.Now:MM/dd/yyyy hh:mm:ss}' WHERE playerid='{playerID}' AND server_name='{v}'

旧的解决方案真的很慢,尤其是当我对每个玩家调用时。

在MySQL中,您可以使用on duplicate key语法。首先,您需要对列 (playerid, server_name) 进行唯一(或主键)约束。如果它不存在,请创建它:

 alter table visited 
     add constraint ck_visited_uniq 
     unique (playerid, server_name)

那么,你可以这样做:

insert into visited (playerid, server_name, visit_count, last_visit_date)
values (?, ?, 1, now())
on duplicate key update 
    visit_count = coalesce(visit_count, 0) + 1, 
    last_visit_date = now()

备注:

  • 这使用绑定参数(由 ?s 表示)而不是连接查询字符串中的值

  • 您似乎想要 last_visit_date 当前的 date/time:如果是这样,则无需通过您的应用程序,您可以使用 built-in 函数now()

  • 我知道你想要 1 的首字母 visit_count,然后随着每个提示递增

我用这种方式,所以我不必总是依赖主ID(密钥)

if exists(select 1 from [{tablename}] where {Where_cmd} )
BEGIN
 update {tablename} set {...} where {Where_cmd};
END  
ELSE 
 INSERT INTO {tablename} (...) Values(...);