是否可以有一个 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(...);
我正在做一个项目,目前遇到了一个问题。我有一个 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(...);