unixODBC編程(三)查詢數據庫表中的數據
訪問www.tomcoding.com網站,學習Oracle內部數據結構,詳細文檔說明,下載Oracle的exp/imp,DUL,logminer,ASM工具的源代碼,學習高技術含量的內容。
連接數據庫成功后,就可以對數據庫進行操作了,我們先看一下怎樣從數據庫表中查詢數據。查詢數據在ODBC中也有幾個步驟。
1. 分配一個語句句柄,使用SQLAllocHandle()函數,句柄類型為SQL_HANDLE_STMT。
2. 準備語句,使用SQLPrepare()函數。
3. 執行語句,使用SQLExecute()函數。
4. 綁定輸出的變量,使用SQLBindCol()函數。
5. 循環取回結果集數據,使用SQLFetch()函數。
下面看看這幾個函數的原型和參數。
準備語句函數。
SQLRETURN SQLPrepare(
SQLHSTMT StatementHandle,
SQLCHAR * StatementText,
SQLINTEGER TextLength);
StatementHandle是一個輸入參數,語句句柄。
StatementText是一個輸入參數,SQL文本字符串。
TextLength是一個輸入參數,SQL文本字符串 StatementText 的長度。
執行語句函數。
SQLRETURN SQLExecute(
SQLHSTMT StatementHandle);
StatementHandle是一個輸入參數,語句句柄。
綁定輸出變量函數。
SQLRETURN SQLBindCol(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
StatementHandle是一個輸入參數,語句句柄。
ColumnNumber是一個輸入參數,要綁定的結果集列的序號。列從 0 開始遞增編號,其中列 0 是書簽列。如果沒有使用書簽列,則列號從 1 開始。
TargetType是一個輸入參數,是TargetValuePtr 緩沖區的 C 數據類型。
TargetValuePtr是一個輸入/輸出參數,指向要綁定到列的數據緩沖區的指針。
BufferLength是一個輸入參數,TargetValuePtr 緩沖區的長度(以字節為單位)。
StrLen_or_IndPtr是一個輸入/輸出參數,指向要綁定到列的長度/指示器緩沖區的指針。
取回結果集中數據的函數。
SQLRETURN SQLFetch(
SQLHSTMT StatementHandle);
StatementHandle是一個輸入參數,語句句柄。
現在來看一個例子,連接到數據庫后,從user_table中查詢表名,表空間名和表的狀態。SQL語句為select table_name, tablespace_name, status from user_tables。
#include "stdio.h" #include "stdlib.h" #include "string.h" #include "sql.h" #include "sqlext.h" #include "sqltypes.h" SQLHANDLE envh; /* env handle */ SQLHANDLE dbch; /* connect handle */ SQLHANDLE stmth; /* statement handle */ int main(int argc, char *argv[]){ int conn = 0; SQLRETURN rc; SQLLEN rlen1; SQLLEN rlen2; SQLLEN rlen3; char dsn_str[32]; char usrname[32]; char passwd[32]; char table_name[256]; char ts_name[32]; char status[16]; /* 從命令行參數中輸入數據源名稱,數據庫用戶名和密碼 */ if (argc < 3) { fprintf(stderr, "usage: %s dsn username password\n", argv[0]); return (-1); } strncpy(dsn_str, argv[1], 32); dsn_str[31] = '\0'; strncpy(usrname, argv[2], 32); usrname[31] = '\0'; strncpy(passwd, argv[3], 32); passwd[31] = '\0'; /* 分配環境句柄 */ rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &envh); if (rc != SQL_SUCCESS) { fprintf(stderr, "Allocate environment handle error.\n"); return (-1); } /* 設置ODBC版本 */ rc = SQLSetEnvAttr(envh, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0); if (rc != SQL_SUCCESS) { fprintf(stderr, "Set ODBC version error.\n"); goto free_exit; } /* 分配連接句柄 */ rc = SQLAllocHandle(SQL_HANDLE_DBC, envh, &dbch); if (rc != SQL_SUCCESS) { fprintf(stderr, "Allocate DB connection handle error.\n"); goto free_exit; } /* 設置連接超時時間 */ rc = SQLSetConnectAttr(dbch, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER)10, 0); if (rc != SQL_SUCCESS) { fprintf(stderr, "Set connection timeout value error.\n"); goto free_exit; } /* 連接到數據庫 */ rc = SQLConnect(dbch, (SQLCHAR *)dsn_str, SQL_NTS, (SQLCHAR *)usrname, SQL_NTS, (SQLCHAR *)passwd, SQL_NTS); if (rc != SQL_SUCCESS) { fprintf(stderr, "Connect to DB error.\n"); goto free_exit; } /* 設置連接數據庫成功的標志 */ conn = 1; fprintf(stdout, "connect DB ok ......\n"); /* 分配語句句柄 */ rc = SQLAllocHandle(SQL_HANDLE_STMT, dbch, &stmth); if (rc != SQL_SUCCESS) { fprintf(stderr, "Allocate statment handle error.\n"); goto free_exit; } /* 準備SQL語句文本 */ rc = SQLPrepare(stmth, (SQLCHAR *)"select table_name, tablespace_name, status from user_tables", SQL_NTS); if (rc != SQL_SUCCESS) { fprintf(stderr, "Prepare statment error.\n"); goto free_exit; } /* 執行語句 */ rc = SQLExecute(stmth); if (rc != SQL_SUCCESS) { fprintf(stderr, "Execute statment error.\n"); goto free_exit; } /* 綁定第一列的輸出變量,類型是C語言的char類型,rlen1是返回的數據長度 */ rc = SQLBindCol(stmth, 1, SQL_C_CHAR, (SQLCHAR *)table_name, 256, &rlen1); if (rc != SQL_SUCCESS) { fprintf(stderr, "Bind column 1 error.\n"); goto free_exit; } /* 綁定第二列輸出變量 */ rc = SQLBindCol(stmth, 2, SQL_C_CHAR, (SQLCHAR *)ts_name, 32, &rlen2); if (rc != SQL_SUCCESS) { fprintf(stderr, "Bind column 2 error.\n"); goto free_exit; } /* 綁定第三列輸出變量 */ rc = SQLBindCol(stmth, 3, SQL_C_CHAR, (SQLCHAR *)status, 16, &rlen3); if (rc != SQL_SUCCESS) { fprintf(stderr, "Bind column 3 error.\n"); goto free_exit; } while (1) { /* 返回結果集數據 */ rc = SQLFetch(stmth); if (rc == SQL_NO_DATA) { /* 結果集中沒有數據了,退出循環 */ break; } else if (rc == SQL_ERROR) { /* 出錯,返回 */ fprintf(stderr, "Fetch data error.\n"); goto free_exit; } /* 打印返回的變量值 */ fprintf(stdout, "table_name=%s, tablespace_name=%s, status=%s\n", table_name, ts_name, status); } /* 釋放語句句柄 */ SQLFreeHandle(SQL_HANDLE_STMT, stmth); /* 斷開數據庫連接 */ SQLDisconnect(dbch); /* 釋放連接句柄 */ SQLFreeHandle(SQL_HANDLE_DBC, dbch); /* 釋放環境句柄 */ SQLFreeHandle(SQL_HANDLE_ENV, envh); return (0); free_exit: if (stmth != NULL) { SQLFreeHandle(SQL_HANDLE_STMT, stmth); } if (conn) { SQLDisconnect(dbch); } if (dbch != NULL) { SQLFreeHandle(SQL_HANDLE_DBC, dbch); } if (envh != NULL) { SQLFreeHandle(SQL_HANDLE_ENV, envh); } return (-1); }
編譯程序,需要包含unixODBC的include路徑和連接庫的路徑,比如源文件叫odbc_test.c,編譯命令如下。
cc -I$HOME/unixODBC/include -L$HOME/unixODBC/lib -lodbc odbc_test.c

浙公網安備 33010602011771號