ASP.NET操作Oracle知識記錄(采用ODP.NET)


最近因為要把以前做的一個項目數據庫從MSSQL2005轉移到Oracle上,所以開始接觸Oracle,通過本篇隨筆簡單記錄一些ASP.NET結合Oralce的操作;

因為微軟未來不再支持 System.Data.OracleClient 這個 Data Provider 的研發,從 .NET 4 以后的版本,會將該類庫移除。所以決定采用Oracle 自家的解決方案 ODP.NET;

目前ODP.NET最新版本為12.1.0.1.0(開發跟部署機器都要安裝);下載地址[http://www.oracle.com/technetwork/database/windows/downloads/index-101290.html];

該版本支持Oracle10g以上的操作;下載安裝完后,我們可以在安裝路徑[product\12.1.0\client_1\odp.net\managed\common]找到要引用的Oracle.ManagedDataAccess.dll

 

 

 

 

 

 

1:連接Oracle配置內容

  <appSettings>
    <!--<add key="OracleConString" value="Data Source=(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.12.15)(PORT = 1521))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = Orcl)));User Id=wujy;Password=123456" />-->
    <add key="OracleConString" value="user id=wujy;password=123456;data source=192.168.12.15:1521/Orcl" />
  </appSettings>

 

2:對Oracle進行增刪改

 (1):增加操作

      public bool Create(LogInfoModel model)
        {
            StringBuilder strSql = new StringBuilder();
            strSql.Append("insert into LOGINFO(");
            strSql.Append(" ID,LOGSOURCE,LOGTYPE,LOGCONTENT,OPERATER,CREATEDATE,ISDELETE");
            strSql.Append(") values (");
            strSql.Append(" :ID,:LOGSOURCE,:LOGTYPE,:LOGCONTENT,:OPERATER,:CREATEDATE,:ISDELETE");
            strSql.Append(") ");
            OracleParameter[] parameters = {
                        new OracleParameter(":ID",  model.ID),           
                        new OracleParameter(":LOGSOURCE",  model.LOGSOURCE),           
                        new OracleParameter(":LOGTYPE",  model.LOGTYPE),           
                        new OracleParameter(":LOGCONTENT",  model.LOGCONTENT),           
                        new OracleParameter(":OPERATER",  model.OPERATER),           
                        new OracleParameter(":CREATEDATE",  model.CREATEDATE),           
                        new OracleParameter(":ISDELETE",  model.ISDELETE),           
                };
            return OracleHelper.OracleHelper.ExecuteNonQuery(PubConnection.ConnectionString, CommandType.Text, strSql.ToString(), parameters) > 0;
        }

注意:參數的順序跟SQL語句中要一一對應,否者也會報錯,這個要MSSQL是不會出現的,更新也要注意參數的順序

(2):更新操作

        public bool Update(LogInfoModel model)
        {
            StringBuilder strSql = new StringBuilder();
            strSql.Append("update LOGINFO set ");
            strSql.Append(" ID = :ID , ");
            strSql.Append(" LOGSOURCE = :LOGSOURCE , ");
            strSql.Append(" LOGTYPE = :LOGTYPE , ");
            strSql.Append(" LOGCONTENT = :LOGCONTENT , ");
            strSql.Append(" OPERATER = :OPERATER , ");
            strSql.Append(" ISDELETE = :ISDELETE ");
            strSql.Append(" where ID=:ID  ");
            OracleParameter[] parameters = {
                        new OracleParameter(":ID",  model.ID),           
                        new OracleParameter(":LOGSOURCE",  model.LOGSOURCE),           
                        new OracleParameter(":LOGTYPE",  model.LOGTYPE),           
                        new OracleParameter(":LOGCONTENT",  model.LOGCONTENT),           
                        new OracleParameter(":OPERATER",  model.OPERATER),                    
                        new OracleParameter(":ISDELETE",  model.ISDELETE),           
            };
            return OracleHelper.OracleHelper.ExecuteNonQuery(PubConnection.ConnectionString, CommandType.Text, strSql.ToString(), parameters) > 0;
        }

注意:Oracle更新要是用OracleParameter參數形式時要把條件也進行更新,否則會失敗;這個跟MSSQL是不一樣的;或者可以換另外一種寫法:

        public bool Update(LogInfoModel model)
        {
            string strSql = string.Format("update LOGINFO set LOGSOURCE = :LOGSOURCE ,LOGTYPE = :LOGTYPE ,LOGCONTENT = :LOGCONTENT ,OPERATER = :OPERATER ,ISDELETE = :ISDELETE where ID='{0}'", model.ID);
            OracleParameter[] parameters = {          
                        new OracleParameter(":LOGSOURCE",  model.LOGSOURCE),           
                        new OracleParameter(":LOGTYPE",  model.LOGTYPE),           
                        new OracleParameter(":LOGCONTENT",  model.LOGCONTENT),           
                        new OracleParameter(":OPERATER",  model.OPERATER),                      
                        new OracleParameter(":ISDELETE",  model.ISDELETE),           
            };
            return OracleHelper.OracleHelper.ExecuteNonQuery(PubConnection.ConnectionString, CommandType.Text, strSql, parameters) > 0;
        }

(3):刪除操作

        public bool Delete(string ID)
        {
            string sql = "delete  from LOGINFO where ID=:ID";
            OracleParameter[] parm = { new OracleParameter(":ID", ID) };
            return OracleHelper.OracleHelper.ExecuteNonQuery(PubConnection.ConnectionString, CommandType.Text, sql, parm) > 0;
        }

(4):查找操作

        public List<LogInfoModel> GetListForwhere(string strWhere)
        {
            string sql = string.Empty;
            if (string.IsNullOrEmpty(strWhere))
            {
                sql = "select * from LOGINFO";
            }
            else
            {
                sql = "select *  from LOGINFO where " + strWhere + "";
            }
            DataTable dt = OracleHelper.OracleHelper.ExecuteDataset(PubConnection.ConnectionString, CommandType.Text, sql).Tables[0];
            return Convert(dt);
        }

 

3:創建自增字段

Oracle因為沒有像MSSQL那么簡單的創建自增字段,所以必需通過SQL腳本進行設置(先創建序列再創建觸發器),實例如下:

(1)創建表

Create  table  t_user(
Id number(6),userid varchar2(20)
);

(2)創建序列

create sequence user_seq
increment by 1  
start with 1
nomaxvalue
nominvalue
nocache

(3)創建觸發器

create or  replace trigger tr_user
before insert on t_user
for each row
begin
select user_seq.nextval into :new.id from dual;
end;

 

4:使用存儲過程進行分頁:

(1):首先在Oracle新建一個存儲過程,腳本如下(此腳本源於網絡):

create or replace package p_page is
  TYPE type_cur IS REF CURSOR; --定義游標變量用於返回記錄集

  PROCEDURE Pagination(Pindex in number, --分頁索引
                       Psql   in varchar2, --產生dataset的sql語句
                       Psize  in number, --頁面大小
                       Pcount out number, --返回分頁總數
                       Prcount out number,--返回總條數
                       v_cur  out type_cur --返回當前頁數據記錄
                       );
end p_page;
/
create or replace package body p_page is

PROCEDURE Pagination(
  Pindex in number,
  Psql in varchar2,
  Psize in number,
  Pcount out number,
  Prcount out number,
  v_cur out type_cur
 )
 AS

  v_sql VARCHAR2(1000);
  v_count number;
  v_Plow number;
  v_Phei number;
  v_prcount number;
  
 Begin
  ------------------------------------------------------------取分頁總數
  v_sql := 'select count(*) from (' || Psql || ')';
  execute immediate v_sql into v_count;
  Pcount := ceil(v_count/Psize);
  ------------------------------------------------------------顯示總條數
  v_sql := 'select count(*) from (' || Psql || ')';
   execute immediate v_sql into v_prcount;
   Prcount := v_prcount;                  --返回記錄總數  
  ------------------------------------------------------------顯示任意頁內容
  v_Phei := Pindex * Psize + Psize;
  v_Plow := v_Phei - Psize + 1;
  --Psql := 'select rownum rn,t.* from zzda t' ;            --要求必須包含rownum字段
  v_sql := 'select * from (' || Psql || ') where rn between ' || v_Plow || ' and ' || v_Phei ;

  open v_cur for v_sql;

 End Pagination;

 --**************************************************************************************
end p_page;

(2):把分頁進行簡單封裝,返回DataTable

 /// <summary>
        /// 內容描述:使用存儲過程,查詢分頁后的數據。
        /// </summary>
        /// <param name="strConStr">連接oracle數據庫字符串</param>
        /// <param name="strSql">查詢sql語句(要求必須包含rownum字段,別名是rn 如:select rownum rn,ID from TableName)</param>
        /// <param name="curPage">當前顯示頁數</param>
        /// <param name="strPageSize">每頁條數</param>
        /// <param name="strCount">返回分頁數</param>
        /// <param name="strRowCount">返回記錄數</param>
        /// <returns>分頁結果數據集</returns>
        public static DataTable getDataTable(string strConStr, string strSql, int curPage, string strPageSize, out string strCount, out string strRowCount)
        {
            DataTable dt = new DataTable();
            OracleParameter[] parameters = { 
                                           new OracleParameter("Pindex",curPage-1),
                                           new OracleParameter("Psql",strSql),
                                           new OracleParameter("Psize",strPageSize),
                                           new OracleParameter("Pcount",OracleDbType.Int32),
                                           new OracleParameter("Prcount",OracleDbType.Int32),
                                           new OracleParameter("v_cur",OracleDbType.RefCursor),
                                           };
            parameters[3].Direction = ParameterDirection.Output;
            parameters[4].Direction = ParameterDirection.Output;
            parameters[5].Direction = ParameterDirection.Output;
            dt = OracleHelper.ExecuteDataset(strConStr, CommandType.StoredProcedure, "p_page.Pagination", parameters).Tables[0];
            strCount = parameters[3].Value.ToString();
            strRowCount = parameters[4].Value.ToString();
            return dt;
        }

        /// <summary>
        /// 內容描述:使用存儲過程,查詢分頁后的數據。
        /// </summary>
        /// <param name="strConStr">連接oracle數據庫字符串</param>
        /// <param name="strSql">查詢sql語句(要求必須包含rownum字段,別名是rn 如:select rownum rn,ID from TableName)</param>
        /// <param name="curPage">當前顯示頁數</param>
        /// <param name="strPageSize">每頁條數</param>
        /// <param name="strCount">返回分頁數</param>
        /// <param name="strRowCount">返回記錄數</param>
        /// <param name="Strwhere">帶條件 沒有則為空</param>
        /// <returns>分頁結果數據集</returns>
        public static DataTable getDataTable(string strConStr, string strSql, int curPage, string strPageSize, out string strCount, out string strRowCount,string Strwhere)
        {
            string StrSqlByWhere;
            if (!string.IsNullOrEmpty(Strwhere))
            {
                StrSqlByWhere = strSql + " where " + Strwhere;
            }
            else
            {
                StrSqlByWhere = strSql;
            }
            return getDataTable(strConStr, StrSqlByWhere, curPage, strPageSize, out strCount, out strRowCount);
        }


(3):分頁測試代碼

        public static void PageGetDataSet()
        {
            string HangSh = "0";//行數
            string YeSh = "0";//頁數
            string connectStr = ConfigurationManager.AppSettings["OracleConString"];
            string sqlStr = "select rownum rn,ID from wujy.Db_Tables";
            DataTable tb = getDataTable(connectStr, sqlStr, 1, "10", out YeSh, out HangSh);
            Console.WriteLine("總共為" + YeSh + "" + "|每頁為10條|數據總條數為" + HangSh);
            Console.WriteLine("第一頁:");
            for (int i = 0; i < tb.Rows.Count; i++)
            {
                Console.WriteLine(tb.Rows[i]["ID"].ToString());
            }
        }

(4):運行效果:

 

5:其它常見問題:

 

(1):創建完Oracle后我們一般會新建一個用戶來,語句如下:

create user wujy identified by admin

創建完這個用戶它是沒有權限的,要對它進行賦相應角色

grant connect,resource to wujy

 

(2):Oracle中執行SQL時,如果被操作的表不是此用戶創建則要在表的前面加上其所有者,否則將會提示沒有此表,wujy就是這表的所有者

delete from wujy.Db_Tables where ID=14

 

(3):連接Oracle一直報:ORA-12154:TNS:無法解析指定的連接標識符

這個問題是因為我電腦里面裝的幾個版本的oracle客戶端,我把連接的語句配置在9i版本上(tnsnames),卻一直用10G的Oracle Sql*Plus去連接,肯定會報錯的;

若是用PL/SQL Developer去連時也會報這個錯誤,要在"工具"--"首選項"--"連接"--"Oracle 主目錄名(自動檢測為空)"選擇相應的版本

 

(4):我們平常都是運用CodeSmithGenerator來進行代碼的生成;創建Oracle連接語句如下(一些參數自行替換):

Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.12.15)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=Orcl)));User Id=system;Password=123456;

 

(5):創建視圖,提示“權限不夠”,怎么解決?

 grant create any view to 用戶名

 

(6):賦予調試Oracle存儲過程權限,怎么解決?

grant debug any procedure ,debug connect session to username

 

(7):多條SQL語句放在一起執行

以前用MSSQL時我們經常: string sqlStr="delete from User where ID=1;delete from Unit where ID=1";

但在Oracle就不能這么寫,會報錯誤,要加上begin end;要寫成如下:string sqlStr="begin delete from User where ID=1;delete from unit where ID=1;end;";

 

感謝您的閱讀,文中OracleHelper為操作Oracle數據助手,可以從網絡上進行下載所以就不上傳了,若有需要或找不到可以留下郵箱地址;


免責聲明!

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



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