OCI編程基礎篇(九) 查詢數據
訪問www.tomcoding.com網站,學習Oracle內部數據結構,詳細文檔說明,下載Oracle的exp/imp,DUL,logminer,ASM工具的源代碼,學習高技術含量的內容。
查詢數據是OCI程序中的一個常用的操作,它不會對數據庫的數據產生改變,操作的步驟也與更新操作的步驟有區別,用到了不一樣的函數。下面先看一下查詢操作的步驟。
1. 分配OCI語句句柄,用到函數OCIHandleAlloc()。
2. 準備SQL語句,用到函數OCIStmtPrepare()。
3. 定義每個查詢字段輸出變量,用到函數OCIDefineByPos()。
4. 執行OCI語句,用到函數OCIStmtExecute()。
5. 取回查詢結果,用到函數OCIStmtFetch()。
下面看一下用到的新函數原型和參數。
第一個函數,定義輸出變量函數。
sword OCIDefineByPos ( OCIStmt *stmtp,
OCIDefine **defnpp,
OCIError *errhp,
ub4 position,
void *valuep,
sb4 value_sz,
ub2 dty,
void *indp,
ub2 *rlenp,
ub2 *rcodep,
ub4 mode );
stmtp是一個輸入/輸出參數,是分配的查詢語句句柄。
defnpp是一個輸入/輸出參數,是跟查詢列表中的字段對應的定義句柄,存放本字段相關的信息,如果不需要,可以賦值為NULL。
errhp是一個輸入/輸出參數,是錯誤句柄,用于獲取錯誤碼和錯誤信息文本。
position是一個輸入參數,是查詢列表中字段的位置,從1開始計算。
valuep是一個輸入/輸出參數,指向輸出變量的地址或一個輸出數組的地址。
value_sz是一個輸入參數,指定valuep存儲緩沖區的大小,以字節計算。
dty是一個輸入參數,是查詢列表中字段的數據類型,與綁定函數中的定義一致。
indp是一個輸入參數,是指示變量指針,如果查詢的字段返回值為NULL,指示變量返回值為-1。
rlenp是一個輸入/輸出參數,是返回結果的字段值的實際大小。
rcodep是一個輸出參數,返回字段級別的錯誤碼。
mode是一個輸入參數,指示定義函數的模式,一般取值為OCI_DEFAULT。
第二個函數,取回查詢結果函數。
sword OCIStmtFetch ( OCIStmt *stmtp,
OCIError *errhp,
ub4 nrows,
ub2 orientation,
ub4 mode );
stmtp是一個輸入參數,查詢語句的OCI句柄。
errhp是一個輸入參數,錯誤句柄,用于返回錯誤碼和錯誤信息文本。
nrows是一個輸入參數,希望取回的數據條數。
orientation是一個輸入參數,獲取數據的方向,取值為OCI_FETCH_NEXT,獲取下一條數據。
mode是一個輸入參數,取值為OCI_DEFAULT。
我們還是通過一個實際的例子來看看這些函數的用法,還是使用前面創建的表test_tab,從里面查詢數據的SQL語句為SELECT ID, NAME, ADDR FROM test_tab。其中ID, NAME, ADDR就是查詢列表字段。下面看看用OCI程序怎樣操作。
OCIEnv *envhp = NULL; OCIError *errhp = NULL; OCIServer *svrhp = NULL; OCISession *usrhp = NULL; OCISvcCtx *svchp = NULL; OCIStmt *smthp = NULL; /* 查詢數據 */
int select_data(void){ sword rc; int slen; sb2 ind_id; sb2 ind_name; sb2 ind_addr; ub2 alen_id; ub2 alen_name; ub2 alen_addr; ub2 rcode_id; ub2 rcode_name; ub2 rcode_addr; int32_t id; char id_str[64]; char name[32]; char addr[256]; OCIDefine *defp; char sqltxt[1024]; /* 分配OCI語句句柄 */ rc = OCIHandleAlloc( (void *)envhp, (void **)&smthp, OCI_HTYPE_STMT, 0, (void **)NULL ); if (rc != OCI_SUCCESS) { fprintf(stderr, "OCIHandleAlloc() - allocate statement handle error !\n"); return (-1); } /* 生成查詢語句文本 */ strcpy(sqltxt, "SELECT ID, NAME, ADDR FROM test_tab"); slen = strlen(sqltxt); /* 準備語句 */ if (check_oci_error(errhp, OCIStmtPrepare(smthp, errhp, (const OraText *)sqltxt, slen, OCI_NTV_SYNTAX, OCI_DEFAULT)) < 0) return (-1); /* 定義第一個字段ID的輸出變量 */ if (check_oci_error(errhp, OCIDefineByPos((OCIStmt *)smthp, (OCIDefine **)&defp, errhp, (ub4)1, /* position */ (void *)&id, /* valuep */ (sb4)4, /* value_sz */ (ub2)SQLT_INT, /* dty */ (void *)&ind_id, /* indp */ (ub2 *)&alen_id, /* alenp */ (ub2 *)&rcode_id, /* column return code pointer */ (ub4)OCI_DEFAULT) /* mode */ ) < 0) return (-1); /* 定義第二個字段NAME的輸出變量 */ if (check_oci_error(errhp, OCIDefineByPos((OCIStmt *)smthp, (OCIDefine **)&defp, errhp, (ub4)2, /* position */ (void *)name, /* valuep */ (sb4)30, /* value_sz */ (ub2)SQLT_STR, /* dty */ (void *)&ind_name, /* indp */ (ub2 *)&alen_name, /* alenp */ (ub2 *)&rcode_name, /* column return code pointer */ (ub4)OCI_DEFAULT) /* mode */ ) < 0) return (-1); /*定義第三個字段ADDR的輸出變量 */ if (check_oci_error(errhp, OCIDefineByPos((OCIStmt *)smthp, (OCIDefine **)&defp, errhp, (ub4)3, /* position */ (void *)addr, /* valuep */ (sb4)200, /* value_sz */ (ub2)SQLT_STR, /* dty */ (void *)&ind_addr, /* indp */ (ub2 *)&alen_addr, /* alenp */ (ub2 *)&rcode_addr, /* column return code pointer */ (ub4)OCI_DEFAULT) /* mode */ ) < 0) return (-1); /* 執行OCI語句,注意在查詢語句執行時,iters要設置為0 */ if (check_oci_error(errhp, OCIStmtExecute(svchp, smthp, /* stmthp */ errhp, /* errhp */ 0, /* iters */ 0, /* rowoff */ NULL, /* snap_in */ NULL, /* snap_out */ OCI_DEFAULT) /* mode */ ) < 0) return (-1); while (1) { if ((rc = check_oci_error(errhp, OCIStmtFetch(smthp, errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT))) < 0) return (-1); /* 返回的結果集中沒有數據了,退出循環 */ if (rc == OCI_NO_DATA) break; if (ind_id == -1) sprintf(id_str, "NULL"); else sprintf(id_str, "%d", id); if (ind_name == -1) sprintf(name, "NULL"); if (ind_addr == -1) sprintf(addr, "NULL"); fprintf(stdout, "ID=%s, NAME=%s, ADDR=%s\n", id_str, name, addr); } return (0); }
如果查詢語句中有WHERE條件,那么條件字段會用占位符表示,通過綁定函數來關聯占位符和條件變量值。比如查詢ID=1的數據,那么OCI程序中的語句文本為SELECT ID, NAME, ADDR FROM test_tab WHERE ID=:1。占位符:1通過OCIBindByPos()函數來綁定數值。

浙公網安備 33010602011771號