In this tutorial, we'll learn the details of using ODBC APIs.
Because our program does not communicate with the ODBC driver directly, but through the ODBC Manager to define a series of APIs for your program calls to complete the work, so we need to include odbc32.inc and odbc32.lib files, of course, and Windows.inc.
The following steps are required to connect to a data source:
Assigns an environment handle (environment handle). This is done only once for each ODBC task (session). Once the handle is obtained, we can modify the environment properties to suit our needs. You can think of this as creating a workspace in db work.
Confirm the version of ODBC that will be used. You can choose between ODBC 2.x and 3.x. They are different in many ways, so this step is necessary to allow the ODBC Administrator what syntax it will use to communicate with the user program and how to interpret the user program's commands.
Assigns a connection handle. This step can be seen as creating an empty connection. We have not yet specified the use of that driver to connect to that database. This information will be written slightly later.
Establish a connection. You can establish a connection by calling an ODBC function.
When the connection completes, you must close and destroy it by following these steps:
Disconnect from the data source.
Releases the connection handle.
Releases the environment handle (if you no longer need to make more connections in this environment)
Assigning a handle
Before the ODBC 3.x version, we needed to invoke many separate functions to allocate the environment, the connection, and the statement handles (SQLALLOCENV, SQLAllocConnect, sqlallocstmt). In ODBC 3.x, These functions are replaced by sqlallochandle, and the syntax is as follows:
Sqlreturn Sqlallochandle (Sqlsmallint handletype,
Sqlhandle Inputhandle,
Sqlhandle * outputhandleptr
);
It looks like a hassle, simplify it and look at it:
Sqlallochandle Proto Handletype:dword, Inputhandle:dword, Outputhandleptr:dword
Sqlreturn is defined as the Sqlsmallint type. and Sqlsmallint is defined as a short integer, such as a word (bits). So the return value of the function is in ax, not eax. This is very important. However, the parameters of the WIN32 function are transmitted through a 32-bit stack. Even if this parameter is only a word length (16 bits), it should be extended to 32 bits. This is why Handletype is described as a double character (DWORD) instead of Word (word). Take a look at the import library The entrance to the Odbc32.lib,sqlallochandle is _sqlallochandle@12. This means that the parameter of this function has a combined length of 12 bytes (3 DWORDs). However, this does not mean that the C function is not a prototype. Sqlallochandle will use only the Handletype word and ignore the high word. So the C function prototype is functionally (functionally) correct and our Assembler function prototype reflects the reality.
To end the discussion of SQL types, let's take a look at the parameters and return values of the functions ...
Handletype is a constant that defines the type of handle that you want to assign. The possible values are as follows:
SQL_HANDLE_ENV Environment handle (environment HANDLE)
SQL_HANDLE_DBC connection handle (Connection HANDLE)
SQL_HANDLE_STMT statement handle (Statement HANDLE)
Sql_handle_desc Description Fu (descriptor HANDLE)
A descriptor is a that describes the parameters of an SQL statement or the number of columns of a result set, depending on the application or driver.
Inputhandle is a handle to the parent text. That is, if you want to assign a connection handle, you need to pass an environment handle because the connection will be created in the text of that environment. If you want to assign an environment handle, this parameter must be sql_handle_null (note sql_ Handle_null is incorrectly defined as 0L in Windows.inc version 1.18 and its previous version. You need to remove "L" otherwise the program will not be compiled. This is my fault because I am responsible for revising the SQL/ODBC section of Windows.inc.) Because the environment has no parent text. For statements and descriptor handles, we need to use the connection handle as this argument.
Outputhandleptr If the call succeeds, it will point to a double word containing the assigned handle.
The possible return values for Sqlallochandle are as follows:
The Sql_success function completed successfully.
The Sql_success_with_info function completes successfully, but returns a non-fatal error or warning.
The Sql_error function call failed.
Sql_invalid_handle the handle passed to the function is illegal.
Regardless of the success or failure of the call to the function, we can get more information by invoking the SQLGetDiagRec or SQLGetDiagField function. They are similar to the GetLastError in the Win32 API.