C++ 連接oracle數據庫


 http://41062947.iteye.com/blog/2040784

 

方式1,使用OCCI:

直接上代碼

#include <iostream>
#include <string>
#include <vector>
#include <occi.h>

using namespace oracle::occi;
using std::vector;
using namespace std;

class conndba
{
	private:

		Environment *env;

		Connection *conn;

		Statement *stmt;

	public:

		conndba(string user, string password, string db)

		{

			env = Environment::createEnvironment(Environment::DEFAULT);

			conn = env->createConnection(user, password, db);

		}

		~conndba()

		{

			env->terminateConnection(conn);

			Environment::terminateEnvironment(env);

		}

		void insertBind(string s1, string s2, string s3, string s4)
		{

			string sqlStmt = "INSERT INTO t_user(userid, username, loginname, createdate) VALUES (:1, :2, :3, :4)";  

			stmt=conn->createStatement (sqlStmt);

			try
			{

				stmt->setString(1, s1);

				stmt->setString(2, s2);

				stmt->setString(3, s3);

				stmt->setString(4, s4);

				stmt->executeUpdate();

				cout << "insert - Success" << endl;

			}
			catch (SQLException ex)

			{

				cout << "Exception thrown for insertBind" << endl;
				cout << "Error number: " << ex.getErrorCode() << endl;
				cout << ex.getMessage() << endl;
			}
			conn->terminateStatement(stmt);
		}
		void updateRow(string s1, string s2)
		{
			string sqlStmt = "UPDATE t_user SET userid = :x WHERE username = :y";
			stmt = conn->createStatement(sqlStmt);
			try
			{
				stmt->setString(1, s2);
				stmt->setString(2, s1);
				stmt->executeUpdate();
				cout << "update - Success" << endl;
			}
			catch (SQLException ex)
			{
				cout << "Exception thrown for updateRow" << endl;
				cout << "Error number: " << ex.getErrorCode() << endl;
				cout << ex.getMessage() << endl;
			}
			conn->terminateStatement(stmt);
		}
		void deleteRow(string s1)
		{
			string sqlStmt = "DELETE FROM t_user WHERE userid = :x";
			stmt = conn->createStatement(sqlStmt);
			try
			{
				stmt->setString(1, s1);
				stmt->executeUpdate();
				cout << "delete - Success" << endl;
			}
			catch (SQLException ex)
			{
				cout << "Exception thrown for deleteRow" << endl;
				cout << "Error number: " << ex.getErrorCode() << endl;
				cout << ex.getMessage() << endl;
			}
			conn->terminateStatement(stmt);
		}
		void displayAllRows()
		{
			string sql =
					"select userid, username, loginname, createdate from t_user";
			stmt = conn->createStatement(sql);
			ResultSet *rs = stmt->executeQuery();
			try
			{
				while (rs->next())
				{
					cout << "userid: " << rs->getInt(1) << "\t"
					cout << "username: " << rs->getString(2) << "\t"
					cout << "loginname: " << rs->getString(3) << "\t"
					cout << "createdate: " << rs->getString(4) << endl;
				}
			}
			catch (SQLException ex)
			{
				cout << "Exception thrown for displayAllRows" << endl;
				cout << "Error number: " << ex.getErrorCode() << endl;
				cout << ex.getMessage() << endl;
			}
			stmt->closeResultSet(rs);
			conn->terminateStatement(stmt);
		}
		void displayAllRowsDesc()
		{
			string sql =
					"select userid, username, loginname, createdate from t_user order by userid desc";
			stmt = conn->createStatement(sql);
			ResultSet *rs = stmt->executeQuery();
			try
			{
				while (rs->next())
				{
					cout << "userid: " << rs->getInt(1) << "\t"
					cout << "username: " << rs->getString(2) << "\t"
					cout << "loginname: " << rs->getString(3) << "\t"
					cout << "createdate: " << rs->getString(4) << endl;
				}
			}
			catch (SQLException ex)
			{
				cout << "Exception thrown for displayAllRows" << endl;
				cout << "Error number: " << ex.getErrorCode() << endl;
				cout << ex.getMessage() << endl;
			}
			stmt->closeResultSet(rs);
			conn->terminateStatement(stmt);
		}
};
int main(int argc, char *argv[])
{
	string user = "UOP_ACT4";
	string password = "123456";
	string db = "hyacttst";
	conndba *demo = new conndba(user, password, db);
	cout << "數據庫中的記錄:" << endl;
	demo->displayAllRowsDesc();
	cout << "刪除指定id的用戶信息!" << endl;
	cout << "請輸入需要刪除的用戶id:" << argv[1] << endl;
	demo->deleteRow(argv[1]);
	cout << "刪除指定id的用戶信息后!" << endl;
	demo->displayAllRows();
	cout << "調用析構函數進行處理!";
	delete (demo);
}

  方式2:使用OCI,我們項目中正在使用的方式,看起來及其復雜。

  1 #include <oci.h>
  2 
  3 #include <iostream>
  4 
  5 #include <string>
  6 
  7 #include <string.h>
  8 
  9 #include <stdlib.h>
 10 
 11 using namespace std;
 12 
 13 //存放查詢數據的結構體
 14 
 15 struct result
 16 
 17 {
 18 
 19         char ename[20];
 20 
 21         char cname[20];
 22 
 23         result()
 24 
 25         {
 26 
 27             memset(ename, '\0', sizeof(ename));
 28 
 29             memset(cname, '\0', sizeof(cname));
 30 
 31         }
 32 
 33 };
 34 
 35 int main()
 36 
 37 {
 38 
 39     // 初始化 OCI 環境句柄指針
 40 
 41     OCIEnv *envhpp = NULL;
 42 
 43     // 初始化服務器句柄
 44 
 45     OCIServer *servhpp = NULL;
 46 
 47     // 用於捕獲 OCI 錯誤信息
 48 
 49     OCIError *errhpp = NULL;
 50 
 51     // 初始化會話句柄
 52 
 53     OCISession *usrhpp = NULL;
 54 
 55     // 初始化服務上下文句柄
 56 
 57     OCISvcCtx *svchpp = NULL;
 58 
 59     // 初始化表達式句柄
 60 
 61     OCIStmt *stmthpp = NULL;
 62 
 63     string server = "mydb";
 64 
 65     // 創建 OCI 環境 , 並設置環境句柄。
 66 
 67     sword swResult = OCIEnvCreate(&envhpp, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL);
 68 
 69     if (swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO)
 70 
 71     {
 72 
 73         cout 《 "Oracle environment initialization error!" 《 endl;
 74 
 75         exit(1);
 76 
 77     }
 78 
 79     cout 《 "Oracle environment initialization success!" 《 endl;
 80 
 81     // 創建錯誤句柄
 82 
 83     OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
 84 
 85     // 創建服務句柄
 86 
 87     OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&servhpp, OCI_HTYPE_SERVER, (size_t)0, (dvoid **)0);
 88 
 89     // 連接服務器,如果失敗則獲取錯誤碼
 90 
 91     if (OCIServerAttach(servhpp, errhpp, (text *)server.c_str(), strlen(server.c_str()), 0) != OCI_SUCCESS)
 92 
 93     {
 94 
 95         int errcno;
 96 
 97         char errbuf[512] = "";
 98 
 99         sb4 errcode;
100 
101         // 獲取錯誤指針和 OCI 錯誤代碼
102 
103         OCIErrorGet((dvoid *)errhpp, (ub4)1, (text *)NULL, &errcode, (ub1 *)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
104 
105         errcno = errcode;
106 
107         cout 《 "Oracle server attach error:" 《 errbuf 《 endl;
108 
109         OCIHandleFree((dvoid *)envhpp,OCI_HTYPE_ENV);
110 
111         OCIHandleFree((dvoid *)servhpp,OCI_HTYPE_SERVER);
112 
113         OCIHandleFree((dvoid *)errhpp,OCI_HTYPE_ERROR);
114 
115         exit(1);
116 
117     }
118 
119     cout 《 "Oracle server attach success!"《 endl;
120 
121     /***************** 連接數據庫 ****************/
122 
123     string user = "user";
124 
125     string pas = "passwd";
126 
127     errhpp = NULL;
128 
129     // 創建錯誤句柄
130 
131void) OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
132 
133     // 創建服務上下文句柄
134 
135void) OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&svchpp, OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **)0);
136 
137     // 設置屬性
138 
139void) OCIAttrSet((dvoid *)svchpp, OCI_HTYPE_SVCCTX, (dvoid *)servhpp, (ub4)0, OCI_ATTR_SERVER, (OCIError *)errhpp);
140 
141     // 創建用戶連接句柄
142 
143void) OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&usrhpp, (ub4)OCI_HTYPE_SESSION, (size_t) 0, (dvoid **)0);
144 
145     // 設置用戶名、密碼
146 
147void) OCIAttrSet((dvoid *)usrhpp, (ub4)OCI_HTYPE_SESSION, (dvoid *)user.c_str(), (ub4)strlen(user.c_str()), (ub4)OCI_ATTR_USERNAME, errhpp);
148 
149void) OCIAttrSet((dvoid *)usrhpp, (ub4)OCI_HTYPE_SESSION, (dvoid *)pas.c_str(), (ub4)strlen(pas.c_str()), (ub4)OCI_ATTR_PASSWORD, errhpp);
150 
151     // 創建會話連接
152 
153     if(OCISessionBegin(svchpp, errhpp, usrhpp, OCI_CRED_RDBMS, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
154 
155     {
156 
157         int errcno;
158 
159         char errbuf[512]=
160         {    '\0'};
161 
162         sb4 errcode;
163 
164         // 獲取錯誤指針和 OCI 錯誤代碼
165 
166         OCIErrorGet((dvoid *)errhpp, (ub4)1, (text *)NULL, &errcode, (ub1 *)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
167 
168         errcno = errcode;
169 
170         cout 《 "User session error:" 《 errbuf 《 endl;
171 
172         OCIHandleFree((dvoid *)errhpp,OCI_HTYPE_ERROR);
173 
174         OCIHandleFree((dvoid *)usrhpp,OCI_HTYPE_SESSION);
175 
176         OCIHandleFree((dvoid *)svchpp,OCI_HTYPE_SVCCTX);
177 
178         exit(1);
179 
180     }
181 
182     cout 《 "user session success!" 《 endl;
183 
184void) OCIAttrSet((dvoid *)svchpp, (ub4) OCI_HTYPE_SVCCTX, (dvoid *)usrhpp, (ub4)0, (ub4)OCI_ATTR_SESSION, errhpp);
185 
186     /***********************以上代碼已經成建立了一條數據庫連接************************/
187     
188     /*************** 以下代碼是對數據庫的各種操作     ***   執行 查詢SQL 語句 ******************/
189 
190     errhpp = NULL;
191 
192     // 創建一個表達式句柄
193 
194     if (OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&stmthpp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0) != OCI_SUCCESS)
195 
196     {
197 
198         cout 《 "Create STMT error !" 《 endl;
199 
200         exit(1);
201 
202     }
203 
204     cout 《 "Create stmt success !" 《 endl;
205 
206     // 創建錯誤句柄
207 
208     OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
209 
210     // Select語句
211 
212     char sql[255] = "select col1, col2 from table1 ";
213 
214     if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql, (ub4)strlen(sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
215 
216     {
217 
218         cout 《 "Create prepare error!" 《 sql 《 endl;
219 
220         exit(1);
221 
222     }
223 
224     cout 《 "Create prepare success!" 《 endl;
225 
226     /********* 綁定參數 ***********/
227 
228     // 申請綁定字段的句柄
229     OCIDefine *bhp1 = NULL;
230 
231     OCIDefine *bhp2 = NULL;
232 
233     // 存放數據的結構
234 
235     struct result rst;
236 
237     // 指定提取數據長度
238 
239     ub2 datalen = 0;
240 
241     // 定義指示器變量 , 用於取可能存在空值的字段
242 
243     char isnul[6] = "";
244 
245     // 定義輸出變量 ,
246 
247     OCIDefineByPos(stmthpp, &bhp1, errhpp, 1, (dvoid *)&rst.ename, sizeof(rst.ename), SQLT_CHR, NULL, &datalen, NULL, OCI_DEFAULT);
248 
249     OCIDefineByPos(stmthpp, &bhp2, errhpp, 2, (dvoid *)&rst.cname, sizeof(rst.cname), SQLT_STR, NULL, &datalen, NULL, OCI_DEFAULT);
250 
251     // 獲取 SQL 語句類型
252 
253     ub2 stmt_type;
254 
255     OCIAttrGet ((dvoid *)stmthpp, (ub4)OCI_HTYPE_STMT, (dvoid *)&stmt_type, (ub4 *)0, (ub4)OCI_ATTR_STMT_TYPE, errhpp);
256 
257     // 執行 SQL 語句
258 
259     OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT);
260 
261     // 獲取查詢信息
262 
263     int rows_fetched;
264 
265     do
266 
267     {
268 
269         cerr 《 rst.ename《 " ";
270 
271         cerr 《 rst.cname《 " \n";
272 
273     }
274 
275     while(OCIStmtFetch2(stmthpp, errhpp, 1, OCI_FETCH_NEXT, 1, OCI_DEFAULT) != OCI_NO_DATA);
276 
277     // 獲得記錄條數
278 
279     OCIAttrGet((CONST void *)stmthpp, OCI_HTYPE_STMT, (void *)&rows_fetched, (ub4 *)sizeof(rows_fetched), OCI_ATTR_ROW_COUNT, errhpp);
280 
281     cout 《 " rows :" 《 rows_fetched 《 endl;
282 
283     /*************** 執行 新增SQL 語句 ******************/
284 
285     if (OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&stmthpp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0) != OCI_SUCCESS)
286 
287     {
288 
289         cout 《 "Create STMT error !" 《 endl;
290 
291         exit(1);
292 
293     }
294 
295     cout 《 "Create stmt success !" 《 endl;
296 
297     OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
298 
299     // Insert語句
300 
301     char sql2[255] = "insert into table1 (col1, col2) values('testoci', 'testoci')";
302 
303     // 准備Sql語句
304 
305     if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql2, (ub4)strlen(sql2), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
306 
307     {
308 
309         cout 《 "Create prepare error!" 《 sql2 《 endl;
310 
311         exit(1);
312 
313     }
314 
315     cout 《 "Create prepare success!" 《 endl;
316 
317     // 執行SQL 語句
318 
319     OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)1, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT);
320 
321     // 斷開用戶會話
322 
323     OCILogoff(svchpp, errhpp);
324 
325     // 斷開服務器連接
326 
327     OCIServerDetach(servhpp, errhpp, OCI_DEFAULT);
328 
329     // 釋放資源
330 
331     OCIHandleFree((dvoid *) stmthpp, OCI_HTYPE_STMT);
332 
333     OCIHandleFree((dvoid *) svchpp, OCI_HTYPE_SVCCTX);
334 
335     OCIHandleFree((dvoid *) servhpp, OCI_HTYPE_SERVER);
336 
337     OCIHandleFree((dvoid *) errhpp, OCI_HTYPE_ERROR);
338 
339     return 0;
340 
341 }

沒有編譯驗證, 如果有錯請看的童鞋多多包含。

 

明顯OCCI是OCI的進階版,個人認為,在硬件不是制約條件的今天,OCCI和OCI的執行效率不差上下,但是從程序員的調用方便來講,明顯OCCI要方便的多,如果以后的項目還要用到的話,本人會毫不猶豫的選擇OCCI。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM