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&amp; 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 &amp;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);