最近因為要把以前做的一個項目數據庫從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數據助手,可以從網絡上進行下載所以就不上傳了,若有需要或找不到可以留下郵箱地址;