ODBC Backend Reference
SOCI backend for accessing variety of databases via ODBC API.
Prerequisites
Supported Versions
The SOCI ODBC backend is supported for use with ODBC 3.
Tested Platforms
ODBC | OS | Compiler |
---|---|---|
3 | Linux (Ubuntu 12.04) | g++ 4.6.3 |
3 | Linux (Ubuntu 12.04) | clang 3.2 |
3.8 | Windows 8 | Visual Studio 2012 |
3 | Windows 7 | Visual Studio 2010 |
3 | Windows XP | Visual Studio 2005 (express) |
3 | Windows XP | Visual C++ 8.0 Professional |
3 | Windows XP | g++ 3.3.4 (Cygwin) |
3 (unixodbc 2.3.6) | macOS High Sierra 10.13.5 | AppleClang 9.1.0.9020039 |
Required Client Libraries
The SOCI ODBC backend requires the ODBC client library.
Connecting to the Database
To establish a connection to the ODBC database, create a Session object using the ODBC
backend factory together with a connection string:
backend_factory const& backEnd = odbc;
session sql(backEnd, "filedsn=c:\\my.dsn");
or simply:
session sql(odbc, "filedsn=c:\\my.dsn");
The set of parameters used in the connection string for ODBC is the same as accepted by the SQLDriverConnect function from the ODBC library.
Once you have created a session
object as shown above, you can use it to access the database, for example:
int count;
sql << "select count(*) from invoices", into(count);
(See the connection and data binding documentation for general information on using the session
class.)
SOCI Feature Support
Dynamic Binding
The ODBC backend supports the use of the SOCI row
class, which facilitates retrieval of data whose type is not known at compile time.
When calling row::get<T>()
, the type you should pass as T depends upon the underlying database type.
For the ODBC backend, this type mapping is:
ODBC Data Type | SOCI Data Type (data_type ) |
row::get<T> specializations |
---|---|---|
SQL_DOUBLE, SQL_DECIMAL, SQL_REAL, SQL_FLOAT, SQL_NUMERIC | dt_double | double |
SQL_TINYINT, SQL_SMALLINT, SQL_INTEGER, SQL_BIGINT | dt_integer | int |
SQL_CHAR, SQL_VARCHAR | dt_string | std::string |
SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_TYPE_TIMESTAMP | dt_date | std::tm |
ODBC Data Type | SOCI Data Type (db_type ) |
row::get<T> specializations |
---|---|---|
SQL_DOUBLE, SQL_DECIMAL, SQL_REAL, SQL_FLOAT, SQL_NUMERIC | db_double | double |
SQL_TINYINT | db_int8 | int8_t |
SQL_SMALLINT | db_int16 | int16_t |
SQL_INTEGER | db_int32 | int32_t |
SQL_BIGINT | db_int64 | int64_t |
SQL_CHAR, SQL_VARCHAR | db_string | std::string |
SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_TYPE_TIMESTAMP | db_date | std::tm |
Not all ODBC drivers support all datatypes.
Columns having the attribute unsigned
get mapped to their corresponding db_uint[n]
and uint[n]_t
types.
(See the dynamic resultset binding documentation for general information on using the row
class.)
Binding by Name
In addition to binding by position, the ODBC backend supports binding by name, via an overload of the use()
function:
int id = 7;
sql << "select name from person where id = :id", use(id, "id")
Apart from the portable "colon-name" syntax above, which is achieved by rewriting the query string, the backend also supports the ODBC ? syntax:
int i = 7;
int j = 8;
sql << "insert into t(x, y) values(?, ?)", use(i), use(j);
Bulk Operations
The ODBC backend has support for SOCI's bulk operations interface. Not all ODBC drivers support bulk operations, the following is a list of some tested backends:
ODBC Driver | Bulk Read | Bulk Insert |
---|---|---|
MS SQL Server 2005 | YES | YES |
MS Access 2003 | YES | NO |
PostgresQL 8.1 | YES | YES |
MySQL 4.1 | NO | NO |
Transactions
Transactions are also fully supported by the ODBC backend, provided that they are supported by the underlying database.
BLOB Data Type
Not currently supported.
RowID Data Type
Not currently supported.
Nested Statements
Not currently supported.
Stored Procedures
Not currently supported.
Native API Access
SOCI provides access to underlying datbabase APIs via several getBackEnd() functions, as described in the beyond SOCI documentation.
The ODBC backend provides the following concrete classes for navite API access:
Accessor Function | Concrete Class |
---|---|
session_backend* session::get_backend() | odbc_session_backend |
statement_backend* statement::get_backend() | odbc_statement_backend |
rowid_backend* rowid::get_backend() | odbc_rowid_backend |
Backend-specific extensions
odbc_soci_error
The ODBC backend can throw instances of class odbc_soci_error
, which is publicly derived from soci_error
and has additional public members containing the ODBC error code, the Native database error code, and the message returned from ODBC:
int main()
{
try
{
// regular code
}
catch (soci::odbc_soci_error const& e)
{
cerr << "ODBC Error Code: " << e.odbc_error_code() << endl
<< "Native Error Code: " << e.native_error_code() << endl
<< "SOCI Message: " << e.what() << std::endl
<< "ODBC Message: " << e.odbc_error_message() << endl;
}
catch (exception const &e)
{
cerr << "Some other error: " << e.what() << endl;
}
}
get_connection_string()
The odbc_session_backend
class provides std::string get_connection_string() const
method
that returns fully expanded connection string as returned by the SQLDriverConnect
function.
Configuration options
This backend supports odbc_option_driver_complete
option which can be passed to it via connection_parameters
class. The value of this option is passed to SQLDriverConnect()
function as "driver completion" parameter and so must be one of SQL_DRIVER_XXX
values, in the string form. The default value of this option is SQL_DRIVER_PROMPT
meaning that the driver will query the user for the user name and/or the password if they are not stored together with the connection. If this is undesirable for some reason, you can use SQL_DRIVER_NOPROMPT
value for this option to suppress showing the message box:
connection_parameters parameters("odbc", "DSN=mydb");
parameters.set_option(odbc_option_driver_complete, "0" /* SQL_DRIVER_NOPROMPT */);
session sql(parameters);