当前位置:编程技术网 > 技术文章 > 简明扼要的掌握ado.net框架 > 文章详细内容

学习ado.net(5):调用存储过程 2-2

还有一些系统,数据访问全部采用存储过程的情况,那就对调用的要求是越方便越好, 也就是我们常说的调用存储过程的通用类:

首先看调用代码:
   object[] parms = new object[3]; //存储过程有几个参数, 就声明几个元素的对象数组
   parms[0] = 值1; //输入参数则直接赋值
   parms[1] = 值2;
   ExeProc dao= new ExeProc("connectionstring");
   DataTable dt = new DataTable();
   dao.Execute("存储过程名", parms, dt);
   输出参数的值= Convert.ToInt32(parms[2]);
   return dt;

这个调用代码看了之后,发现里面简单就在于调用存储过程的时候不需要写存储过程参数的名字,那这个dao.Execute执行的时候在哪儿得到的存储过程参数的名字呢,当然只有1个方法,就是读数据库的字典表了。下面是完整的代码:

/// <summary>

/// ExeProc的摘要说明。

/// </summary>

public  class ExeProc

{

       private SqlConnection conn;

       private SqlCommand cmd;

       public ExeProc( string connStr)

       {

              conn = new SqlConnection(connStr);

              cmd = new SqlCommand();

              cmd.Connection = conn;

       }

 

 

       #region 执行存储过程的2个方法

       /// <summary>

       /// 执行存储过程

       /// </summary>

       /// <param name="procName">存储过程名</param>

       /// <param name="objA">参数值数组</param>

       /// <param name="dt">取值的容器</param>

       public void Execute(string procName, object[] objA, DataTable dt)

       {

              SqlParameter[] parmA = ObjArrayToParmArray(procName, objA); //把一个对象数组转换成一个参数数组                   

              cmd.Parameters.Clear();//SqlCommand中的数据清空

              cmd.CommandText = procName;

              cmd.CommandType = CommandType.StoredProcedure;

              for(int i = 0 ; i < parmA.Length; i++)

                     cmd.Parameters.Add(parmA[i]);

 

              SqlDataAdapter ada = new SqlDataAdapter(cmd);

              ada.Fill(dt);

 

              //给输出参数赋值

              for(int i = 0 ; i < parmA.Length; i++)

              {

                     if (parmA[i].Direction == ParameterDirection.Output)

                            objA[i] = parmA[i].Value;

              }

              ada.Dispose();

       }

 

       /// <summary>

       /// 执行存储过程

       /// </summary>

       /// <param name="procName">存储过程名</param>

       /// <param name="objA">参数值数组</param>

       public void Execute(string procName, object[] objA)

       {

              SqlParameter[] parmA = ObjArrayToParmArray(procName, objA);               

              cmd.Parameters.Clear();

              cmd.CommandText = procName;

              cmd.CommandType = CommandType.StoredProcedure;

 

              for(int i = 0 ; i < parmA.Length; i++)

                     cmd.Parameters.Add(parmA[i]);

 

              cmd.ExecuteNonQuery();

 

              //给输出参数赋值

              for(int i = 0 ; i < parmA.Length; i++)

              {

                     if (parmA[i].Direction == ParameterDirection.Output)

                            objA[i] = parmA[i].Value;

              }

       }

       #endregion

 

       #region 对象数组 转换成 参数数组

       /// <summary>

       /// 对象数组 转换成 参数数组

       /// </summary>

       /// <param name="procName">存储过程名</param>

       /// <param name="objA">对象数组</param>

       /// <param name="parmA">参数数组</param>

       private SqlParameter[] ObjArrayToParmArray(string procName, object[] objA)

       {

              string sqlStr = "select"

                     + "  syscolumns.name as ParameterName,"                      //            参数名

                     + "  systypes.name as ParameterType,"                                   //            参数类型                           

                     + "  syscolumns.length as ParameterLength,"                   //            参数长度

                     + "  syscolumns.xscale as ParameterDecimalDigits,"         //            小数位数

                     + "  syscolumns.isoutparam as IsOutputParameter"           //            是否是输出参数

                     + " from"

                     + "  syscolumns,"

                     + "  systypes"

                     + " where"

                     + "  syscolumns.id=object_id('" + procName + "')" // 存储过程名

                     + " and"

                     + "  systypes.xtype=syscolumns.xtype ORDER BY syscolumns.colid";

              //ORDER BY syscolumns.colid 一定要注意排序。否则,参数顺序是乱的。

 

              SqlDataAdapter dataAda = new SqlDataAdapter(sqlStr, conn);

              DataTable dt = new DataTable();

              dataAda.Fill(dt);

             

              SqlParameter[] parmA = new SqlParameter[dt.Rows.Count];

 

              if (parmA.Length != objA.Length)

                     throw new ApplicationException("存储过程调用异常,参数设置不匹配!");

 

              for(int i = 0 ; i < parmA.Length; i++)

              {

                     parmA[i] = new SqlParameter();

 

                     parmA[i].ParameterName = dt.Rows[i]["ParameterName"].ToString();

                     parmA[i].SqlDbType = GetSqlDBTypeFromName(dt.Rows[i]["ParameterType"].ToString());

                     parmA[i].Size = Convert.ToInt32(dt.Rows[i]["ParameterLength"].ToString());

                     parmA[i].Scale = Convert.ToByte(dt.Rows[i]["ParameterDecimalDigits"].ToString());

                     //如果是输出参数,旧给它赋值

                     if (dt.Rows[i]["IsOutputParameter"].ToString() == "1")

                            parmA[i].Direction = ParameterDirection.Output;

                     else

                     {

                            parmA[i].Direction = ParameterDirection.Input;

                            parmA[i].Value = objA[i];

                     }

              }

 

              dt.Dispose();

              dataAda.Dispose();

              return parmA;

       }

       #endregion

 

       #region 根据DotNet参数类型 获取 SqlDbType类型

       /// <summary>

       /// 根据DotNet参数类型 获取 SqlDbType类型;默认值为SqlDbType.VarChar

       /// </summary>

       /// <param name="typename">DotNet类型字符串</param>

       /// <returns>SqlDbType</returns>

       private SqlDbType GetSqlDBTypeFromName(string typeName)

       {

              SqlDbType dbtype = SqlDbType.VarChar;

              if (typeName == "varchar")

              {

                     dbtype = SqlDbType.VarChar;

              }

              if (typeName == "int")

              {

                     dbtype = SqlDbType.Int;

              }

              if (typeName == "money")

              {

                     dbtype = SqlDbType.Money;

              }

              if (typeName == "decimal")

              {

                     dbtype = SqlDbType.Decimal;

              }

              if (typeName == "datetime")

              {

                     dbtype = SqlDbType.DateTime;

              }

              if (typeName == "bit")

              {

                     dbtype = SqlDbType.Bit;

              }

              if (typeName == "nchar")

              {

                     dbtype = SqlDbType.NChar;

              }

              return dbtype;

       }

       #endregion

 

       #region IDisposable 成员

       public void Dispose()

       {

              conn.Close();

              cmd.Dispose();

              conn.Dispose();

       }

       #endregion

}

作者|来源:原创(17fx.net)发表于:2009-1-1 21:27:04