ODP.NET r囧r小猫 2021-09-18 01:40 362阅读 0赞 1,什么是ODP?就是Oracle 为 .NET ([ODP.NET][]) 专门编写了 `Oracle Data Provider`,一个用于 Microsoft `.NET` 环境下的 `Oracle` 数据访问 `API` 。 详细解说 [http://www.oracle.com/technetwork/cn/testcontent/o23odp-084525-zhs.html][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][http_www.oracle.com_technetwork_database_windows_downloads_index-090165.html] 32位下载地址 [http://www.oracle.com/technetwork/database/windows/downloads/index-101290.html][http_www.oracle.com_technetwork_database_windows_downloads_index-101290.html] 在引用dll库后,可能会引发下列异常: ![在这里插入图片描述][20190214230440837.png]这就需要将项目的平台改成相应的平台即可: ![在这里插入图片描述][20190214230503866.png] **步骤二:在正式使用之前,需要在项目中添加引用:** `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; } } } } 显示结果: ![在这里插入图片描述][20190214230841688.png] 以下是: *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` 就可以知道版本 我的结果: ![在这里插入图片描述][20190214231303569.png] -------------------- ## C\#连接`Oracle`数据库的方法(`Oracle.DataAccess.Client`也叫`ODP.net`) ## 官方下载地址([ODP.net][])(中文):[http://www.oracle.com/technetwork/cn/topics/dotnet/downloads/index.html][http_www.oracle.com_technetwork_cn_topics_dotnet_downloads_index.html] 官方下载地址([ODP.net][]):[http://www.oracle.com/technetwork/topics/dotnet/downloads/index.html][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_rrrrssss00_article_details_7178515] 还有这位大侠的 [http://blog.csdn.net/sumirry/article/details/46746331][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数据库访问连接字符串** <table> <thead> <tr> <th align="left">Connection String Attribute</th> <th align="left">默认值</th> <th align="left">描述</th> </tr> </thead> <tbody> <tr> <td align="left">Connection Lifetime</td> <td align="left">0</td> <td align="left">Maximum life time (in seconds) of the connection</td> </tr> <tr> <td align="left"></td> <td align="left"></td> <td align="left">当数据库连接被返回到连接池中时,它的创建时间将与当前时间比较,如果超过了 Connection Lifetime 规定的时间,它将被释放掉。 为 0 时将被视为最大连接时间。</td> </tr> <tr> <td align="left">Connection Timeout</td> <td align="left">15</td> <td align="left">Maximum time (in seconds) to wait for a free connection from the pool</td> </tr> <tr> <td align="left">Data Source</td> <td align="left">empty string</td> <td align="left">Oracle Net Service Name that identifies the database to connect to</td> </tr> <tr> <td align="left">DBA Privilege</td> <td align="left">empty string</td> <td align="left">Administrative privileges: SYSDBA or SYSOPER</td> </tr> <tr> <td align="left">Decr Pool Size</td> <td align="left">1</td> <td align="left">Controls the number of connections that are closed when an excessive amount of established connections are unused</td> </tr> <tr> <td align="left">Enlist</td> <td align="left">True</td> <td align="left">Enables or disables serviced components to automatically enlist in distributed transactions</td> </tr> <tr> <td align="left"></td> <td align="left"></td> <td align="left">当此值为 true 时,池中现存的所有数据库连接将被加入到它的创建线程的 Transaction Context 中。如果不存在这个 Transaction Context 则无任何变化。</td> </tr> <tr> <td align="left">Incr Pool Size</td> <td align="left">5</td> <td align="left">Controls the number of connections that are established when all the connections in the pool are used</td> </tr> <tr> <td align="left">Max Pool Size</td> <td align="left">100</td> <td align="left">Maximum number of connections in a pool</td> </tr> <tr> <td align="left">Min Pool Size</td> <td align="left">1</td> <td align="left">Minimum number of connections in a pool</td> </tr> <tr> <td align="left">Password</td> <td align="left">empty string</td> <td align="left">Password for the user specified by User Id</td> </tr> <tr> <td align="left">Persist Security Info</td> <td align="left">False</td> <td align="left">Enables or disables the retrieval of password in the connection string</td> </tr> <tr> <td align="left">Pooling</td> <td align="left">True</td> <td align="left">Enables or disables connection pooling</td> </tr> <tr> <td align="left">Proxy User Id</td> <td align="left">empty string</td> <td align="left">User name of the proxy user</td> </tr> <tr> <td align="left">Proxy Password</td> <td align="left">empty string</td> <td align="left">Password of the proxy user</td> </tr> <tr> <td align="left">User Id</td> <td align="left">empty string</td> <td align="left">Oracle user name</td> </tr> </tbody> </table> ... 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`命名空间 ![在这里插入图片描述][20190214233006267.png] ### 三、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变量顺序和绑定顺序即可不一致 [ODP.NET]: http://ODP.NET [http_www.oracle.com_technetwork_cn_testcontent_o23odp-084525-zhs.html]: http://www.oracle.com/technetwork/cn/testcontent/o23odp-084525-zhs.html [http_www.oracle.com_technetwork_database_windows_downloads_index-090165.html]: http://www.oracle.com/technetwork/database/windows/downloads/index-090165.html [http_www.oracle.com_technetwork_database_windows_downloads_index-101290.html]: http://www.oracle.com/technetwork/database/windows/downloads/index-101290.html [20190214230440837.png]: /images/20210626/17d9116217d14e839df335fae212d4b9.png [20190214230503866.png]: /images/20210626/6acf02607fb04b69899f0e3e98e08a98.png [20190214230841688.png]: /images/20210626/aa9505890a71459c89dece36dee43a7f.png [20190214231303569.png]: /images/20210626/d995eddf4cd644039bef92bba766403b.png [ODP.net]: http://ODP.net [http_www.oracle.com_technetwork_cn_topics_dotnet_downloads_index.html]: http://www.oracle.com/technetwork/cn/topics/dotnet/downloads/index.html [http_www.oracle.com_technetwork_topics_dotnet_downloads_index.html]: http://www.oracle.com/technetwork/topics/dotnet/downloads/index.html [http_blog.csdn.net_rrrrssss00_article_details_7178515]: http://blog.csdn.net/rrrrssss00/article/details/7178515/ [http_blog.csdn.net_sumirry_article_details_46746331]: http://blog.csdn.net/sumirry/article/details/46746331 [www.ConnectionStrings.com]: http://www.ConnectionStrings.com [20190214233006267.png]: /images/20210626/3fa844d6d9a84d46afde18d722c4cac8.png
还没有评论,来说两句吧...