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的参数传递方法

    每天成就一小步,积累下来就是一大步。 转发本文请注明出处,谢谢您的阅读与分享!
  • 相关阅读:
    父子进程 signal 出现 Interrupted system call 问题
    一个测试文章
    《淘宝客户端 for Android》项目实战 html webkit android css3
    Django 中的 ForeignKey ContentType GenericForeignKey 对应的数据库结构
    coreseek 出现段错误和Unigram dictionary load Error 新情况(Gentoo)
    一个 PAM dbus 例子
    漫画统计学 T分数
    解决 paramiko 安装问题 Unable to find vcvarsall.bat
    20141202
    js
  • 原文地址:https://www.cnblogs.com/lixiaobin/p/ODP.html
Copyright © 2011-2022 走看看