unixODBC編程(九)分片查詢長數據
訪問www.tomcoding.com網站,學習Oracle內部數據結構,詳細文檔說明,下載Oracle的exp/imp,DUL,logminer,ASM工具的源代碼,學習高技術含量的內容。
當一個表中有長數據類型的字段,比如LONG數據類型,LONG RAW數據類型,字段存儲的數據可能比較大,不可能在程序中定義這樣大的緩沖區,這時就需要一部分一部分的讀取數據,比如字段中存放了一個大的圖片數據,現在取出來存儲成一個圖片文件,那么就可以定義一個合適的緩沖區,每次讀取一部分數據,邊讀邊寫入文件。這時就需要用到一個函數SQLGetData(),先看一下函數原型和參數。
SQLRETURN SQLGetData(
SQLHSTMT StatementHandle,
SQLUSMALLINT Col_or_Param_Num,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
StatementHandle是一個輸入參數,查詢語句的句柄。
Col_or_Param_Num是一個輸入參數,結果集中列的編號,從1開始編號。
TargetType是一個輸入參數,是列的數據類型對應的C語言類型。比如SQL_C_CHAR,SQL_C_SLONG,SQL_C_SSHORT,SQL_C_FLOAT等。
TargetValuePtr是一個輸出參數,指向存儲數據的緩沖區,不能為NULL。
BufferLength是一個輸入參數,上面緩沖區的長度。
StrLen_or_IndPtr是一個輸出參數,指示返回的數據長度,或空數據(SQL_NULL_DATA)。
這個函數要從結果集中取數據,所以需要游標在要取數的那行數據上,所以要在SQLFetch()或SQLFetchScroll()函數之后調用。
看一個實際的例子,有一個表叫做test_long1,有兩個字段id和summary,id是整數類型,summary是LONG類型。從這個表中查詢一條數據,id通過SQLBindCol()函數獲取,summary通過SQLGetData()函數獲取,代碼如下。
#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 rlen_ind1; SQLLEN rlen_ind2; SQLINTEGER id; char dsn_str[32]; char usrname[32]; char passwd[32]; char sqltxt[128]; char buf[256]; 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); } 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; } sprintf(sqltxt, "select id, summary from test_long1 where id=11"); rc = SQLPrepare(stmth, (SQLCHAR *)sqltxt, 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; } /* 綁定ID字段的輸出變量 */ rc = SQLBindCol(stmth, 1, SQL_C_ULONG, (SQLPOINTER)&id, 0, &rlen_ind1); if (rc != SQL_SUCCESS) { fprintf(stderr, "Bind column 1 error.\n"); goto free_exit; } /* 調用SQLFetch()使得游標定位在第一條數據上,也就是我們要取數的數據行上 */ rc = SQLFetch(stmth); if (rc == SQL_NO_DATA) { fprintf(stderr, "no data in result set.\n"); } else if (rc == SQL_ERROR) { fprintf(stderr, "Fetch data error.\n"); goto free_exit; } else if (rc == SQL_SUCCESS) { /* fetch成功,取得ID的值,下面通過SQLGetData()函數,一部分一部分的讀取summary的值 */ fprintf(stdout, "id=%d\nsummary:\n", id); while (1) { rc = SQLGetData(stmth, 2, SQL_C_CHAR, buf, 256, &rlen_ind2); if (rc == SQL_NO_DATA) break; if (rc == SQL_ERROR) { fprintf(stderr, "Get data from column error.\n"); goto free_exit; } if (rc == SQL_SUCCESS) { /* 調用成功,打印這部分的數據 */ fprintf(stdout, "%s\n", buf); } } } /* 關閉游標,游標可以隱式打開,但一定要顯式關閉 */ SQLCloseCursor(stmth); 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); }
訪問www.tomcoding.com網站,學習Oracle內部數據結構,詳細文檔說明,下載Oracle的exp/imp,DUL,logminer,ASM工具的源代碼,還有實時數據庫復制軟件下載,學習高技術含量的內容。

浙公網安備 33010602011771號