Как работает 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.