.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常

asword發表於2007-03-21
ZT[@more@]在.net平臺下訪問資料庫有以下幾種方式:
1、OleDB資料庫訪問程式,
2、ODBC資料庫訪問程式,
3、專有的資料庫訪問程式。如:訪問Sql Server 2000 時,我們一般喜歡使用專有的SQL Server .NET Framework 資料庫訪問程式。名稱空間為: System.Data.SqlClient 。

在這裡我使用第三種,也就是“專有的資料庫訪問程式”(Oracle .NET Framework 資料庫訪問程式)訪問Oracle資料庫

在1.1版本之前 Oracle .NET Framework需要另外下載,.net Framework本身並沒有這個元件。 下載地址:

在2.0版本的Framework中已經自帶了 Oracle .NET Framework 資料庫訪問程式。但並不是說有了Oracle .NET Framework 就可以順利訪問Oracle了。 要訪問Oracle資料庫,除了專有的資料庫訪問程式,還必須具備以下條件:

必須安裝 Oracle 8i Release 3 (8.1.7) 客戶端或更高版本。
以下分幾點談談Oracle資料庫訪問的細節

經常使用的一些元件
Oracle.NET Framework 資料庫訪問程式名稱空間為: System.Data.OracleClient. 檔名為:System.Data.OracleClient.dll , 位於全域性程式集快取中。預設情況下vs 2005沒有引用該元件,需要使用時,只需要新增引用即可。
與SqlClient 類似,OracleClient名稱空間下由 OracleConnection ,OracleCommand,OracleDataReader, OracleParameter ,OracleType等組成。以上列出的只是最常用的幾個類。更詳細的類檢視請參考MSDN.

欄位型別,引數型別
欄位型別一般在使用Parameter是會涉及到。 在Sql Server中我們一般使用SqlDbType 列舉表示資料庫中的各種欄位型別, 而在Oracle中,使用OracleType。 在Oracle中,字元型的欄位經常使用Varchar2 或 Nvarchar2, 而數值型用Number。 Varchar後面多了個2, 沒有深入學習Oracle,不知多加的這個“2" 的有什麼意義。 在使用引數(Parameter)時.
OracleType.Varchar 表示資料庫中的 varchar2,
OracleType.Nvarchar 表示資料庫中的 Nvarchar2,
OracleType.Number 表示 Number
OracleType.DateTime 表示 Date
至於其他的如:OracleType.Int32 由於在Oracle中沒有對應的欄位型別,一般使用較小,如果資料庫中的Number型欄位的值沒有小數位,也可以使用OracleType.Int32對應Number.

資料庫連線

與SqlConnection類似, 只是連線字串一般為:User ID=使用者名稱;Data Source=資料庫服源名稱(Oracel資料庫服務名稱);Password=密碼
下面是我使用的連線字串: User ID=search_user;Data Source=etbank_192.168.0.250;Password=12345

儲存過程的使用

