我试图让数据库每秒检查一次表,看看 XP 值是否达到 800,如果达到,则将排名值设置为“Elite Genin”并将 XP 值设置为 0。
@bot.event
async def on_message(message):
guild = message.guild.id
table = "PEOPLE_" + str(guild)
try:
connection = mysql.connector.connect(
host="localhost",
port="3306",
user="root",
password="root",
database="naruto_game"
)
cursor = connection.cursor()
sql_event_query = """CREATE EVENT geninpromotion
ON SCHEDULE EVERY 1 Second
STARTS CURRENT_TIMESTAMP + INTERVAL 1 Second
ENDS CURRENT_TIMESTAMP + INTERVAL 24 Hours
DO UPDATE """ + table + """ SET rank = 'Elite Genin' where xp = 800 AND SET xp = 0"""
cursor.execute(sql_event_query)
except mysql.connector.Error as error:
print("Failed to find name: {}".format(error))
finally:
if connection.is_connected():
cursor.close()
connection.close()
print("MySQL connection has been closed.")
print("Event created.")
但是当运行后我发送一条消息,出现此错误。
Failed to find name: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Hours DO UPDATE " + table + " SET rank = 'Elite Genin' where xp = 800 AND SET xp' at line 2
该错误告诉你你的 SQL 语法有问题。具体来说,MySQL 不喜欢
UPDATE
语句中的
AND
。你不能在
UPDATE
语句的
SET
子句中使用多个
SET
。
以下是如何使用 MySQL 事件和正确的语法创建所需功能的方法:
1. 创建存储过程:
首先,创建一个执行更新的存储过程:
DELIMITER //
CREATE PROCEDURE update_rank()
BEGIN
UPDATE `PEOPLE_` + CAST(@guildId AS CHAR)
SET rank = 'Elite Genin', xp = 0
WHERE xp >= 800;
END //
DELIMITER ;
此存储过程执行以下操作:
-
它接收
guildId
作为参数。 -
它更新
PEOPLE_
表,后跟guildId
。 -
如果
xp
大于或等于 800,则将rank
设置为 'Elite Genin',并将xp
设置为 0。
2. 创建事件:
现在,创建一个每秒调用此存储过程的事件:
sql_event_query = """
CREATE EVENT geninpromotion
ON SCHEDULE EVERY 1 SECOND
DO
BEGIN
CALL update_rank(%s);
END
"""
cursor.execute(sql_event_query, (guild,))
此事件执行以下操作:
-
它每秒调用一次
update_rank
存储过程。 -
它将
guild
变量作为参数传递给存储过程。
重要注意事项:
- 性能影响: 每秒更新数据库会对性能造成很大影响,尤其是在大型表中。考虑降低更新频率或探索其他选项(如消息队列)来处理此类任务。
- 并发性: 如果你的应用程序同时修改 XP,你可能需要考虑使用事务或锁定机制来防止数据不一致。
通过这些更改,你的代码应该可以正常工作,并且你的事件将按预期更新数据库。但是,请务必考虑性能影响并根据需要调整代码。
标签:python,mysql,discord,bots From: 79020207