知識點:通過ODBC操作Orcale數據庫的說明

本文通過ODBC方式連接Oracle數據庫,使用MFC進行數據庫操作的關鍵函數。詳細介紹了配置ODBC的方法和其中遇到的各項困難,以及最終幾個的關鍵函數。

1. ODBC數據源連接數據庫方式

1.1 使用odbc數據源的好處

  • 客戶端無需知道數據庫所在的IP地址。只要在數據庫中配置好監聽,客戶端配置好文件tnsnames.ora。客戶端電腦中的程序即可通過數據源直接訪問Orcale數據庫口程序的開發人員只需調用ODBC相關的函數即可實現通信。
  • 在系統中直接配置監聽TNS、用戶名UID、密碼PSW,可以避免數據庫密碼等信息維護,客戶端電腦上接口程序的修改,程序開發人員也不需要知道密碼。
  • 一個數據庫可以配置多個ns。

1.2 客戶端安裝orcale的驅動

爲了方便,我們將Oracle數據庫所在電腦稱作服務器,將配置ODBC的電腦稱作客戶端。需要注意的是隻有客戶端需要在windows系統中配置odbc數據源,服務器只需要在Oracle數據庫內部配置好監聽即可,不需要配置odbc數據源。現在假設Oracle數據庫服務器配置的服務命名orcl,如下圖所示。
在這裏插入圖片描述
​​首先要明確Oracle_ODBC驅動有32位和64位之分。理論上講,客戶端電腦安裝的的驅動一定要和服務器安裝的Orcale數據庫的位數一致。如果不一致會出現 “在指定的DSN中,驅動程序和應用程序之間的體系結構不匹配” 的問題。
Microsoft 會默認自帶一個 32位Oracle ODBC的ODBC驅動文件,但是我們在這個驅動文件上創建數據源的話會報錯 一般會提示 “未發現Oracle™客戶端和網絡組件。”的錯誤。我們需要這樣的情況下我們要重新下載安裝手動配置32位ODBC數據驅動。

  • (1) 首先把我提供的instantclient_12_1 (Orcale_ODBC驅動)文件放在 C:\ProgramFiles 目錄下。
  • (2) 用記事本打開“C:\ProgramFiles\instantclient_12_1\network\ADMIN\tnsnames.ora”文件將主機名"HOST"填寫你要連接的IP地址(這條是針對客戶端的電腦,服務器側的電腦不用動),其它不用動。
    在這裏插入圖片描述
  • (3) 添加環境變量(右鍵單擊我的電腦—屬性—高級選項卡—環境變量)TNS_ADMIN,變量值指向ADMIN目錄,我的配置是c:\Program Files\instantclient_12_1\NETWORK\ADMIN;新建的變量名填寫TNS_ADMIN 變量值填寫c:\Program Files\instantclient_12_1\NETWORK\ADMIN
    在這裏插入圖片描述
  • (4) 雙擊instantclient_12_1目錄下的odbc_install.exe完成安裝。注:安裝時出現DOC框,並一閃而過,你可能無法判斷是不是正確安裝。其實你可以cmd進入instantclient_12_1目錄,並.\odbc_install.exe手動安裝。
    instantclient_12_1的下載地址如下:
    32位Oracle ODBC驅動安裝包及安裝教程地址:https://download.csdn.net/download/dashumak/10421614 (壓縮包中是xp下的安裝方法,win7下的安裝方法見 本文)
    64位Oracle ODBC驅動安裝包地址(安裝方式很簡單,找到odbc_install.exe右鍵管理員方式運行即可):https://download.csdn.net/download/dashumak/10421608
  • 這兩個都是在沒有安裝過Oracle的電腦上安裝的驅動,如果安裝過Oracle的電腦是有相應的驅動的,但是也要檢查一下驅動的版本(好像32位的Oracle裝的是32位的驅動,64位的甲骨文裝的是64位的驅動)。

1.3 Win7電腦配置ODBC數據源管理器

通過“運行”進入32位或者64位ODBC數據源管理器的方法是如下(這裏文件夾名和軟件的位數擰着呢,不知爲什麼):

  • 64位: C:\windows\system32\odbcad32.exe
  • 32位: C:\Windows\SysWOW64\odbcad32.exe
    客戶端需要配置ODBC數據源,配置界面如下圖所示。
    在這裏插入圖片描述
    各項參數說明如下(這裏的代碼是後續提到的CDatabase::OpenEx中的參數):
  • Data Source Name(即是代碼中用到的DSN),取值是客戶端自行設定。
  • Description只是一個描述,取值無所謂,可不做任何配置
  • ODBC中的User ID(即是代碼中的UID),取值是由Oracle數據庫配置,本次配置是sms。
  • TNS Service Name要(即是代碼中的DBQ),是由客戶端所在電腦tnsnames.ora配置文件中確定的,通過查詢下圖所示的文件,我們可以發現ORCLA和ORCLCYJ均與數據庫的orcl綁定,因此客戶端配置ODBC數據源中的TNS Service Name位ORCLA和ORCLCYJ均可。tnsnames.ora文件一般在orcale驅動的位置,如E:\app\dgax\product\11.2.0\client_1\network\admin。
    在這裏插入圖片描述

