Как работает SQL-запрос INSERT WHERE NOT EXISTS в Lua

    При разработке игровых серверов или веб-приложений часто возникает задача: добавить запись в таблицу только если её ещё нет. Это позволяет избежать дублирования данных и сохранить целостность базы. В статье разберём конкретный пример на Lua с использованием MySQL и конструкции INSERT ... WHERE NOT EXISTS.

    Структура запроса на вставку с проверкой существования

    В исходном коде используется функция DelAcc_Start_MySQL, которая формирует SQL-запрос для добавления нового игрока. Основная логика:

    • Проверяется, существует ли запись с переданным SteamID.
    • Если записи нет - вставляются новые данные (логин, SteamID, стартовые значения).
    • Если запись уже есть - ничего не происходит.

    Ключевая часть запроса:

    INSERT INTO qq_player_acc(...) SELECT ... WHERE NOT EXISTS(SELECT * FROM qq_player_acc WHERE SteamID='^sid');

    В MySQL INSERT ... SELECT позволяет вставить результат подзапроса. А WHERE NOT EXISTS гарантирует, что вставка произойдёт только при отсутствии совпадений.

    Функция чтения данных и возврат nil

    Функция DelAcc_GET_PersonsCreate возвращает значение поля PersonsCreate для указанного SteamID. Если запись не найдена - результат будет nil. Это нормальное поведение: nil означает отсутствие данных. Когда запись только создаётся, поле получает значение 2 (статус сбора данных).

    Почему возвращается nil или 2

    Логика проста:

    • nil - игрок ещё не создан в таблице (запись отсутствует).
    • 2 - игрок создан, данные собираются (поле PersonsCreate установлено в 2).

    После завершения сбора данных значение может измениться на другое (например, 1 или 0). Это зависит от бизнес-логики приложения.

    Обработка подстановки переменных в Lua

    В коде используется gsub для замены плейсхолдеров ^login, ^sid, ^time на реальные значения. Это простой и безопасный способ, если данные предварительно экранированы. В противном случае рекомендуется использовать параметризованные запросы для предотвращения SQL-инъекций.

    Типичные ошибки и их решение

    • Ошибка синтаксиса: проверьте, что в запросе нет лишних кавычек и правильно расставлены скобки.
    • Неверный тип данных: функция tonumber может вернуть nil, если поле содержит нечисловое значение.
    • Отсутствие соединения с БД: убедитесь, что do_query_data корректно обрабатывает ошибки подключения.

    Заключение

    Конструкция INSERT WHERE NOT EXISTS - надёжный способ добавить запись только при её отсутствии. В сочетании с Lua и MySQL она позволяет эффективно управлять данными игроков. Главное - следить за корректной подстановкой переменных и обрабатывать случай nil.

    Часто задаваемые вопросы