zoukankan      html  css  js  c++  java
  • ODP.Net Sql的参数传递方法

    ODP.Net Sql的参数传递方法

      Oracle为dotNet开发人员提供了全新的开发包ODP.NET,ODP.NET是为微软dotNet应用程序所提供的一套高效的访问Oracle数据库开发包。正是由于它的高效性,使用范围比较广。自然而然园子里面关于此的话题很多。这里我就切身实践谈谈ODP的使用。

      第一次听说ODP也是在做项目改善速度的时候。历史回顾:接手某大型项目后,老大让我负责了一个很复杂的逻辑程序---说白了就是算钱。逻辑太复杂了,看老代码都是03年以前的,而且中间改过好几个版本。这稍微改错一个地,客户就要么多收钱,要么就亏钱。说实在压力山大。刚开始在老的基础上改过一段时间,发现这程序越改越比牛车还慢。10万数据要1个半小时。实际使用将有1000万数据,客户要求1小时以内。这如何是好?最后实在没办法,重写,分成常驻程序。想法有了,加班加点,总算是改造成功了!拿去运行,速度只提升了一个数量级。后来公司高手推荐用ODP。由于没用过,这问题接二连三出现。

      ODP使用常见问题及解决方案

      1,ODP版本与开发端的Oracle客户端版本不一致。

      用select * from v$version;一查,我们服务器用的是11g 11.2.0.1.0,而我本地用的客户端是10g的。怕出问题,只好卸了10g,配上11g的客户端(Oracle的卸载也有不少学问,不知道的网上有很多资料)。版本是对了,可是客户端里面居然没带ODP.Net(我表示无语)。只好上官网下载,找了半天就是没有这11.2.0.1.0的ODP版本,这Oracle太坑人吧。这如何是好,客户已经在用这个版本了。人家上百台客户端总不可能为了这个全给升级吧。最后经过讨论把这程序放服务器端,在服务器端装个11.2.0.1.2的客户端版本。这回总算是同一版本了。

      2,开发IDE VS 2005及以上

      我们这项目都是用的Net 1.1+Vs 2003。在引用Oracle.DataAccess.dll类库时出错,加上错误信息又是日文。鬼才知道是啥意思。找个日本朋友看看也不明白啥意思。难题不断。看Oracle官网,10g都用到Vs 2005了。我想应该是开发IDE版本问题,就用Vs 2005试了下,结果正常引用。还好新做的程序是单独的,没辙只好将程序给升级到.Net 2.0。

      3,ODP是区分32/64位的

        以上的问题总算都解决了,然后查了点ODP使用,感觉和System.Data.OracleClient的使用差不多。就三下五除二改造完了,仔细测试了一通发现没问题,就发过去测试了。本想每晚11,12点下班的日子总算是要结束了,总算可以早点回去安心睡觉了。正要走人,客户一个电话@ODP无法使用,抛异常了!今晚必须解决!!@。天咋这么黑啊!经过百般调查,原来服务器是64位的------天咋越来越黑了!服务端64位,天啊!那得找个64位的开发电脑才行,还得下载个64位的ODP才行.............黑夜与我同行.......

      无奈,找来台裸机,安装开发环境。上官网下64位ODP,这坑人的Oracle居然没有11.2.0.1.2版本的。只好下个11.2.0.3.0的版本了,最后总算是程序编译搞定。客户怕又出啥问题,就叫我陪他去测试服务器搞定这程序。又是各种安装卸载,最后总算是完事了。看看时间半夜了......淡定.......

      ODP使用,虽然没长啥大经验,也算是一点点收获吧!下面讲讲实际如何使用Oracle.DataAccess.dll(要想以后更改数据底层方便,最好封装一个DB操作类)。

      先来几句Sql:

    INSERT INTO TS_ITEM(ITEM_CD) VALUES(:ITEM_CD)
    SELECT ITEM_CD  FROM TS_ITEM WHERE ITEM_CD BETWEEN :ITEMFROM AND :ITEMTO

      这Sql是不是很像我在第二篇MSDAORA Sql的参数传递方法中写的一样。确实是如此,而且使用极其相似。Sql具体特点请参照MSDAORA Sql的参数传递方法

      应用举例:

            /// <summary>
            /// 参数追加
            /// </summary>
            /// <param name="valName"> 参数名</param>
            /// <param name="var">参数値</param>
            /// <param name="valType">参数类型</param>
            public static void AddDbParameter(string valName, object var, OracleDbType valType)
            {
                OracleParameter p = new OracleParameter();
                p.ParameterName = valName;
                p.Direction = ParameterDirection.Input;
                p.OracleDbType = valType;
                p.IsNullable = true;
                p.Value = var;
                DbCommand.Parameters.Add(p);
            }
            /// <summary>
            /// 数据取得
            /// </summary>
            /// <param name="i_ItemFrom">項目From</param>
            /// <param name="i_ItemTO">項目To</param>
            /// <returns></returns>
            public static DataTable GetData(string i_ItemFrom,string i_ItemTO)
            {
                ODPParModel.PreProcess();
                ODPParModel.PrepareDbSql(DBSql.ODPSelSql);
                ODPParModel.AddDbParameter("ITEMFROM", i_ItemFrom, OracleDbType.Varchar2);
                ODPParModel.AddDbParameter("ITEMTO", i_ItemTO, OracleDbType.Varchar2);
    
                return ODPParModel.GetDataSet("M_ITEM").Tables[0];
            }

       存储过程也是如此使用,只是CommandType不一样而已。

    DbCommand.CommandType = CommandType.StoredProcedure;

      总结下优缺点:

      优点:1,能够充分利用Oracle数据库资源,速度极快。

          2,在缓存没清除的情况下,此Sql数据库只需解析一次,再次执行此Sql时速度将更快。

          3,传入参数顺序没要求,只要名字对应上就可以。

          4,数据类型和Oracle数据库定义的完全一致。

      缺点: 只能用于Oracle数据库

           其他优缺点等大虾提供了。

    附加ODP DBHelper类(精简版):

    ODP DBHelper
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Data;
    
    using Oracle.DataAccess.Client;
    using Oracle.DataAccess.Types;
    
    namespace DBPar.Models
    {
        public class ODPParModel
        {
            public static OracleConnection DbConnection;
    
            public static OracleTransaction transaction;
    
            public static OracleCommand DbCommand;
    
            public static OracleDataReader DbDataReader;
    
            public static OracleDataAdapter DbDataAdapter;
    
            /// <summary>
            /// DB连接
            /// </summary>
            public static void PreProcess()
            {
                if (string.IsNullOrEmpty(DBConfig.ODP_DBConnectionString))
                {
                    DBConfig.Init();
                }
    
                if (DbConnection == null)
                {
                    try
                    {
                        DbConnection = new OracleConnection(DBConfig.ODP_DBConnectionString);
                        DbConnection.Open();
                    }
                    catch (InvalidOperationException)
                    {
    
                        throw new Exception("Config连接未设定" + DBConfig.ODP_DBConnectionString);
                    }
                }
    
                if (transaction == null)
                {
                    if (DbConnection.State != System.Data.ConnectionState.Open)
                    {
                        DbConnection.Open();
                    }
    
                    transaction = DbConnection.BeginTransaction();
                }
            }
    
            public static void EndProcess()
            {
                if (DbDataReader != null)
                {
                    if (!DbDataReader.IsClosed)
                    {
                        DbDataReader.Close();
                    }
                    DbDataReader = null;
                }
                if (DbCommand != null)
                {
                    DbCommand.Dispose();
                    DbCommand = null;
                }
                if (transaction != null)
                {
                    transaction.Commit();
                    transaction = null;
                }
            }
    
            public static void PrepareDbSql(string sql)
            {
                if (DbCommand != null)
                {
                    DbCommand.Dispose();
                }
                DbCommand = new OracleCommand(sql, DbConnection);
            }
    
            /// <summary>
            /// 参数追加
            /// </summary>
            /// <param name="valName"> 参数名</param>
            /// <param name="var">参数値</param>
            /// <param name="valType">参数类型</param>
            public static void AddDbParameter(string valName, object var, OracleDbType valType)
            {
                OracleParameter p = new OracleParameter();
                p.ParameterName = valName;
                p.Direction = ParameterDirection.Input;
                p.OracleDbType = valType;
                p.IsNullable = true;
                p.Value = var;
                DbCommand.Parameters.Add(p);
                
            }
    
            public static DataSet GetDataSet(string tablename)
            {
                DataSet ds = new DataSet();
                OracleDataAdapter adapter = new OracleDataAdapter();
                adapter.SelectCommand = DbCommand;
                adapter.Fill(ds, tablename);
    
                return ds;
            }
    
            public static int ExecuteDbUpdate()
            {
                return DbCommand.ExecuteNonQuery();
            }
        }
    }

    程序开发,终究是条无止境的路----

    上一篇:MSDAORA Sql的参数传递方法

    每天成就一小步,积累下来就是一大步。 转发本文请注明出处,谢谢您的阅读与分享!
  • 相关阅读:
    修改代码一般在测试服务器
    人很臭尽量往香里去做...
    救赎
    写的css十个错误
    如何debug看源代码
    办公室倒水
    程序和思维
    mousewheel.js 和scroll api
    drupal.behavior 和 document.ready 没有直接的关系
    revision in drupal
  • 原文地址:https://www.cnblogs.com/lixiaobin/p/ODP.html
Copyright © 2011-2022 走看看