Параметры SQL-запроса в C++
Склеивать пользовательский текст в SQL небезопасно.
Подготовленный запрос держит шаблон с местами
"?", куда позже кладут значения функциями
sqlite3_bind_text и sqlite3_bind_int.
Шаблон готовят один раз на соединении, затем
заполняют параметры по номеру, начиная с 1:
#include <iostream>
#include <sqlite3.h>
int main() {
sqlite3* db = nullptr;
if (sqlite3_open("slots.db", &db) != SQLITE_OK) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_close(db);
return 1;
}
char* err = nullptr;
if (sqlite3_exec(
db,
"CREATE TABLE IF NOT EXISTS slots ("
"id INTEGER PRIMARY KEY,"
"code TEXT NOT NULL,"
"capacity INTEGER NOT NULL"
")",
nullptr,
nullptr,
&err
) != SQLITE_OK) {
std::cerr << err << "\n";
sqlite3_free(err);
sqlite3_close(db);
return 1;
}
sqlite3_stmt* insert = nullptr;
if (sqlite3_prepare_v2(
db,
"INSERT INTO slots (code, capacity) VALUES (?, ?)",
-1,
&insert,
nullptr
) != SQLITE_OK) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_close(db);
return 1;
}
sqlite3_bind_text(insert, 1, "A1", -1, SQLITE_STATIC);
sqlite3_bind_int(insert, 2, 12);
if (sqlite3_step(insert) != SQLITE_DONE) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_finalize(insert);
sqlite3_close(db);
return 1;
}
std::cout << sqlite3_changes(db) << "\n";
sqlite3_finalize(insert);
sqlite3_close(db);
return 0;
}
Тот же шаблон можно выполнить с другими аргументами:
достаточно снова вызвать sqlite3_bind_...
и sqlite3_step после новой подготовки
или повторного использования текста SQL:
#include <sqlite3.h>
int main() {
sqlite3* db = nullptr;
if (sqlite3_open("slots.db", &db) != SQLITE_OK) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_close(db);
return 1;
}
const char* sql =
"INSERT INTO slots (code, capacity) VALUES (?, ?)";
sqlite3_stmt* insert = nullptr;
if (sqlite3_prepare_v2(db, sql, -1, &insert, nullptr)
!= SQLITE_OK) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_close(db);
return 1;
}
sqlite3_bind_text(insert, 1, "B2", -1, SQLITE_STATIC);
sqlite3_bind_int(insert, 2, 8);
sqlite3_step(insert);
sqlite3_finalize(insert);
if (sqlite3_prepare_v2(db, sql, -1, &insert, nullptr)
!= SQLITE_OK) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_close(db);
return 1;
}
sqlite3_bind_text(insert, 1, "C3", -1, SQLITE_STATIC);
sqlite3_bind_int(insert, 2, 20);
sqlite3_step(insert);
sqlite3_finalize(insert);
sqlite3_close(db);
return 0;
}
Создайте таблицу crates в dock.db
и добавьте строку с меткой "K9" и весом
15 через шаблон с двумя "?".
Добавьте еще одну строку с меткой "L1"
и весом 22 тем же шаблоном без
пересборки SQL-текста.