C または Visual C++ アプリケーションで Visual FoxPro ODBC ドライバーを使用する
C または C++ アプリケーションは、 SQLExecute または SQLExecDirect ステートメントを Visual FoxPro に送信することで、Visual FoxPro データと通信します。 このステートメントには、次の内容を含めることができます。
DROP TABLE コマンドなど、Visual FoxPro 言語にネイティブな SQL ステートメント。
サポートされている SET コマンドなど、SQL 以外の Visual FoxPro 言語。
Visual FoxPro にネイティブな SQL の詳細については、Visual FoxPro のドキュメントを参照してください。
例: C または C++ アプリケーションで Visual FoxPro ODBC ドライバーを使用する
次の例では、ODBC C API を使用して、TasTrade という名前の Microsoft Visual FoxPro サンプル データベースの従業員テーブルのlast_name フィールドに格納されているデータを取得します。 このデータベースは Visual FoxPro で提供され、既定では次の場所にインストールされます。
c:\vfp\samples\mainsamp\data\tastrade.dbc
この例では、一度に 1 つの姓を表示し、メッセージ ボックスで [OK] をクリックして次の姓を表示できるようにします。 Tastrade.dbc データベースを使用するように、Tastrade という名前のデータ ソースが設定されていることを前提としています。
注意
エラー チェックは、すべての ODBC API 呼び出しで実行する必要があります。この例では、簡潔にするためにエラー チェックを除外します。
// 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);
}