Letzte Änderung: 17.3.97 von B. Tritsch
Zurück zum Index "PC- und MS-Windows-Support"
ODBC oder Open Database Connectivity repräsentiert einen herstellerunabhängigen Mechanismus für den Datenzugriff auf eine Vielzahl von Quellen. ODBC-Treiber sind für viele Datenquellen verfügbar, z.B. für ASCII-Textdateien, Excel Spreadsheets, SQL Server Datenbanken oder Oracle Datenbanken. Viele dieser ODBC-Treiber sind frei distributierbar. Sie können daher zur Installation auf einem Fremdsystem zu einer Applikation gefügt werden, ohne daß der potentielle Kunde extra Lizenzgebühren bezahlen muß.
Das Herz von ODBC ist seine Fähigkeit SQL Aufrufe (Structured Query Language) gegenüber Datenquellen auszuführen. Die MFC-Bibliothek stellt eine breite Unterstützung von ODBC zur Verfügung. Eine Reihe von Klassen kapseln die ODBC-Funktionalitäten.
Bevor eine Datenquelle über ODBC angesprochen werden kann, muß der entsprechende ODBC-Treiber installiert sein. Dies geschieht im Windows-System mit Hilfe des ODBC-Setup-Applets.
Applikationen, die ODBC verwenden, können entweder auf "Single-Tier"- oder "Multiple-Tier"-Treibern basieren. Erstere verarbeiten sowohl ODBC-Aufrufe als auch SQL-Statements. Letztere verarbeiten nur die ODBC-Aufrufe und reichen die SQL-Statements an die Datenquelle weiter (z.B. an einen SQL-Server, der irgendwo im Netz liegt). Weiterhin unterteilt sich ODBC zwischen drei definierten Zugriffsschichten, die sich durch verschiedene Komplexität der Datenbankaufrufe unterscheiden.
Eine ODBC-Applikation muß eine Reihe von Schritten durchführen, um sich mit einer Datenquelle zu verbinden und dort SQL-Statements abzusetzen. Diese Schritte werden im folgenden skizziert:
Im folgenden wird ein einfaches ODBC-Beispiel aufgezeigt. Es verwendet ein MS-Excel Spreadsheet als Datenquelle, wobei die Excel-Worksheets die Rolle der Datenbanktabellen und die Reihen im Worksheet die Rolle von Records in einer Tabelle spielen. Die Tabelle selbst ist eine einfache Auflistung von Personendaten (Name, Vorname, Alter).
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>
#define CONNSTR "DBQ=AGES.XLS;DRIVER={Microsoft Excel Driver (*.xls)}"
#define CONNLEN (sizeof(CONNSTR)-1)
#define SQLTRY(x,y) \
{ \
rc = y; \
if (rc != SQL_SUCCESS) \
{ \
char buf[255]; \
char szState[6]; \
char szMsg[255]; \
SDWORD sdwNative; \
SWORD swMsgLen; \
SQLError(hEnv, hDBC, hStmt, szState, &sdwNative, szMsg, sizeof(szMsg), &swMsgLen); \
wsprintf(buf, "Error %d performing %s\nSQLState = %s\nSQL message = %s", rc, x, szState, szMsg); \
MessageBox(NULL, buf, "Error", MB_OK | MB_ICONSTOP); \
goto Terminate; \
} \
}
int WINAPI WinMain(HINSTANCE d1, HINSTANCE d2, LPSTR d3, int d4)
{
SQLHENV hEnv = 0;
SQLHDBC hDBC = 0;
SQLHSTMT hStmt = 0;
SQLCHAR szConnStr[255];
SQLCHAR szStmt[255];
SQLCHAR szFirstName[255];
SQLCHAR szLastName[255];
long nAge;
SWORD cbConnStr;
RETCODE rc;
SDWORD sdwLNLen;
SDWORD sdwFNLen;
SDWORD sdwALen;
int i;
char szResult[1000];
SQLTRY("SQLAllocEnv", SQLAllocEnv(&hEnv))
SQLTRY("SQLAllocConnect", SQLAllocConnect(hEnv, &hDBC))
SQLTRY("SQLDriverConnect", SQLDriverConnect(hDBC, NULL, CONNSTR, CONNLEN, szConnStr, sizeof(szConnStr), &cbConnStr, SQL_DRIVER_NOPROMPT))
SQLTRY("SQLAllocStmt", SQLAllocStmt(hDBC, &hStmt))
wsprintf(szStmt, "SELECT * FROM [Sheet1$]");
SQLTRY("SQLPrepare", SQLPrepare(hStmt, szStmt, strlen(szStmt)))
SQLTRY("SQLBindCol", SQLBindCol(hStmt, 1, SQL_C_CHAR, (PTR)szLastName, sizeof(szLastName), &sdwLNLen))
SQLTRY("SQLBindCol", SQLBindCol(hStmt, 2, SQL_C_CHAR, (PTR)szFirstName, sizeof(szFirstName), &sdwFNLen))
SQLTRY("SQLBindCol", SQLBindCol(hStmt, 3, SQL_C_SLONG, (PTR)&nAge, sizeof(nAge), &sdwALen))
SQLTRY("SQLExecute", SQLExecute(hStmt))
for (i = 1; (rc = SQLFetch(hStmt)) == SQL_SUCCESS; i++)
{
wsprintf(szResult, "Record #%d\nLast Name: %s\nFirst Name: %s\nAge: %d", i, szLastName, szFirstName, nAge);
MessageBox(NULL, szResult, "Data", MB_OK);
}
if (rc != SQL_NO_DATA_FOUND)
{
SQLTRY("SQLFetch", rc)
}
MessageBox(NULL, "Successfully completed.", "Success", MB_OK);
Terminate:
if (hStmt) SQLFreeStmt(hStmt, SQL_CLOSE);
if (hDBC) SQLDisconnect(hDBC);
if (hDBC) SQLFreeConnect(hDBC);
if (hEnv) SQLFreeEnv(hEnv);
}
Da so viele Dinge bei dem Datenzugriff über ODBC fehleranfällig sind, konnte auch bei diesem Minimalbeispiel nicht auf eine Fehlerbehandlung verzichtet werden. Diese wird durch den allgemeinen Fehler-Reportmechanismu realisiert und basiert auf einem einfachen Makro SQLTRY. Der Rest ist sehr einfach: Es werden die weiter oben beschriebene Standardaufrufe für die Anfrage bei der Datenquelle verwendet. Die Ausgabe erfolgt in einer MessageBox.