ODP.NET
1,什麼是ODP?就是Oracle 為 .NET (ODP.NET) 專門編寫了 Oracle Data Provider
,一個用於 Microsoft .NET
環境下的 Oracle
資料訪問 API
。
詳細解說 http://www.oracle.com/technetwork/cn/testcontent/o23odp-084525-zhs.html
ODP.NET
你不需要安裝Oracle
,不需要配置oracle.key
檔案,不需要配置TnsNames.Ora
檔案 不需要配置環境變數;完全的傻瓜式的在沒有安裝oracle
資料庫或者客戶端等任何oracle的產品的機器去訪問Oracle
資料庫!
下面詳細解說ODP.NET
如何對Oracle
的資料操作【可以完成建表,CURD
( 增刪查改)】
步驟一:獲取支援資料庫連線的類庫檔案:Oracle.DataAccess.dll
如何獲取呢?
到官網去相應的版本http://www.oracle.com/technetwork/cn/topics/dotnet/index-088718-zhs.html
要跑64位的.Net程式,就必須用64位的odp.net
,要跑32位的.Net程式,就必須用32位的odp.net
,最後給出odp.net32位與64位的下載地址:
64位下載地址
http://www.oracle.com/technetwork/database/windows/downloads/index-090165.html
32位下載地址
http://www.oracle.com/technetwork/database/windows/downloads/index-101290.html
在引用dll庫後,可能會引發下列異常:
這就需要將專案的平臺改成相應的平臺即可:
步驟二:在正式使用之前,需要在專案中新增引用:
Oracle.DataAccess.Client
設定資料庫的連線等等通用功能,
Oracle.DataAccess.Types
設定 oracle自定義的一些資料型別
步驟三:例項解說
如提供以下資料庫的資訊
資料庫伺服器地址:192.168.10.20
庫名:44410g242
賬號:44bikll
密碼:487gf,.q
連線oracle
的字串就是這樣的(提供我測試的2種方式)
//string conString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.10.20)(PORT=1521))" +//"(CONNECT_DATA=(SERVER = DEDICATED)(SERVICE_NAME = 44410g242)));User Id=44bikll;Password=487gf,.q;";
string conString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.10.20)(PORT=1521))" +"(CONNECT_DATA=(SID=44410g242)));User Id=44bikll;Password=487gf,.q;";
//寫連線串以上2方法連線都可以,也可以放到Web.Config中。
以上的連線協議TCP
和埠1521
都是預設的 ,無需修改,如埠被佔用了就需要改下。
本案例中涉及2個表TBLOCKLOG
和TBACCOUNT
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
namespace DHH_Bill_TBLockLog
{
class Program
{
static void Main(string[] args)
{
#region 測試資料庫
Console.WriteLine("獲取testid031使用者在2013-4-11 15:53:40到2013-04-12 00:00:00的消費清單");
Console.WriteLine();
string conString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.10.20)(PORT=1521))" +
"(CONNECT_DATA=(SID=44410g242)));User Id=44bikll;Password=487gf,.q;"; //這個也可以放到Web.Config中。
//例項化OracleConnection物件
try
{
using (OracleConnection conn = new OracleConnection(conString))
{
conn.Open();
string sql = "select TBACCOUNT.username,TBLOCKLOG.accountid,TBLOCKLOG.amount,TBLOCKLOG.locktime FROM TBLOCKLOG,TBACCOUNT WHERE TBLOCKLOG.accountid=TBACCOUNT.accountid ";
sql += " and TBLOCKLOG.serviceid=1 and TBACCOUNT.username='testid031' and TBLOCKLOG.status=1 and TBLOCKLOG.locktime >= to_date('2013-4-11 13:53:40','yyyy-mm-dd hh24:mi:ss') and TBLOCKLOG.locktime <= to_date('2013-04-12 00:00:00','yyyy-mm-dd hh24:mi:ss') order by TBLOCKLOG.locktime";
using (OracleCommand comm = new OracleCommand(sql, conn))
{
using (OracleDataReader rdr = comm.ExecuteReader())
{
while (rdr.Read())
{
Console.WriteLine("UserName:" + rdr.GetString(0) + ",UserId:" + rdr.GetInt32(1) + ",點數:" + rdr.GetInt32(2) + "," + rdr.GetDateTime(3));
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
#endregion
Console.WriteLine(); Console.WriteLine();
Console.WriteLine("計算2013-4-11 15:53:40到2013-04-12 00:00:00時間的testid031使用者消費的amount的總和");
Console.WriteLine(GetBillByDateAndGameId(conString, "testid031", 1, Convert.ToDateTime("2013-4-11 13:53:40"), Convert.ToDateTime("2013-04-12 00:00:00")));
}
public static int GetBillByDateAndGameId(string conString,string accountId, int gameId, DateTime beginTime, DateTime endTime)
{
try
{
using (OracleConnection conn = new OracleConnection(conString))
{
accountId = accountId.ToLower();//全部轉換為小寫
conn.Open(); string sql = "select sum(TBLOCKLOG.amount) sumamount FROM TBLOCKLOG,TBACCOUNT WHERE TBLOCKLOG.accountid=TBACCOUNT.accountid ";
sql += " and TBLOCKLOG.serviceid=" + gameId + " and TBACCOUNT.username='" + accountId + "' and TBLOCKLOG.status=1 and TBLOCKLOG.locktime >= to_date('" + beginTime + "','yyyy-mm-dd hh24:mi:ss') and TBLOCKLOG.locktime <= to_date('" + endTime + "','yyyy-mm-dd hh24:mi:ss') order by TBLOCKLOG.locktime";
using (OracleCommand comm = new OracleCommand(sql, conn))
{
using (OracleDataReader rdr = comm.ExecuteReader())//建立一個OracleDateReader物件
{
int sum = 0;
while (rdr.Read())//讀取資料,如果odr.Read()返回為false的話,就說明到記錄集的尾部了
{
if (rdr.GetOracleValue(0).ToString() == "null")//防止為空
{
sum = 0;
}
else
{
sum = int.Parse(rdr.GetOracleValue(0).ToString());
//sum = int.Parse(rdr[0].ToString());
}
}
return sum;
}
}
}
}
catch (Exception ex)
{
return -1;
}
}
}
}
顯示結果:
以下是:
1. 建立資料庫
建立一個名為OracleTypesTable
的表
create table OracleTypesTable (MyVarchar2 varchar2(3000),MyNumber number(28,4) Primary key ,MyDate date,MyRaw RAW(255));
插入一行資料
insert into OracleTypesTable values ('test',4,to_date('2000-01-11 12:54:01','yyyy-mm-dd hh24:mi:ss'),'0001020304');
注意:
1,案例中的sql
語句還是和mssql
有一點區別的;
2,統計的話如果獲取不到統計的資料的會報錯,這就是我為什麼加上if (rdr.GetOracleValue(0).ToString() == "null")//防止為空
3,WebSERVICE
的時候不知道為什麼他對使用者名稱的大小寫也有區分。
步驟四:部署說明
在部署到真實伺服器的時候,你也同樣按照步驟一中的步驟安裝客戶端ODP.NET
檔案,點選執行EXE
檔案自動配置環境變數,檢視一下是否安裝成功。
注意版本是否一致,這個是執行你的程式的關鍵,開啟cmd
,執行:C:\Documents and Settings\Administrator>sqlplus /nolog
就可以知道版本
我的結果:
C#連線Oracle
資料庫的方法(Oracle.DataAccess.Client
也叫ODP.net
)
官方下載地址(ODP.net)(中文):http://www.oracle.com/technetwork/cn/topics/dotnet/downloads/index.html
官方下載地址(ODP.net):http://www.oracle.com/technetwork/topics/dotnet/downloads/index.html
首先介紹下開發環境:WIn10 64bit+Visual Studio 2015+Oracle10ClientWin32
(只是客戶端,如果安裝整個資料庫也是可以的)
目前瞭解C#
中連線Oracle
資料庫的方法有3種,分佈是微軟的System.Data.OracleClient
,Oracle的Oracle.DataAccess.Client
和Oracle的Oracle.ManagedDataAccess.dll
(最優)
1.微軟的System.Data.OracleClient
可以直接引用,但是VS會提示“System.Data.OracleClient.OracleConnection”
已過時,這表明微軟自己都不建議使用了,所以知道就可以了,不必使用
2.C#使用Oracle.DataAccess.Client
也叫ODP.net
,他是Oracle
提供的資料庫訪問類庫,其功能和效率上都有所保證,它還有一個非常方便特性:在客戶端上,可以不用安裝Oracle
客戶端,直接拷貝即可使用。由於微軟在.net framework4
中會將System.Data.OracleClient.dll deprecated
,而且就訪問效率和速度而言,System.Data.OracleClient.dll
與Oracle.DataAccess.dll
相比,微軟的確實沒有oracle提供的類庫有優勢,所以我放棄了使用多年的System.Data.OracleClient.dll
,取而代之的是odp.net
。然而odp.net
的優點不止這些,還包括:
1)不在安裝客戶端也能訪問伺服器上的oracle
(假設Application Server
與DB Server
分開)
2)不需要配置TnsNames.Ora
檔案
具體的使用方法請參考這位大俠的 http://blog.csdn.net/rrrrssss00/article/details/7178515/
還有這位大俠的 http://blog.csdn.net/sumirry/article/details/46746331
如果專案要從System.Data.OracleClient.OracleConnection
轉Oracle.DataAccess.Client
時,只需要在oracle
安裝目錄下 找到 Oracle.DataAccess.dll
新增引用,後 using Oracle.DataAccess.Client;
其他的都不用動,即可。
連線字串中 如有 用的是 user=xxx
就改成user id=xxx
把原來 Using
的System.Data.OracleClient
去掉即可。
3.重點學習最後一種Oracle.ManagedDataAccess.dll
,第二種的優點很多,但是也有缺點,就是要區分用區分x86/x64
版本。
OracleConnection con = new OracleConnection(ConfigurationManager.ConnectionStrings["OracleConnString"].ToString());
con.Open();
OracleCommand cmd = new OracleCommand(cmdString, con);
OracleDataAdapter oda = new OracleDataAdapter();
oda.SelectCommand = cmd;
oda.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
Oracle ODP.NET資料庫訪問連線字串
Connection String Attribute | 預設值 | 描述 |
---|---|---|
Connection Lifetime | 0 | Maximum life time (in seconds) of the connection |
當資料庫連線被返回到連線池中時,它的建立時間將與當前時間比較,如果超過了 Connection Lifetime 規定的時間,它將被釋放掉。 為 0 時將被視為最大連線時間。 | ||
Connection Timeout | 15 | Maximum time (in seconds) to wait for a free connection from the pool |
Data Source | empty string | Oracle Net Service Name that identifies the database to connect to |
DBA Privilege | empty string | Administrative privileges: SYSDBA or SYSOPER |
Decr Pool Size | 1 | Controls the number of connections that are closed when an excessive amount of established connections are unused |
Enlist | True | Enables or disables serviced components to automatically enlist in distributed transactions |
當此值為 true 時,池中現存的所有資料庫連線將被加入到它的建立執行緒的 Transaction Context 中。如果不存在這個 Transaction Context 則無任何變化。 | ||
Incr Pool Size | 5 | Controls the number of connections that are established when all the connections in the pool are used |
Max Pool Size | 100 | Maximum number of connections in a pool |
Min Pool Size | 1 | Minimum number of connections in a pool |
Password | empty string | Password for the user specified by User Id |
Persist Security Info | False | Enables or disables the retrieval of password in the connection string |
Pooling | True | Enables or disables connection pooling |
Proxy User Id | empty string | User name of the proxy user |
Proxy Password | empty string | Password of the proxy user |
User Id | empty string | Oracle user name |
...
OracleConnection con = new OracleConnection();
con.ConnectionString = "User Id=scott;Password=tiger;Data Source=oracle;Pooling=true;Enlist=true;Min Pool Size=10;Connection Lifetime=120;Connection Timeout=60;Incr Pool Size=5; Decr Pool Size=2";
con.Open();
...
以下網站提供連線字串大全:
www.ConnectionStrings.com
Oracle.ManagedDataAccess.dll
全託管驅動學習總結
一、學習背景:
1)微軟自vs2010後放棄了自家的system.data.oracleClient
驅動,推薦使用oracle
提供的驅動。
2)微軟提供的system.data.oracleClient
驅動存在oracle32
位與64
位連線相容性的問題,解決起來費時費力。
二、Oracle推薦的驅動:oracle.DataAccess.dll
與oracle.ManagedDataAccess.dll
1)oracle.DataAccess.dll
的缺陷。oracle.DataAccess.dll
需要幾個dll檔案,在實際使用中發現,oracle.DataAccess.dll
無客戶端連線方式同樣存在所使用的dll
檔案的32位與64位和oracle
資料庫或系統本身存在的dll存在連線相容性問題。所以不推薦使用該驅動。
2)推薦使用oracle.ManagedDataAccess.dll
(oracle.ManagedDataAccess.Client
)全託管驅動。實際使用發現,oracle全託管驅動對32位和64位oracle資料庫具有很好的連線相容性。可採用無客戶端遠端連線oracle
,或在本機使用連線。可通過visual studio 2010 nuget安裝,或直接下載dll檔案,然後引用oracle.ManagedDataAccess.dll
檔案。在專案資料訪問層中引用名稱空間using oracle.ManagedDataAccess.Client
,如圖2-1
圖 2-1引用oracle.ManagedDataAccess.Client
名稱空間
三、Web.config連線字串
NET提供的連結字串connectionString="DataSource=192.168.1.2:1521/orcl;Persist Security Info=True;User ID=scott;Password=tiger";
四、關於command.BindByName = true;
(重點敲黑板)
1)在使用全託管驅動oracle.ManagedDataAccess.dll
後,ado.net
的增刪查語句都執行正常,但是在執行修改語句(update
語句)時,會引發異常。
2)預設情況下ODP.Net
繫結變數時,sql語句中的變數順序必須和變數繫結順序一致,否則Fill
查不到資料,cmd.ExecuteNonQuery()
返回0
無法執行,將BindByName
設為true
後,sql變數順序和繫結順序即可不一致