
源码仓库Gitee·GitHub存储过程对sql的封装和重用经编译创建并保存在数据库中通过指定存储过程的名字并给定参数(需要时)来调用执行。优缺点1 优点执行速度快------存储过程只在创建时进行编译以后每次执行存储过程都不需要重新编译而一般SQL语句每执行一次就需编译一次所以使用存储过程可提高数据库的执行速度减少网络通信量------当对数据库进行复杂操作时如对多个表进行insert、update、select、delete时可将这些复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。这些操作如果用程序完成就是多条SQL语句可能要多次连接数据库而换成存储过程只需一次连接。更强的适应性与复用性------存储过程可以重复使用提高了可重用性减少数据库开发人员的工作量。可维护性高------更新存储过程通常比更改、测试以及重新部署程序集需要较少的时间和精力。安全性高可设定只有某用户才能对指定存储过程的使用权且存储过程比多条sql稳定只要数据库不出现问题基本上是不会出现什么问题的同时可以防止 SQL注入。2 缺点开发调试差无良好的IDE开发工具存储过程的调试比一般SQL要复杂的多。可移植性差由于存储过程将应用程序绑定到数据库上因此使用存储过程封装业务逻辑将限制应用程序的可移植性如果应用程序进行数据源的切换Mysql--Orcle)需重新编写存储过程。不支持群集数据库服务器无法水平扩展或者数据库的切割水平或垂直切割。数据库切割之后存储过程并不清楚数据存储在哪个数据库中。存储过程的创建create procedure 存储过程名 ([参数列表]) begin sql 语句 end;参数列表的格式[类型限定 变量名 数据类型] 5.7的发现参数数据类型长度必须声明不然sql编译不过参数列表有自己的类型限定这个类型限定与数据类型不同它是限定参数的作用范围in:限定这个参数是传值给存储过程,既然是传值所以可以是变量或常量数据【in修饰的参数一般是传入存储过程中作为某些条件的不会被存储过程修改】out:限定这个参数是存储过程传出的一个值因为有值的返回所以这个参数必须是一个变量【存储过程中会给out修饰的变量赋值使得过程外部可以获取这个更改的值】inout:inout是上面两者的叠加,既可以被存储过程内部使用又可以修改后被外部使用,因为有值的返回所以这个参数必须是一个变量理论上对于希望简洁代码的地方都可以使用存储过程来处理比如希望快速使用多条select,又比如希望从数据中取出多个值赋值给变量所以下面只给出用法应用场景就不讲述了。不传入参数只执行某些特定代码传入参数并利用参数作为条件执行代码传入参数并利用参数作为条件执行代码同时利用变量获取结果。存储过程的使用调用存储过程call 存储过程名();带参数的调用存储过程call 存储过程名(参数);对于in类型的参数可以是数值可以是变量对于out\inout类型的参数必须是变量所有MySQL变量都必须以 开始示例call myselect(lilei,变量名);示例call myselect(变量名,变量名)实例-- 无参创建 CREATE PROCEDURE demo1() BEGIN SELECT * from cli_txinfo LIMIT 1; end; -- 调用输出查询结果 call demo1(); -- 2.有参创建格式为in 参数名 类型长度.... -- 单参demo2(in tableName varchar(20)) -- 多参demo2(in tableName varchar(20),name varchar(40)) create procedure demo2(in tableName varchar(20),name varchar(40)) BEGIN SELECT * from cli_txinfo where txname name LIMIT 1; end; -- 调用输出查询结果 call demo2(abc001,专属顾问绑定申请列表查询); --3.有参创建值返回格式为out 参数名 类型长度 create procedure demo3(in tx varchar(20),out otx varchar(20)) begin SELECT txname from cli_txinfo where txcode tx into otx; end; -- 调用输出结果存储到tx中只显示sql的执行情况没有输出操作结果变量命名必须以开头 -- call demo3(abd002,tx); ----编译错误 call demo3(abd002,tx); -- 变量传参格式为 set 变量名 值 -- set a abd002; -- call demo3(a,tx); -- 查询输出结果变量名的值 SELECT tx; -- 存储过程的复杂sql语句 create procedure demo4() begin SELECT * from cli_txinfo limit 1; select * from cli_role limit 1; END; demo call demo4; -- 动态传入表名案例以两个数据库进行表的同步 -- 使用CONCAT进行sql的拼接拼接处必须留有空格比如 concat(insert into )不然拼接无法识别参数 -- prepare预处理execute 执行DEALLOCATE PREPARE释放资源 create procedure demo5(in syncTable varchar(20)) BEGIN set deleteSql CONCAT(truncate table keyun.,syncTable); set insertSql CONCAT(insert into keyun.,syncTable, SELECT distinct * ,from keyun_sync.,syncTable); prepare delstmt from deleteSql; prepare insstmt from insertSql; execute delstmt; execute insstmt; DEALLOCATE PREPARE delstmt; DEALLOCATE PREPARE insstmt; end; -- 调用输出查询结果 call demo5(third_binding);6.查看存储过程查看存储过程的创建语句show create procedure 存储过程名;查看存储过程状态show procedure status;【显示的内容包括创建时间、注释、定义的用户、安全类型等等】7.修改存储过程修改存储过程只能修改那些选项并不能修改传入传出参数或者sql语句。alter procedure 存储过程名 选项8.删除存储过程语法drop procedure 存储过程名;示例drop procedure demo1;9.MyBatis实战使用//Service业务层 MapString, Object param new HashMapString, Object(); param.put(YPID, ypId); factory.yearPlanMapper.updArrAndLeav(param); Date arriveTime (Date) param.get(arrive_time); Date leaveTime (Date) param.get(leave_time); //Dao数据层 void updArrAndLeav(MapString, Object param); //MyBatis的xmlin参数out返回值 select idupdArrAndLeav statementTypeCALLABLE {call usp_update_year_date_formal( #{YPID,modeIN,jdbcTypeNVARCHAR}, #{arrive_time,modeOUT,jdbcTypeDATE}, #{leave_time,modeOUT,jdbcTypeDATE} )} /select