一 使用时机:地址:
1.当一个事务涉及到多个SQL语句时或者涉及到对多个表的操作时;
2.当在一个事务的完成需要很复杂的商业逻辑时(比如,对多个数据的操作,对多个状态的判断更改等);
3.还有就是比较复杂的统计和汇总也要考虑;
4.复杂的数据处理用存储过程,如有些报表处理
5.多条件多表联合查询,并做分页处理
6.当一个业务同时对多个表进行处理的时候采用存储过程比较合适。
为什么使用存储过程:
1.存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般 SQL 语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
2.当对数据库进行复杂操作时(如对多个表进行 Update,Insert,Query,Delete 时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。这些操作,如果用程序来完成,就变成了一条条的 SQL 语句,可能要多次连接数据库。而换成存储,只需要连接一次数据库就可以了。
3.存储过程可以重复使用,可减少数据库开发人员的工作量。
4.安全性高,可设定只有某此用户才具有对指定存储过程的使用权。
三 优缺点
优点:
1.速度快。尤其对于较为复杂的逻辑,减少了网络流量之间的消耗
我有的过程和函数达到了几百行,一个微型编译器,相信用程序就更麻烦了。
2.写程序简单,采用存储过程调用类,调用任何存储过程都只要1-2行代码。
(我不知道别人怎么调用,我是深受其益)
3.升级、维护方便
4.调试其实也并不麻烦,可以用查询分析器
5.如果把所有的数据逻辑都放在存储过程中,那么asp.net只需要负责界面的显示阿什么的,出错的可能性最大就是在存储过程。我碰到的就一般是这种情况。
缺点:
1.可移植性差,我一直采用sql server开发,可是如果想卖自己的东西,发现自己简直就是在帮ms卖东西,呵呵。想换成mysql,确实移植麻烦。
2.采用存储过程调用类,需要进行两次调用操作,一次是从sql server中取到过程的参数信息,并且建立参数;第二次才是调用这个过程。多了一次消耗。
不过这个缺点可以在项目开发完成,过程参数完全确定之后,把所有过程参数信息倒入到一个xml文件中来提高性能。
- 使用存储过程在一般情况下会提高性能,因为数据库优化了存储过程的数据访问计划并应用缓存方便以后的查询;
- 存储过程单独保护存在于数据库中。客户端可以获取权限执行存储过程,而不需要对底层的具体表设置其他的访问权限;
- 存储过程会使得维护起来更加方便,因为通常修改一个存储过程要比在一个已经发布的组件中修改SQL语句更加方便;
- 存储过程给底层数据格式增添了额外的抽象层。使得使用存储过程的客户端对存储过程的实现细节以及对底层数据格式是隔离独立的;
- 存储过程能够缓解网络带宽,因为可以批量执行SQL语句而不是从客户端发送超负载的请求。
java调用 地址:
//加载驱动
DriverManager.registerDriver(new sun.jdbc.odbc.JdbcOdbcDriver());
//获得连接
Connection conn=DriverManager.getConnection("jdbc:odbc:mydata","sa","");ModPro存储过程名
CallableStatement c=conn.prepareCall("{call ModPro(?,?)}");
c.setInt(1,2);
c.setString(2,"美女");
c.execute();//执行
c=conn.prepareCall("{call selePro}");
ResultSet rs=c.executeQuery();//结果集
while(rs.next())//遍历出数据
{
String Stu=rs.getString("StuID");
String name=rs.getString("StuName");
String add=rs.getString("StuAddress");
System.out.println ("学号:"+" "+"姓名:"+" "+"地址");
System.out.println (Stu+" "+name+" "+add);
}
c.close();
五 mybatis 存储过程
1.创建存储过程
DROP PROCEDURE IF EXISTS `countDevicesName`;
DELIMITER ;
CREATE PROCEDURE `countDevicesName`(IN,OUT deviceCount INT)
BEGIN
SELECT COUNT(*) INTO deviceCount FROM cus_device WHERE device_name = dName;
END;
DELIMITER ;
2.mybatis 调用存储过程
<select id="count" parameterType="java.lang.String" useCache="false" statementType="CALLABLE"><!--注明statementType="CALLABLE"表示调用存储过程-->
<!--/**countDevicesName 存储过程名称**/ -->
<![CDATA[
call countDevicesName( #{devoceName,mode=IN,jdbcType=VARCHAR},#{deviceCount,mode=OUT,jdbcType=INTEGER});
]]>
</select>