OCI介面學習筆記--基本理解(二)
一. Oracle oci工具包安裝:
$ORACLE_HOME\BIN:執行檔案和help檔案
$ORACLE_HOME\OCI\INCLUDE:標頭檔案
$ORACLE_HOME\OCI\LIB\BC: for Borlanf C++的OCI庫
$ORACLE_HOME\OCI\LIB\MSVC: for MS Visual C++的CI庫
如果是unix下,對於ORACLE8i,則OCI庫在$ORACLE_HOME/lib下,如果是9i,則在$ORACLE_HOME/lib32下,庫檔名一般為libclntsh.so
二、一個資料庫OCI操作一般流程
- 初始化OCI環境
- 申請控制程式碼
- 連線資料庫
- 建立會話
- 執行SQL操作(在這個過程中包括:(1)準備SQL語句。(2)在SQL語句中繫結需要輸入到SQL語句中的變數。(3)執行SQL語句。(4)獲取SQL中的輸出描述。(5)定義輸出變數。(6)獲取資料)
- 斷開會話
- 斷開伺服器
- 釋放資源
三、例項分析
先通過一段較為簡單的程式碼大致理解一下OCI程式設計:
- #include <oci.h>
- #include <iostream>
- #include <string>
- #include <string.h>
- #include <stdlib.h>
- using namespace std;
- //存放查詢資料的結構體
- struct result
- {
- char ename[20];
- char cname[20];
- result()
- {
- memset(ename,
'\0', sizeof(ename));
- memset(cname,
'\0', sizeof(cname));
- }
- };
- int main()
- {
- // 初始化 OCI 環境控制程式碼指標
- OCIEnv *envhpp
= NULL;
- // 初始化伺服器控制程式碼
- OCIServer *servhpp
= NULL;
- // 用於捕獲 OCI 錯誤資訊
- OCIError *errhpp
= NULL;
- // 初始化會話控制程式碼
- OCISession *usrhpp
= NULL;
- // 初始化服務上下文控制程式碼
- OCISvcCtx *svchpp
= NULL;
- // 初始化表示式控制程式碼
- OCIStmt *stmthpp
= NULL;
- string server="mydb";
- // 建立 OCI 環境
, 並設定環境控制程式碼。
- sword swResult = OCIEnvCreate(&envhpp, OCI_DEFAULT,
NULL,
NULL, NULL,
NULL, 0,
NULL);
- if (swResult
!= OCI_SUCCESS
&& swResult != OCI_SUCCESS_WITH_INFO)
- {
- cout <<
"Oracle environment initialization error!"
<< endl;
- exit(1);
- }
- cout <<
"Oracle environment initialization success!"
<< endl;
- // 建立錯誤控制程式碼
- OCIHandleAlloc((dvoid
*)envhpp,
(dvoid **)&errhpp, OCI_HTYPE_ERROR,
(size_t)0,
(dvoid **)0);
- // 建立服務控制程式碼
- OCIHandleAlloc((dvoid
*)envhpp,
(dvoid **)&servhpp, OCI_HTYPE_SERVER,
(size_t)0,
(dvoid **)0);
- // 連線伺服器,如果失敗則獲取錯誤碼
- if (OCIServerAttach(servhpp, errhpp,
(text *)server.c_str(), strlen(server.c_str()),
0) != OCI_SUCCESS)
- {
- int errcno;
- char errbuf[512]
= "";
- sb4 errcode;
- // 獲取錯誤指標和 OCI 錯誤程式碼
- OCIErrorGet((dvoid
*)errhpp,
(ub4)1,
(text *)NULL,
&errcode,
(ub1 *)errbuf,
(ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
- errcno = errcode;
- cout <<
"Oracle server attach error:"
<< errbuf << endl;
- OCIHandleFree((dvoid
*)envhpp,OCI_HTYPE_ENV);
- OCIHandleFree((dvoid
*)servhpp,OCI_HTYPE_SERVER);
- OCIHandleFree((dvoid
*)errhpp,OCI_HTYPE_ERROR);
- exit(1);
- }
- cout <<
"Oracle server attach success!"<< endl;
- /*****************
連線資料庫 ****************/
- string user =
"user";
- string pas =
"passwd";
- errhpp = NULL;
- // 建立錯誤控制程式碼
- (void) OCIHandleAlloc((dvoid
*)envhpp,
(dvoid **)&errhpp, OCI_HTYPE_ERROR,
(size_t)0,
(dvoid **)0);
- // 建立服務上下文控制程式碼
- (void) OCIHandleAlloc((dvoid
*)envhpp,
(dvoid **)&svchpp, OCI_HTYPE_SVCCTX,
(size_t) 0,
(dvoid **)0);
- // 設定屬性
- (void) OCIAttrSet((dvoid
*)svchpp, OCI_HTYPE_SVCCTX,
(dvoid *)servhpp,
(ub4)0, OCI_ATTR_SERVER,
(OCIError *)errhpp);
- // 建立使用者連線控制程式碼
- (void) OCIHandleAlloc((dvoid
*)envhpp,
(dvoid **)&usrhpp,
(ub4)OCI_HTYPE_SESSION,
(size_t) 0,
(dvoid **)0);
- // 設定使用者名稱、密碼
- (void) OCIAttrSet((dvoid
*)usrhpp,
(ub4)OCI_HTYPE_SESSION,
(dvoid *)user.c_str(),
(ub4)strlen(user.c_str()),
(ub4)OCI_ATTR_USERNAME, errhpp);
- (void) OCIAttrSet((dvoid
*)usrhpp,
(ub4)OCI_HTYPE_SESSION,
(dvoid *)pas.c_str(),
(ub4)strlen(pas.c_str()),
(ub4)OCI_ATTR_PASSWORD, errhpp);
- // 建立會話連線
- if(OCISessionBegin(svchpp, errhpp, usrhpp, OCI_CRED_RDBMS,
(ub4)OCI_DEFAULT)
!= OCI_SUCCESS)
- {
- int errcno;
- char errbuf[512]={'\0'};
- sb4 errcode;
-
- // 獲取錯誤指標和 OCI 錯誤程式碼
- OCIErrorGet((dvoid
*)errhpp,
(ub4)1,
(text *)NULL,
&errcode,
(ub1 *)errbuf,
(ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
- errcno = errcode;
- cout <<
"User session error:"
<< errbuf << endl;
- OCIHandleFree((dvoid
*)errhpp,OCI_HTYPE_ERROR);
- OCIHandleFree((dvoid
*)usrhpp,OCI_HTYPE_SESSION);
- OCIHandleFree((dvoid
*)svchpp,OCI_HTYPE_SVCCTX);
- exit(1);
- }
- cout <<
"user session success!"
<< endl;
-
- (void) OCIAttrSet((dvoid
*)svchpp,
(ub4) OCI_HTYPE_SVCCTX,
(dvoid *)usrhpp,
(ub4)0,
(ub4)OCI_ATTR_SESSION, errhpp);
- /***************
執行 查詢SQL 語句 ******************/
- errhpp = NULL;
- // 建立一個表示式控制程式碼
- if (OCIHandleAlloc((dvoid
*)envhpp,
(dvoid **)&stmthpp, OCI_HTYPE_STMT,
(size_t)0,
(dvoid **)0)
!= OCI_SUCCESS)
- {
- cout <<
"Create STMT error !"
<< endl;
- exit(1);
- }
- cout <<
"Create stmt success !"
<< endl;
-
- // 建立錯誤控制程式碼
- OCIHandleAlloc((dvoid
*)envhpp,
(dvoid **)&errhpp, OCI_HTYPE_ERROR,
(size_t)0,
(dvoid **)0);
-
- // Select語句
- char sql[255]
= "select col1, col2 from table1 ";
-
- if (OCIStmtPrepare(stmthpp, errhpp,
(text *)sql,
(ub4)strlen(sql),
(ub4)OCI_NTV_SYNTAX,
(ub4)OCI_DEFAULT)
!= OCI_SUCCESS)
- {
- cout <<
"Create prepare error!"
<< sql << endl;
- exit(1);
- }
- cout <<
"Create prepare success!"
<< endl;
- /*********
繫結引數 ***********/
- // 申請繫結欄位的控制程式碼
- OCIDefine *bhp1
= NULL;
- OCIDefine *bhp2
= NULL;
-
- // 存放資料的結構
- struct result rst;
-
- // 指定提取資料長度
- ub2 datalen = 0;
- // 定義指示器變數
, 用於取可能存在空值的欄位
- char isnul[6]
= "";
- // 定義輸出變數
,
- OCIDefineByPos(stmthpp,
&bhp1, errhpp, 1,
(dvoid *)&rst.ename, sizeof(rst.ename),
SQLT_CHR, NULL,
&datalen,
NULL, OCI_DEFAULT);
- OCIDefineByPos(stmthpp,
&bhp2, errhpp, 2,
(dvoid *)&rst.cname, sizeof(rst.cname),
SQLT_STR, NULL,
&datalen,
NULL, OCI_DEFAULT);
- // 獲取 SQL 語句型別
- ub2 stmt_type;
- OCIAttrGet ((dvoid
*)stmthpp,
(ub4)OCI_HTYPE_STMT,
(dvoid *)&stmt_type,
(ub4 *)0,
(ub4)OCI_ATTR_STMT_TYPE, errhpp);
-
- // 執行 SQL 語句
- OCIStmtExecute(svchpp, stmthpp, errhpp,
(ub4)0,
(ub4)0,
(OCISnapshot *)NULL,
(OCISnapshot *)NULL, OCI_DEFAULT);
- // 獲取查詢資訊
- int rows_fetched;
- do
- {
- cerr << rst.ename<<
" ";
- cerr << rst.cname<<
" \n";
- }
- while(OCIStmtFetch2(stmthpp, errhpp, 1, OCI_FETCH_NEXT,
1, OCI_DEFAULT)
!= OCI_NO_DATA);
- // 獲得記錄條數
- OCIAttrGet((CONST void
*)stmthpp, OCI_HTYPE_STMT,
(void *)&rows_fetched,
(ub4 *)sizeof(rows_fetched), OCI_ATTR_ROW_COUNT,
errhpp);
- cout <<
" rows :" << rows_fetched
<< endl;
- /***************
執行 新增SQL 語句 ******************/
- if (OCIHandleAlloc((dvoid
*)envhpp,
(dvoid **)&stmthpp, OCI_HTYPE_STMT,
(size_t)0,
(dvoid **)0)
!= OCI_SUCCESS)
- {
- cout <<
"Create STMT error !"
<< endl;
- exit(1);
- }
- cout <<
"Create stmt success !"
<< endl;
- OCIHandleAlloc((dvoid
*)envhpp,
(dvoid **)&errhpp, OCI_HTYPE_ERROR,
(size_t)0,
(dvoid **)0);
- // Insert語句
- char sql2[255]
= "insert into table1 (col1, col2) values('testoci', 'testoci')";
-
- // 準備Sql語句
- if (OCIStmtPrepare(stmthpp, errhpp,
(text *)sql2,
(ub4)strlen(sql2),
(ub4)OCI_NTV_SYNTAX,
(ub4)OCI_DEFAULT)
!= OCI_SUCCESS)
- {
- cout <<
"Create prepare error!"
<< sql2 << endl;
- exit(1);
- }
- cout <<
"Create prepare success!"
<< endl;
-
- // 執行SQL 語句
- OCIStmtExecute(svchpp, stmthpp, errhpp,
(ub4)1,
(ub4)0,
(OCISnapshot *)NULL,
(OCISnapshot *)NULL, OCI_DEFAULT);
- // 斷開使用者會話
- OCILogoff(svchpp, errhpp);
-
- // 斷開伺服器連線
- OCIServerDetach(servhpp, errhpp, OCI_DEFAULT);
-
- // 釋放資源
- OCIHandleFree((dvoid
*) stmthpp, OCI_HTYPE_STMT);
- OCIHandleFree((dvoid
*) svchpp, OCI_HTYPE_SVCCTX);
- OCIHandleFree((dvoid
*) servhpp, OCI_HTYPE_SERVER);
- OCIHandleFree((dvoid
*) errhpp, OCI_HTYPE_ERROR);
- return 0;
- }
相關文章
- OCI學習筆記--簡介(一)筆記
- TS學習筆記(二):介面筆記
- Go 介面 學習筆記Go筆記
- MySQL學習筆記--基本操作MySql筆記
- ElasticSearch學習筆記(二)——對聚合的簡單理解Elasticsearch筆記
- batch normalization學習理解筆記BATORM筆記
- ANFIS學習筆記(二)筆記
- activiti學習筆記二筆記
- Typescript學習筆記(二)TypeScript筆記
- JavaScript學習筆記(二)JavaScript筆記
- React 學習筆記【二】React筆記
- goLang學習筆記(二)Golang筆記
- vue學習筆記二Vue筆記
- vue學習筆記(二)Vue筆記
- 科二學習筆記筆記
- jQuery 學習筆記(二)jQuery筆記
- git學習筆記(二)Git筆記
- Java學習筆記二Java筆記
- TS學習筆記(二)筆記
- JavaScript學習筆記---基本語法JavaScript筆記
- OpenGL學習筆記(12)基本光照筆記
- 機器學習學習筆記——基本知識機器學習筆記
- Java學習筆記記錄(二)Java筆記
- 高等數學學習筆記(二)筆記
- Vue學習筆記(二)------axios學習Vue筆記iOS
- python學習筆記(二)Python筆記
- TensorFlow學習筆記(二)筆記
- github--學習筆記(二)Github筆記
- orientDB學習筆記(二)MATCH筆記
- Hibernate學習筆記二筆記
- 智慧窗-學習筆記(二)筆記
- linux學習筆記二Linux筆記
- MySql 學習筆記二:索引MySql筆記索引
- MPAndroidChart學習筆記(二)Android筆記
- Tensorflow學習筆記二筆記
- jQuery學習系列筆記(二)jQuery筆記
- android學習筆記二Android筆記
- Spss 學習筆記(二)SPSS筆記