Uso del controlador ODBC de Visual FoxPro con la aplicación de C o Visual C++
La aplicación de C o C++ se comunica con los datos de Visual FoxPro mediante el envío de una instrucción SQLExecute o SQLExecDirect a Visual FoxPro. Esta instrucción puede contener lo siguiente:
Instrucciones SQL nativas del lenguaje Visual FoxPro, como el comando DROP TABLE .
Lenguaje Visual FoxPro que no es de SQL, como los comandos SET admitidos.
Para obtener más información sobre SQL nativo de Visual FoxPro, consulte la documentación de Visual FoxPro.
Ejemplo: Uso del controlador ODBC de Visual FoxPro con la aplicación C o C++
En el ejemplo siguiente se usa la API de ODBC C para recuperar los datos almacenados en el campo last_name de la tabla employee de la base de datos de ejemplo de Microsoft Visual FoxPro denominada TasTrade. Esta base de datos se proporciona con Visual FoxPro y se instala de forma predeterminada en la siguiente ubicación:
c:\vfp\samples\mainsamp\data\tastrade.dbc
En el ejemplo se muestra un apellido a la vez, lo que le permite hacer clic en Aceptar en el cuadro de mensaje para ver el apellido siguiente. Se supone que se ha configurado un origen de datos denominado Tastrade para usar la base de datos Tastrade.dbc.
Nota
La comprobación de errores debe realizarse en todas las llamadas API odbc; en este ejemplo se excluye la comprobación de errores por motivos de brevedad.
// FoxPro_ODBC_Driver_with_C.cpp
// compile with: odbc32.lib user32.lib /c
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <stdio.h>
#include <mbstring.h>
#define MAX_DATA 100
#define MYSQLSUCCESS(rc) ((rc==SQL_SUCCESS)||(rc==SQL_SUCCESS_WITH_INFO))
class direxec {
RETCODE rc; // ODBC return code
HENV henv; // Environment
HDBC hdbc; // Connection handle
HSTMT hstmt; // Statement handle
unsigned char szData[MAX_DATA]; // Returned data storage
SDWORD cbData; // Output length of data
unsigned char chr_ds_name[SQL_MAX_DSN_LENGTH]; // Data source name
public:
direxec(); // Constructor
void sqlconn(); // Allocate env, stat, and conn
void sqlexec(unsigned char *); // Execute SQL statement
void sqldisconn(); // Free pointers to env, stat, conn, and disconnect
void error_out(); // Displays errors
};
// Constructor initializes the string chr_ds_name with the data source name.
direxec::direxec() {
_mbscpy_s(chr_ds_name, (const unsigned char *)"tastrade");
}
// Allocate environment handle, allocate connection handle,
// connect to data source, and allocate statement handle.
void direxec::sqlconn() {
SQLAllocEnv(&henv);
SQLAllocConnect(henv, &hdbc);
rc=SQLConnect(hdbc, chr_ds_name, SQL_NTS, NULL, 0, NULL, 0);
// Deallocate handles, display error message, and exit.
if (!MYSQLSUCCESS(rc)) {
SQLFreeEnv(henv);
SQLFreeConnect(hdbc);
error_out();
exit(-1);
}
rc = SQLAllocStmt(hdbc, &hstmt);
}
// Execute SQL command with SQLExecDirect() ODBC API.
void direxec::sqlexec(unsigned char * cmdstr) {
rc = SQLExecDirect(hstmt, cmdstr, SQL_NTS);
if (!MYSQLSUCCESS(rc)) { // Error
error_out();
// Deallocate handles and disconnect.
SQLFreeStmt(hstmt, SQL_DROP);
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
exit(-1);
}
else {
for (rc = SQLFetch(hstmt) ; rc == SQL_SUCCESS; rc=SQLFetch(hstmt)) {
SQLGetData(hstmt, 1, SQL_C_CHAR, szData, sizeof(szData), &cbData);
// In this example, the data is returned in a messagebox for
// simplicity. However, normally the SQLBindCol() ODBC API could
// be called to bind individual data rows and assign for a rowset.
MessageBox(NULL, (const char *)szData, "ODBC", MB_OK);
}
}
}
// Free the statement handle, disconnect, free the connection handle, and
// free the environment handle.
void direxec::sqldisconn() {
SQLFreeStmt(hstmt, SQL_DROP);
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
}
// Display error message in a message box that has an OK button.
void direxec::error_out() {
unsigned char szSQLSTATE[10];
SDWORD nErr;
unsigned char msg[SQL_MAX_MESSAGE_LENGTH + 1];
SWORD cbmsg;
while(SQLError(0, 0, hstmt, szSQLSTATE, &nErr, msg, sizeof(msg), &cbmsg) == SQL_SUCCESS) {
sprintf_s((char *)szData, MAX_DATA, "Error:\nSQLSTATE=%s, Native error=%ld, msg='%s'",
szSQLSTATE, nErr, msg);
MessageBox(NULL, (const char *)szData, "ODBC Error", MB_OK);
}
}
int main (){
// Declare an instance of the direxec object.
direxec x;
// Allocate handles and connect.
x.sqlconn();
// Execute SQL command "SELECT last_name FROM employee".
x.sqlexec((UCHAR FAR *)"SELECT last_name FROM employee");
// Free handles, and disconnect.
x.sqldisconn();
// Return success code; example executed successfully.
return (TRUE);
}