Задача 1
Вы принимаете решение, уже занято ли имя пользователя, на основе переменной temp
.
Этот параметр настроен на параметр arg c обратного вызова. Когда вы выполняете свой первый вызов INSERT C, обратный вызов для следующего оператора SELECT COUNT(*) FROM customer
устанавливает temp
в 1, поскольку имеется один столбец результатов COUNT(*)
. Фактический результат приходит в виде строки с параметром argv обратного вызова.
Документация гласит:
2-й аргумент функции обратного вызова sqlite3_exe c () - это количество столбцов в результате. Третий аргумент обратного вызова sqlite3_exe c () - это массив указателей на строки, полученных как бы из sqlite3_column_text (), по одному для каждого столбца.
см. https://www.sqlite.org/c3ref/exec.html
Задача 2
Но на самом деле кажется, что вы хотите проверить temp
с помощью SELECT userid FROM customer WHERE username='%s'
ранее. Но если не найдено ни одной записи с соответствующим именем пользователя, обратный вызов не вызывается.
Указатель данных
Указатель * данные никогда не инициализируются.
4-й аргумент sqlite3_exe c () передается на 1-й аргумент каждого вызова обратного вызова.
Поскольку вы не используете указатель данных, вы мог просто передать NULL. Если вы хотите использовать его, обязательно инициализируйте его.
Коды возврата
Функции sqlite3 возвращают код, который указывает, была ли операция успешной или нет. Вы должны проверить, была ли операция успешной, и предпринять соответствующие действия в случае ее сбоя (например, распечатать сообщение об ошибке в stderr и завершить кодом ошибки).
Закрытие соединения с базой данных
Вы вызываете sqlite3_close только в ветке if. Но вы должны закрыть его независимо от результатов.
Лучше использовать подготовленные операторы
Вместо того, чтобы использовать sprintf для создания собственного SQL, который содержит непроверенный внешний пользовательский ввод, вы должны использовать подготовленные операторы. Использование неконтролируемого пользовательского ввода может привести к одной из самых критических угроз безопасности, известной как SQL инъекция.
Поэтому лучше использовать sqlite3_prepare_v2 (), sqlite3_step () и sqlite3_finalize (). По сути, sqlite3_exe c - это просто удобная оболочка для этих вызовов. Для примера того, как его использовать, вы можете взглянуть на { ссылка }.
Еще одним преимуществом этого подхода будет то, что вы будете обрабатывать вызовы SQL и связанные с ними результаты. в том же месте.