云中客

梦想有多大,就能走多远

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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

posted on 2013-03-07 17:19  走遍江湖  阅读(1318)  评论(1编辑  收藏  举报