Синтаксис MySQL не поддерживает конструкции IF...THEN
, кроме как в хранимых подпрограммах, триггерах и событиях. Смотри https://dev.mysql.com/doc/refman/8.0/en/sql-syntax-compound-statements.html
Я предлагаю альтернативное решение для вашего кода:
INSERT INTO `login` (`Username`, `Password`, `LK`)
SELECT ?, ?, ''
FROM `login`
WHERE `LK` = ?
LIMIT 1
Если ваша таблица входа в систему не имеет значения LK, приведенный выше SELECT вернет 0 строк, поэтому ничего не вставит.
Если ваша таблица входа в систему имеет значение LK, приведенное выше SELECT вернет хотя бы 1 строку (и я ограничу ее 1), поэтому она вставит строку. Вставляемая строка состоит из вашего имени пользователя и пароля, а также пустой строки для LK.
Я показал использование заполнителей параметров. Вы должны использовать параметры в SQL вместо объединения переменных в ваш запрос. Это хорошая практика, чтобы избежать случайного внедрения SQL. См. http://go -database-sql.org / подготовленный.html для примеров.
Цель использования параметров - избежать проблем с внедрением SQL. См. Мой ответ на Что такое SQL-инъекция? для объяснения SQL-инъекции.
Или моя презентация Мифы и ошибки SQL-инъекций (или видео на YouTube ).
При использовании параметров вы делаете два шага.
- Первый шаг для подготовки запроса с заполнителями (
?
), в котором в противном случае вы могли бы объединить переменные в запрос SQL.
- Второй шаг - выполнить подготовленный запрос, и это время, когда вы передаете переменные для заполнения заполнителей.
Смысл в том, чтобы держать переменные отдельно от вашего запроса, поэтому, если в переменной есть что-то, что может непреднамеренно изменить ваш синтаксис SQL (например, несбалансированные кавычки), оно никогда не объединяется с SQL. После того, как вы выполните подготовку, SQL уже проанализирован сервером MySQL, и после этого невозможно изменить синтаксис.
MySQL запоминает, какие части запроса необходимо заполнить, и когда вы передаете переменные на этапе выполнения, MySQL заполняет недостающие части запроса, используя ваши значения - но это происходит на сервере MySQL, а не в вашем приложение.
Таким образом, динамические части запроса - ваши переменные - хранятся отдельно от синтаксиса SQL, и вы избегаете проблем с внедрением SQL.
Для вашей задачи, описанной в вашем вопросе, это выглядело бы примерно так (я не проверял этот код Go, но он должен поставить вас на правильный путь).
stmt, err := tx.Prepare("INSERT INTO `login` (`Username`, `Password`, `LK`) SELECT ?, ?, '' FROM `login` WHERE `LK` = ? LIMIT 1")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
_, err = stmt.Exec(regusernameEntry.Text(), regpasswordEntry.Text(), reglicenceEntry.Text())
if err != nil {
log.Fatal(err)
}
Порядок параметров важен. Переменные, которые вы передаете в Exec()
, должны быть в том же порядке, в котором заполнители ?
появляются в вашем подготовленном операторе SQL. Они сопоставляются один за другим в том же порядке сервером MySQL.
Не ставьте кавычки вокруг заполнителей в подготовленном операторе SQL. Это будет работать как буквальная строка '?'
в SQL. Используйте символ ?
без кавычек для заполнителя. Когда он объединяется с MySQL на сервере, он будет работать так, как если бы вы поместили кавычки вокруг значения в виде строки, но без риска внедрения SQL, даже если это строковое значение содержит специальные символы.
Вот еще один сайт, который дает больше примеров кода: https://github.com/go-sql-driver/mysql/wiki/Examples
Функция Exec()
предназначена для выполнения SQL без набора результатов, такого как INSERT, UPDATE, DELETE. В драйвере Go SQL есть другие функции, такие как Query()
и QueryRow()
, которые также принимают аргументы параметров. Вы бы использовали их, если ваш SQL возвращает набор результатов.