1. 程式人生 > >oracle字符集亂碼及返回 REF CURSOR 的儲存過程執行問題

oracle字符集亂碼及返回 REF CURSOR 的儲存過程執行問題



關於oracle字符集亂碼問題:

1.OracleClient方式 存在亂碼問題。(比如:當Oracle資料庫伺服器端採用英文字符集比如 US7ASCII 時,客戶端不管字符集如何設定,讀出的中文都是亂碼;若伺服器端用中文字符集比如 ZHS16GBK ,則無亂碼問題。)

2. OleDb方式 微軟 為“provider=MSDAORA.1;” 存在亂碼問題。 (比如:伺服器oracle為utf8,客戶端為日文系統時,中文顯示亂碼)

3.OleDb方式 Oracle為“provider='OraOleDb.Oracle';”。 不管Oracle伺服器端用何字符集,讀寫中文均無亂碼問題。

關於要執行返回 REF CURSOR 的儲存過程問題:

1 OracleClient:

必須在 OracleParameterCollection 中定義引數,包括 Cursor 的 OracleType 以及 Output 的 Direction。資料提供程式只支援作為輸出引數繫結 REF CURSOR。提供程式不支援 REF CURSOR 作為輸入引數。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Data;
using System.Data.OracleClient;
namespace pro
{
    public partial class WebForm4 : System.Web.UI.Page
    {
        string OracleConnectionString = ConfigurationManager.ConnectionStrings["scott"].ConnectionString;
        protected void Page_Load(object sender, EventArgs e)
        {
            OracleConnection conn = new OracleConnection(OracleConnectionString);
            OracleCommand comm = new OracleCommand();
            comm.Connection = conn;
            comm.CommandType = CommandType.StoredProcedure;
            comm.CommandText = "curspkg.open_one_cursor";
            comm.Parameters.Add(new OracleParameter("n_empno", OracleType.Number)).Value = "0";
            comm.Parameters.Add(new OracleParameter("io_cursor", OracleType.Cursor)).Direction = ParameterDirection.Output;
            conn.Open();
            OracleDataReader rdr = comm.ExecuteReader();
                GridView1.DataSource = rdr;
                GridView1.DataBind();         
            conn.Close();
        }
    }
}

2. OleDb方式 微軟

  provider=MSDAORA提供程式不會自動繫結 REF CURSOR 資料型別

create or replace package PKG_TEST_SYH is

  TYPE T_CURSOR IS REF CURSOR;

  procedure TEST001(io_cursor in out T_CURSOR);

end PKG_TEST_SYH;

create or replace package BODY PKG_TEST_SYH is

   procedure TEST001(O_NumRowUI out Number)
   is
   begin
        SELECT count(*) INTO O_NumRowUI
        FROM F101HEADER


   end TEST001;

begin
  null;
end PKG_TEST_SYH;

.net中呼叫儲存過程時,不必要設定cursor的型別和輸出方式

oleDbCommand.CommandText = procedureName;
   try
   {
    OleDbDataAdapter myAdapter = new OleDbDataAdapter();
    myAdapter.SelectCommand = oleDbCommand;
    myAdapter.Fill(ds,tbName);
   }
   catch(Exception ex)
   {
    Console.WriteLine(ex.Message);
   }

3.OleDb方式 Oracle

provider='OraOleDb.Oracle' 資料提供程式不會自動繫結 REF CURSOR 資料型別,oledb也沒有提供對應(System.Data.OracleClient.OracleType.Cursor)的cursor型別。

目前能想到的方法是:

1) 建立臨時表,將cursor資料集依次儲存在臨時表中,再從臨時表中得到。

2)

ØOracle資料庫連線方式:

Provider=OraOLEDB.Oracle.1;User ID=username;password=dbpassword;Data Source=databasename;Persist Security Info=True;Extended Properties='PLSQLRSet=1';

Extended Properties='PLSQLRSet=1'

注意:上面這個屬性一定要帶上,否則無法操作有返回遊標引數的儲存過程;

參照:

關於oracle字符集亂碼問題:

1 OracleClient方式,是微軟專門針對Oracle資料庫開發的,僅在 .NET Framework 1.1 版中受支援。當Oracle資料庫伺服器端採用英文字符集比如 US7ASCII 時,客戶端不管字符集如何設定,讀出的中文都是亂碼;若伺服器端用中文字符集比如 ZHS16GBK ,則無亂碼問題。
引用類庫:System.Data.OracleClient.dll。 
名稱空間:System.Data.OracleClient。
常用類:OracleConnection、OracleCommand、OracleDataAdapter、OracleTransaction、OracleDataReader等。
典型連線字串:“data source=oratest;user id=scott;password=tiger”(注意:可不指定 provider 驅動)。

2. OleDb方式,微軟和Oracle公司各自提供了OleDb的驅動程式,使用方法的差別很少。
相同之處
名稱空間:System.Data.OleDb。
常用類:OleDbConnection、OleDbCommand、OleDbDataAdapter、OleDbTransaction、OleDbDataReader等。
不同之處
引用類庫:微軟的只需要System.Data.dll;若用Oracle的驅動,雖然也只要引入System.Data.dll,但前提是首先安裝
Oracle針對.Net的資料訪問元件
連線字串:與OracleClient方式相比,要新增一個provider,微軟為“provider=MSDAORA.1;”,Oracle為“provider='OraOleDb.Oracle';”。

provider=MSDAORA.1 存在亂碼問題。 (比如:伺服器oracle為utf8,客戶端為日文系統時,中文顯示亂碼)

provider='OraOleDb.Oracle' 不管Oracle伺服器端用何字符集,讀寫中文均無亂碼問題。

作為返回引數的Cursor,直接使用DataTable接受就可以了
因為效能的原因,除非您顯式指定,否則,Oracle 資料提供程式不會自動繫結 REF CURSOR 資料型別,因為 MSDAORA 會這樣做。

資料提供程式不支援任何 ODBC 轉義序列,包括用於指定 REF CURSOR 引數的 {resultset} 轉義。

要執行返回 REF CURSOR 的儲存過程,必須在 OracleParameterCollection 中定義引數,包括 Cursor 的 OracleType 以及 Output 的 Direction。資料提供程式只支援作為輸出引數繫結 REF CURSOR。提供程式不支援 REF CURSOR 作為輸入引數。

不支援從引數值獲取 OracleDataReader。在執行命令後,值屬於 DBNull 型別。

適用於 REF CURSOR 的唯一 CommandBehavior 列舉值(例如在呼叫 ExecuteReader 時)是 CloseConnection;所有其他列舉值均將被忽略。

REF CURSOR 在 OracleDataReader 中的順序取決於引數在 OracleParameterCollection 中的順序。ParameterName 屬性被忽略。

不支援 PL/SQL TABLE 資料型別。但是,REF CURSOR 的效率更高。如果必須使用 TABLE 資料型別,請使用 OLE DB .NET 資料提供程式和 MSDAORA。