pythonmysqldiscordbots

How to create MySQL function to update database if a value reaches 800?


I'm trying to make the database check the table every second to see if the XP value has reached 800, and if it does, set the rank value to 'Elite Genin' and set the XP value to 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.")

But when I send a message after running it, I get this error.

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

Solution

  • I see three syntax errors.

    1. The time interval keyword you want is HOUR, not HOURS. Read https://dev.mysql.com/doc/refman/8.4/en/expressions.html#temporal-intervals for details on time interval syntax.

    2. Be careful of naming your column rank, because that's a reserved keyword in MySQL. See https://stackoverflow.com/a/23446378/20860

    3. If you want to set two columns in an UPDATE statement, set them before the WHERE clause.

    The fixed SQL syntax should be as follows:

    CREATE EVENT geninpromotion
     ON SCHEDULE EVERY 1 Second
     STARTS CURRENT_TIMESTAMP + INTERVAL 1 SECOND 
     ENDS CURRENT_TIMESTAMP + INTERVAL 24 HOUR
     DO UPDATE mytable SET `rank` = 'Elite Genin', xp = 0 WHERE xp >= 800
    

    Note the fixes:

    This corrects the syntax errors. I tested it with MySQL 8.4.2.

    However, though it has no syntax errors, it may not be the recommended solution for your task. For example, one could use a trigger to change the rank immediately if the xp is 800 or greater. That way you don't need an event polling the table once per second.