zoukankan      html  css  js  c++  java
  • 存储过程调用

    # SQL语句:先编译后执行

    存储过程(Stored Procedure):

      一组可编程的函数,是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

    优点(为什么要用存储过程?):

      ①将重复性很高的一些操作,封装到一个存储过程中,简化了对这些SQL的调用

      ②批量处理:SQL+循环,减少流量,也就是“跑批”

      ③统一接口,确保数据的安全

    相对于oracle数据库来说,MySQL的存储过程相对功能较弱,使用较少。

     

    一、存储过程的创建和调用

      >存储过程就是具有名字的一段代码,用来完成一个特定的功能。

      >创建的存储过程保存在数据库的数据字典中。

      public DataSet Query(string procName, ref int Total, SqlParameter[] sqlParameters)
            {
                DataSet set = new DataSet();
                using (SqlConnection conn = new SqlConnection(con))
                {
                    conn.Open();
                    using (SqlCommand comm = new SqlCommand(procName, conn))
                    {
                        comm.Parameters.AddRange(sqlParameters);
                        comm.CommandType = CommandType.StoredProcedure;
                        SqlDataAdapter adapter = new SqlDataAdapter(comm);
                        adapter.Fill(set);
                        Total = int.Parse(comm.Parameters["@Total"].Value.ToString());
                    }
                }
                return set;
            }

    下面这个例子展示如何在ADO.NET调用存储过程。我只选择了一种方式,说实话不太喜欢多样化的方式去处理问题,这种发散式的做法在编程中似乎没有必要。选择自己喜欢的一种方式。

    这里SQL Server有一个样本数据库Northwind.

    以Northwind里的Region表为例:

    Region表有2个字段:

    • RegionID, int 主键
    • RegionDescription, nchar(50)

    写以下几个存储过程:

    RegionUpdate: 多个参数

    CREATE PROCEDURE RegionUpdate(@RegionID INTEGER, @RegionDescription NCHAR(50))
    AS
    SET NOCOUNT OFF
    UPDATE Region
    SET RegionDescription = @RegionDescription
    WHERE RegionID = @RegionID
    GO

    RegionDelete 一个参数

    CREATE PROCEDURE RegionUpdate(@RegionID INTEGER)
    AS
    SET NOCOUNT OFF
    DELETE FROM Region
    WHERE RegionID = @RegionID
    GO
    

    RegionInsert 带返回参数

    CREATE PROCEDURE RegionInsert(@RegionDescription NCHAR(50), @RegionID INTEGER OUTPUT)
    AS
    SET NOCOUNT OFF
    SELECT @RegionID = MAX(RegionID) + 1 
    FROM Region
    INSERT INTO Region VALUES(@RegionID, @RegionDescription)
    GO
    

     

    public DataTable GetPagingDept(ref int Total, int pageSize, int pageNumber, string where, string field)
            {
                SqlParameter[] sqlParameters = new SqlParameter[]
                    {
    new SqlParameter{ ParameterName="@table",Value=" Shopping ",SqlDbType=SqlDbType.NVarChar,Direction= ParameterDirection.Input,Size=200},
    new SqlParameter{ ParameterName="@field",Value=field,SqlDbType=SqlDbType.NVarChar,Direction= ParameterDirection.Input,Size=2000},
    new SqlParameter{ ParameterName="@where",Value=where,SqlDbType=SqlDbType.NVarChar,Direction= ParameterDirection.Input,Size=2000},
    new SqlParameter{ ParameterName="@order",Value=" Id ",SqlDbType=SqlDbType.NVarChar,Direction= ParameterDirection.Input,Size=200},
    new SqlParameter{ ParameterName="@pageSize",Value=pageSize,SqlDbType=SqlDbType.Int,Direction= ParameterDirection.Input},
    new SqlParameter{ ParameterName="@pageNumber",Value=pageNumber,SqlDbType=SqlDbType.Int,Direction= ParameterDirection.Input},
    new SqlParameter{ ParameterName="@Total",SqlDbType=SqlDbType.Int,Direction= ParameterDirection.Output},
                    };
                return db.Query("[SP_UserInfo]", ref Total, sqlParameters).Tables[0];
            }
    我假设我们已经对IDataParameter对象进行了封装,我想对它简单的封装基本也都能满足日常要求了。一般都是根据当前项目链接数据库的类型字符串进行判断,然后生成相对应如:SqlParameter、OracleParameter、OleDbParameter等等,可能还包括一些开源的数据库扩展框架中的对象,这里的创建工厂可能是抽象工厂,当然方法很多种,实现效果就行。[王清培版权所有,转载请给出署名]
    对其简单的封装我们在使用的时候需要使用工厂方法创建IDataParameter数组,如:

      

    一般性的封装基本都这样或者在IDataParameterFactory.CreateDbDataParameter(Entity)中加入根据实体的属性动态的创建IDataParameter[]对象,如果你的创建始终是使用反射的话那么将是不可取的。有兴趣的朋友可以参见本人的另一篇文章“利用抽象、多态实现无反射的绿色环保ORM框架”对实体的使用如果不能摆脱反射,那么在以后的基础库扩展中将面临着很多性能问题,这里需三思。

    由于很少存储过程的参数名称都是对应的实体的属性名称,这种对应关系很难做到,或者说是做到的话需要DBA花点时间呢,在命名上也是个约束。
    如果存储过程有N个参数的话我们需要对照数据库设计文档来编写IDictionary项,在一般的项目中都将复杂的业务逻辑封装在存储过程中实现,所以存储过程的数量也是不少的。这样一来也算是一个比较浪费时间的工作。
    那么如果减少编码量,让存储过程的调用变的简单,而且对用户来说是透明的?
    public IHttpActionResult Show(int pageSize, int pageNumber,string name)
            {
                int Total = 0;
                if (!string.IsNullOrEmpty(name))
                {
                    Total = 0;
                    name = " Sho_Name like '%" + name + "%'";
                }
                else
                {
                    name = " 1=1 ";
                }
                        
                DataTable tb = bll.GetPagingDept(ref Total, pageSize, pageNumber, name, " * ");
                PagingModel<DataTable> paging = new PagingModel<DataTable> { tb = tb, Total = Total };
                return Ok(paging);
                
            }
  • 相关阅读:
    FreeBSD使用多线程下载工具axel
    类UNIX系统基础:文件安全与权限
    基于pf防火墙控制IP连接数
    在FreeBSD下搭建高性能企业级网关与代理服务器
    搭建自己的CVSup服务器
    转:Spring技术内幕——深入解析Spring架构与设计原理(三)IOC实现原理
    Spring Web MVC的实现(二)
    java中HashSet详解
    转:Spring技术内幕——深入解析Spring架构与设计原理(二)IOC实现原理
    DIV垂直水平都居中
  • 原文地址:https://www.cnblogs.com/ntg2/p/13084330.html
Copyright © 2011-2022 走看看