Oracle中的儲存過程叫作包(Packages), 一個包分為 包頭和包體,類似於C++中的 類宣告。 包頭定義了儲存過程的名稱和引數 ,包體除了名稱和引數,還包儲存過程的所有語句。與SqlServer不同,Oracle中儲存過程一般寫成 Function , 而不是PROCEDURE。Oracle儲存過程並不直接返回記錄集,記錄集以遊標的形式透過引數返回。一個包(Packages可以包含多個儲存過程,使用儲存過程時採用“包名.儲存過程名”的方式,下面是一個典型的Oracle儲存過程,它位於 命稱為"Test"的包(Packages)中,它的使用方式應為:Test.GetList

.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 Function GetList(keywords In varchar2
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 ,p_info_list_Cursor out get_data_cur_type)
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
Return Number
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
As
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
Begin
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
open p_info_list_Cursor For
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
Select * from Test where Key=keywords
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常;
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
Return 0;
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
End;
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常

儲存過程只返回一個Number ,記錄集以 out 引數方式返回。 在.net中呼叫方式如下:

1.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 OracleConnection OracleConn = new OracleConnection(連線字串); 2.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 OracleCommand cmd = new OracleCommand("Test.GetList", OracleConn); 3.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 cmd.Parameters.AddRange( 4.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 new OracleParameter[] 5.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 { 6.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 new OracleParameter("keyWords", OracleType.VarChar), 7.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 new OracleParameter("ReturnValue", OracleType.Number, 0, ParameterDirection.ReturnValue, true, 0, 0, "",DataRowVersion.Default, Convert.DBNull), 8.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 new OracleParameter("p_info_list_Cursor", OracleType.Cursor, 2000, ParameterDirection.Output, true, 0, 0, "",DataRowVersion.Default, Convert.DBNull) 9.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 });10.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 cmd.Parameters[0].Value = '美女';11.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 cmd.Parameters[0].Direction = ParameterDirection.Input;12.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 cmd.CommandType = CommandType.StoredProcedure;13.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 OracleConn.Open()14.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 OracleDataReader rdr=cmd.ExecuteReader();15.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 //.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常其他程式碼16.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 OracleConn.Close();17.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常

OracleParameter中的 引數名一定要與儲存過程中的名稱一致,可以忽略大小寫。儲存過程定義了2個引數,一個KeyWords, 一個是out 型別的遊標:p_info_list_Cursor。 因為 Function有返回值,所以我們還需要增加一個名為“ReturnValue"的引數, 這個名稱是固定的。 記錄集透過 p_info_list_Cursor 返回。 引數配置完成以後,直接使用cmd的眾多Exec方法即可,雖然我們使用了一個Out 引數接受記錄集遊標,但這個引數不需要我們處理,OracleCommand 會自動處理它,我們只需要像以往使用SqlCommand一樣,得到DataReader,然後讀資料即可。

直接執行SQL語句
Sql 語句中使用":" 表示引數。
在Sql Server 中我們可以按以下方式使用SQL 語句: "Insert into Table (Field1,field2) values(@Value1,@Value2) ", 然後我們再New 幾個Paramter: new SqlParameter("@Value1",value)...
在查詢字串中使用@+字元 來描述引數,在SqlParameter中的引數名也要使用"@"符號。
而在Oracle中Sql 語句不能使用@符號, 以冒號":"代替. 如:

.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 string Sql = "Insert into SEARCH_HISTORY(KEYWORDS,PHONE,RESULT_ID,SEARCH_TIME) values(:KEYWORDS,:PHONE,:RESULT_ID,:SEARCH_TIME)";
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 OracleCommand cmd
= new OracleCommand(Sql, OracleConn);
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 cmd.Parameters.AddRange(
new OracleParameter[]{
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
new OracleParameter("KEYWORDS",OracleType.VarChar),
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
new OracleParameter("PHONE",OracleType.VarChar),
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
new OracleParameter("RESULT_ID",OracleType.Number),
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常
new OracleParameter("SEARCH_TIME",OracleType.DateTime)
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 }
);
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 cmd.Parameters[
0].Value = Keywords;
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 cmd.Parameters[
1].Value = Phone;
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 cmd.Parameters[
2].Value=2;
.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 cmd.Parameters[
3].Value = DateTime.Now;


常見錯誤:

1、“呼叫 '儲存過程名稱' 時引數個數或型別錯誤”

出現錯誤的原因是因為你的 建立OracleParameter 是使用的引數名稱與儲存過程或Sql語句中定義的引數名稱不一致。 另外,也要注意,雖然在Sql 語句中使用 冒號“:”代表引數,但在建立OracleParameter時,指定的引數名稱不能使用冒號,在new OracleParameter時,ParameterName只能使用引數的字元部分。

2、“儲存過程名稱' 不是過程或尚未定義”

OracleCommand的Parameters集合中的引數個數與儲存過程中定義的數量不一致,你可能漏了某個Parameter沒有建立

3、"ORA-01036: 非法的變數名/編號“

出現此錯誤的原因很可能是儲存過程的包體的引數定義與包頭的定義不一樣,很多時候修改了包體,卻忘了修改包頭。 另外,建立OracleParameter時,由於建構函式的版本眾多,使用了某些版本時,可能會出現這個錯誤,建議建立OracleParameter時,一定要指定OracleType。
直接使用Sql 語句時,在Sql 語句中的 引數部分沒有使用冒號作為字首,或者錯誤使用了Sql Server 的"@"符號都會導致此錯誤。

總之此錯誤出現在Parameter指定的ParameterName,與實際引數名稱不匹配時。

要注意:在 new OracleParameter() 中,指定的ParameterName 只需要包含引數的字元部分,無需保含字首,如:冒號。


4、System.Data.OracleClient requires Oracle client software version 8.1.7 or greater.

出現這個錯誤表示你需要安裝Oracle客戶端。假如你已經安裝了Oracle客戶端,還出現這個錯誤,那肯定由於許可權的問題,部落格園的朋友Jeet 給出了答案:http://www.cnblogs.com/jeet/archive/2005/06/24/115150.html,具體方法如下:

1、以管理員的使用者登入;
2、找到ORACLE_HOME資料夾(比如C:oracleora92),點右鍵,選屬性--安全,在組或使用者欄中選“Authenticated Users”,在下面許可權列表中把“讀取和執行”的許可權去掉,再按應用;重新選上“讀取和執行”許可權,點選應用;選許可權框下面的“高階”按鈕,確認“Authenticated Users”後面的應用於是“該資料夾、子資料夾及檔案”,按確定把許可權的更改應用於該資料夾;

我在第一次使用Oracle是,碰到這個問題,使用jeet的方案解決了,Jeet說一定要重新啟動系統,但我沒有重啟也可以。或許是作業系統版本的問題,我的是windows 2003

總結:
Oracle與Sql Server的訪問上有很大不同:

1、欄位型別不同
2、儲存過程有很大差異,Oracle不能直接返回記錄集,需要透過一個 out 引數達到目的。在OracleType中有一個OracleType.Cursor 型別與之對應。 Oracle中的儲存過程大部分都定義成Funcion, 有返回值。 在定義Command的引數集合時,需要增加一個"ReturnValue"的引數。
3、Oracle中的引數無需"@"符號
4、Oracle的Sql 語句中 在引數前面加冒號":", 而Sql Server 的Sql 在前面加"@"

--Sql Server的Sql 語句insert into Table (Column1,Column2) values (@Value1,@Value2)

--Oracel中的Sql 語句 Insert Into Table (Column1,Column2) values
(:Value1,:Value2)

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/82387/viewspace-906159/,如需轉載,請註明出處,否則將追究法律責任。

相關文章