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.youkuaiyun.com/rrrrssss00/article/details/7178515/
还有这位大侠的 http://blog.youkuaiyun.com/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变量顺序和绑定顺序即可不一致