What it is
SOCI is a C++ database access library that provides a clean, type-safe, and object-oriented abstraction over SQL databases. It acts like a lightweight ORM but retains full SQL control, offering both simplicity and flexibility.
SOCI allows developers to write queries in natural SQL while providing type-safe bindings to C++ variables. It eliminates manual binding and fetching of data, making database interaction safer and cleaner.
Installation
sudo apt install libsoci-devGetting started
The smallest useful thing you can do with it, and what each part means.
#include <soci/soci.h>
#include <iostream>
int main() {
try {
soci::session sql(soci::postgresql, "dbname=mydb user=myuser password=mypass");
std::cout << "Connected successfully!" << std::endl;
} catch (std::exception const &e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}Advanced usage
Where the library earns its place over a simpler alternative.
int count;
sql << "SELECT COUNT(*) FROM users", soci::into(count);
std::cout << "User count: " << count << std::endl;soci::rowset<soci::row> rs = (sql.prepare << "SELECT id, name FROM users");
for (auto const &r : rs) {
int id = r.get<int>(0);
std::string name = r.get<std::string>(1);
std::cout << id << ": " << name << std::endl;
}std::string name = "John";
int age;
sql << "SELECT age FROM users WHERE name = :name", soci::into(age), soci::use(name);{
soci::transaction tr(sql);
sql << "INSERT INTO logs(message) VALUES('test')";
tr.commit();
}Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- soci_error: Cannot establish connection
- Check database credentials, network connectivity, and that the backend driver is installed.
- Row not found exception
- Use `sql.get_single_result()` cautiously or check for empty results before accessing.
- Type conversion error
- Ensure correct C++ types are mapped to SQL columns (e.g., `int` to INTEGER, `std::string` to TEXT).
Best practices
- Use parameter binding (`soci::use`) to avoid SQL injection.
- Wrap multiple statements in transactions for safety and efficiency.
- Catch exceptions from SOCI queries to handle runtime errors gracefully.
- Use `rowset` for large result sets to stream data instead of loading all at once.
- Leverage backend-specific options (e.g., PostgreSQL vs MySQL) for performance tuning.
Background
Why it exists, and what it was reacting to.
SOCI (The C++ Database Access Library) was started in 2004 by Maciej Sobczak to provide a modern alternative to traditional C database APIs like ODBC and libpq. It focuses on safety, readability, and minimal boilerplate while avoiding the complexity of full ORM frameworks. It supports multiple backends including PostgreSQL, MySQL, SQLite, Oracle, and ODBC.
