3 Overview
3.1 Interfaces
The interface of the ODBC application is divided into three parts:
- Functions for starting and stopping ODBC servers.
- The Basic API which is almost identical to that defined by the ODBC standard.
- The Utility API which supplies a few easy-to-use functions for database access with little control over details.
An ODBC serving process can be compared to an Erlang port. It allows you to make function calls, from Erlang, to an ODBC Driver (or in reality a Driver Manager, which talks to a Driver). The Driver communicates with the database, which it is built for. The serving process also plays the role of a server and will be referred to as the server in this text.
When you start ODBC you get a new server, which handles requests by passing them on to an ODBC Driver. Requests are handled sequentially and the server cannot be connected to more than one database at any time.
An ODBC server can only be started on a named node with a cookie (start Erlang with one of the -name
<nodename>
or -sname<nodename>
options and possibly with the -setcookie<cookie>
option).The server links to the process that starts it (the client). Should the client terminate, the server terminates too. The server is dedicated to the client process just like an Erlang port, but there are two important differences: an ODBC server accepts requests from any process (ports accept messages from the connected process only), and it does not send messages spontaneously (or deliver them from the ODBC Driver) -- the ODBC server is passive.
3.1.1 Utility API
Using the Utility API is easy. Follow the steps below:
- Start the server.
- Initialise the ODBC environment by calling
init_env/[1, 2]
, where [1, 2] marks the possible arities of the function
- Connect to the database with one of
connect/[3, 4, 5, 6]
- Submit SQL statements to the database by calling
exec_stmt/[3, 4]
.
- Disconnect by calling
disconnect/[2, 3]
. At this point it is possible to connect to another database by callingconnect/[3, 4, 5, 6]
again, or you may wish to terminate the environment by callingterminate_env/[2, 3]
.
- The server process dies when
stop/[1, 2]
is called.
3.1.2 Basic API
To be able to make full use of the Basic API it is necessary to be familiar with the ODBC standard. Here is a typical way to use it for a SELECT statement though:
- Allocate an environment handle:
sql_alloc_handle/[3, 4]
.
- Set the ODBC version environment attribute:
sql_set_env_attr/[5, 6]
.
- Allocate a database connection handle:
sql_alloc_handle/[3, 4]
.
- Connect to the database:
sql_connect/[5, 6]
orsql_driver_connect/[5, 6]
.
- Set connection attributes (if you're not happy with the default values):
sql_set_connect_attr/[5, 6]
.
- Allocate a statement handle:
sql_alloc_handle/[3, 4]
.
- Execute an SQL statement:
sql_exec_direct/[3, 4]
- Check if the statement generated a result set (or table), which SELECT statements do:
sql_num_result_cols/[2, 3]
returns a value greater than zero.
- Retrieve data about the buffer size needed for one of the returned columns of the table:
sql_describe_col/[4, 5]
anddisplay_size/2
.
- Allocate a buffer for the column at hand:
alloc_buffer/[3, 4]
.
- Bind the buffer to the column:
sql_bind_col/[4, 5]
.
- Repeat steps 9 through 11 for each desired column (not necessarily all columns in the table).
- Retrieve the first/next column into the buffers:
sql_fetch/[2, 3]
.
- Read the buffer values:
read_buffer/[2, 3]
.
- Repeat steps 13 through 14 until all rows in the table have been retrieved.
- Close the cursor on the statement:
sql_close_cursor/[2, 3]
.
- Start over with step 7 to execute a new statement or free the statement handle:
sql_free_handle/[3, 4]
.
- Disconnect from the database:
sql_disconnect/[2, 3].
- Start over with step 4 to connect to another database or free the database connection handle:
sql_free_handle/[3, 4]
.
- Free the environment handle:
sql_free_handle/[3, 4]
.
Here is a typical way to use the Basic API for an INSERT statement:
- Follow steps 1 through 8 above.
- Check how many rows were affected by the statement:
sql_row_count/[2, 3]
.
- Commmit or rollback the statement:
sql_end_tran/[4, 5]
.
Note:
This is only necessary if the connection attribute SQL_ATTR_AUTOCOMMIT has been changed from the default value to SQL_AUTOCOMMIT_OFF. Otherwise the transaction is automatically committed.
- Follow steps 17 through 19 above.
You may use the Basic API and the Utility API intermittently, but remember that certain operations performed in the Basic API (like setting different attributes defined by the ODBC standard) may affect the behaviour of the Utility API.
3.1.3 Choice of API
When to use which API? The Utility API can be used when none of the following is true:
- It is necessary to set an attribute. This can only be done through the Basic API. You may however use the Basic API just for setting attributes, and the Utility API for all other tasks.
- The table resulting from a SELECT statement is very big. In this case using the Utility API would consume a huge amount of memory, since the whole table is returned in one chunk. You can get around this problem by using the Basic API by retrieving fewer rows at a time, or by using smaller buffers for large columns (which causes data to be truncated).
- You consider ODBC Driver warnings to be serious. The Utility API ignores warnings (when the ODBC Driver returns the code SQL_SUCCESS_WITH_INFO).