然後點擊測試,輸入數據庫配置好的對應UID的密碼,出現下圖表明連接成功
在這裏插入圖片描述

1.4 Xp電腦配置ODBC數據庫源管理器

配置方法:開始菜單>>ODBC,截圖如下
在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

1.4 解決MySQl(或者ODBC測試時)出現”no lisnter“問題

首先在運行中輸入services.msc進入服務,啓動OracleOraDb11g_home1TNSListener服務(右鍵屬性選擇自動方式,這樣每次重啓後會自動打開,但是因爲防火牆這個服務不是每次都能自動打開)。
在這裏插入圖片描述
啓動完後,刷新一下,可能出現服務啓動後又自動關閉的問題,這是由於數據庫配置監聽文件的問題,需要修改”listener.ora“文件。比如我的lisnter.ora文件所在路徑是“C:\Oracle\product\11.2.0\dbhome_1\NETWORK\ADMIN”,不用管那些bak文件。
在這裏插入圖片描述

右鍵記事本打開(最好先備份一下),檢查這個問題是不是有問題,往往是HOST不對,HOST應該與計算機的名稱一致,修改後保存,重新到services.msc中啓動“OracleOraDb11g_home1TNSListener”服務,這樣應該就可以啓動了。至於”listener.ora“文檔中記錄的各種文件地址,對一般監聽影響不大,倘若修改完之後上述服務扔是啓動之後仍是立刻自動關閉,就應該回到這個文檔中,講文件地址檢查一遍,修改爲正確的地址。
在這裏插入圖片描述
在這裏插入圖片描述
這樣問題就解決了,可以到cmd中輸入lsnrctl命令
在這裏插入圖片描述
輸入status,查看數據庫監聽狀態,出現下圖表示監聽成功
在這裏插入圖片描述


2. MFC藉助ODBC操作數據庫

2.1 利用CDatabase::OpenEx打開數據庫連接

CDatabase db_Smartfuel;
BOOL bOpenDbSucc=FALSE;
try{
	db_Smartfuel.OpenEx(_T("DSN=orcl;UID=sms;PWD=123321;DBQ=ORCLCYJ ;DBA=W;APA=T;EXC=F;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;BTD=F;BNF=F;BAM=IfAllSuccessful;NUM=NLS;DPM=F;MTS=T;MDI=F;CSR=F;FWC=F;FBS=64000;TLO=O;MLD=0;ODA=F;"),CDatabase::noOdbcDialog);
	}
catch(CDBException*e){
		AfxMessageBox(e->m_strError);//彈窗顯示錯誤信息
		e->delete();
	}

CDatabase::OpenEx()msdn官方說明,這裏我簡要介紹一下參數。

  • 第一個參數是一個含有連接關係的字符串,要參照ODBC配置填入相關參數,
    • (1)DSN和Data Source Name取值一致
    • (2)User ID要和代碼中的UID保持一致
    • (3)TNS Service Name要和代碼中的DBQ取值對應一致,
  • 第二個參數 CDatabase::noOdbcDialog表示無彈窗提示

2.2 利用CRecordset::m_strFilter進行數據篩選

CRecordset類有兩個公共數據成員m_strFilter和m_strSort用來設置對記錄的過濾和排序。在調用Open或Requery前,如果在這兩個數據成員中指定了過濾或排序,那麼Open和Requery將按這兩個數據成員指定的過濾和排序來查詢數據源。
成員m_strFilter用於指定過濾器.m_strFilter實際上包含了SQL的WHERE子句的內容,但它不含WHERE關鍵字.使用m_strFilter的一個例子爲:

BOOL CSMST_BSAMPLE::SearchRecord(CString value1,CString value2){
//搜索stopflag=value1,newflag=value2。結果爲空時,BOOL CSMST_BSAMPLE::SearchRecord返回結果爲0
	m_strFilter = L"stopflag= '" + value1 + L"' and newflag = '" + value2 +L"'";
	Requery();
	m_strFilter=L"";
	return !IsEOF();
}

成員m_strSort用於指定排序.m_strSort實際上包含了ORDERBY子句的內容,但它不含ORDER BY關鍵字.m_strSort的一個例子爲

m_pSet->m_strSort=“CourseIDDESC”; //按CourseID的降序排列記錄
m_pSet->Open();

事實上,Open函數在構造SELECT語句時,會把m_strFilter和m_strSort的內容放入SELECT語句的WHERE和ORDERBY子句中.如果在Open的lpszSQL參數中已包括了WHERE和ORDERBY子句,那麼m_strFilter和m_strSort必需爲空。
調用無參數成員函數Close可以關閉記錄集.在調用了Close函數後,程序可以再次調用Open建立新的記錄集.CRecordset的析構函數會調用Close函數,所以當刪除CRecordset對象時記錄集也隨之關閉。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章