close

.net 2.0 訪問Oracle --與Sql Server的差異,注意事項,常見異常 
http://cwbboy.cnblogs.com/archive/2006/03/22/356017.html

     在.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 


  Function GetList(keywords In varchar2
                           ,p_info_list_Cursor out get_data_cur_type)
   Return Number
As

  Begin
      
       open p_info_list_Cursor For
       Select * from Test where Key=keywords
;
       Return 0;
  End;

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

 1         OracleConnection OracleConn = new OracleConnection(連接字符串);
 2        OracleCommand cmd = new OracleCommand("Test.GetList", OracleConn);
 3        cmd.Parameters.AddRange(
 4            new OracleParameter[]
 5            {
 6                new OracleParameter("keyWords", OracleType.VarChar),
 7                new OracleParameter("ReturnValue", OracleType.Number, 0, ParameterDirection.ReturnValue, true, 0, 0, "",DataRowVersion.Default, Convert.DBNull),
 8                new OracleParameter("p_info_list_Cursor", OracleType.Cursor, 2000, ParameterDirection.Output, true, 0, 0, "",DataRowVersion.Default, Convert.DBNull)
 9            });
10        cmd.Parameters[0].Value = '美女';
11        cmd.Parameters[0].Direction = ParameterDirection.Input;
12        cmd.CommandType = CommandType.StoredProcedure;
13        OracleConn.Open()
14        OracleDataReader rdr=cmd.ExecuteReader();
15       //其他代碼
16        OracleConn.Close();
17
      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 語句不能使用@符號, 以冒號":"代替. 如:
   

 string Sql = "Insert into SEARCH_HISTORY(KEYWORDS,PHONE,RESULT_ID,SEARCH_TIME) values(:KEYWORDS,:PHONE,:RESULT_ID,:SEARCH_TIME)";
        OracleCommand cmd = new OracleCommand(Sql, OracleConn);
        cmd.Parameters.AddRange(new OracleParameter[]{
            new OracleParameter("KEYWORDS",OracleType.VarChar),
            new OracleParameter("PHONE",OracleType.VarChar),
            new OracleParameter("RESULT_ID",OracleType.Number),
            new OracleParameter("SEARCH_TIME",OracleType.DateTime)
        });
        cmd.Parameters[0].Value = Keywords;
        cmd.Parameters[1].Value = Phone;
        cmd.Parameters[2].Value=2;
        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:\oracle\ora92),點右鍵,選屬性--安全,在組或用戶欄中選「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)

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 11 的頭像
    11

    冠霖的部落格

    11 發表在 痞客邦 留言(0) 人氣()