是否可以有一个MySQL查询,并根据行是否存在选择INSERT或UPDATE



我正在做一个项目,目前遇到了一个问题。我有一张记录玩家访问数据的表。每个玩家都有自己独特的id和他们访问过的地方的名称,包括访问日期和计数。

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

现在速度是这个问题的一部分,因为我需要它相应地快,因为我正在对多达70名球员进行比较。我认为批量查询会更可取,因为这样可以大大缩短执行时间。然而,问题是如何检查该行是否存在于特定对(user and server)的表中,如果不插入新行,如果是,则在访问计数增量(+1)之后用当前日期值更新当前现有行

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

因此,我的问题是,是否有任何方法可以执行一个查询,如果行不存在,它将执行插入操作,或者用这两个指定的列更新现有行。

我以前的解决方案是:

选择要检查是否存在的语句:

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

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

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的当前日期/时间:如果是这样,则无需从应用程序传递if,您可以使用内置函数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(...);

最新更新