存储过程
一、定义
百度百科版:一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。
人话版:存储过程就是一段保存在数据中的SQL语句,然后给这个语句块起个名字,下次需要可直接调用。
选用存储过程可以减少网络通讯量,SQL发送到数据库,数据库也会按照自己的优化方式进行优化后执行的,使用存储过程将SQL语句存到数据库,使用时执行效率更高,而且更新时实时生效,比修改代码方便。
二、语法-以MySQL为例
创建:创建存储过程参数可以没有,也可以设置输入、输出参数,分别用in和out
mysql> delimiter // mysql> CREATE PROCEDURE simpleproc (OUT param1 INT) -> BEGIN -> SELECT COUNT(*) INTO param1 FROM t; -> END -> // Query OK, 0 rows affected (0.00 sec)
修改:alter procedure 存储过程名称 SQL语句块
删除:
DROP PROCEDURE IF EXISTS 存储过程名
eg:DROP PROCEDURE IF EXISTS proc_employee
存储过程参数: in out inout
MySQL 存储过程 “in” 参数:跟 C 语言的函数参数的值传递类似, MySQL 存储过程内部可能会修改此参数,但对 in 类型参数的修改,对调用者(caller)来说是不可见的(not visible);
MySQL 存储过程 “out” 参数:从存储过程内部传值给调用者。在存储过程内部,该参数初始值为 null,无论调用者是否给存储过程参数设置值;
MySQL 存储过程 inout 参数跟 out 类似,都可以从存储过程内部传值给调用者。不同的是:调用者还可以通过 inout 参数传递值给存储过程。
三、例子
带输出参数的存储过程:
--删除存储过程 DROP PROCEDURE IF EXISTS proc_employee_getCount --创建存储过程 CREATE PROCEDURE proc_employee_getCount(out n int) BEGIN SELECT COUNT(*) FROM employee ; END --MYSQL调用存储过程 CALL proc_employee_getCount(@n);
带输入参数的存储过程:
--删除存储过程 DROP PROCEDURE IF EXISTS proc_employee_findById; --创建存储过程 CREATE PROCEDURE proc_employee_findById(in n int) BEGIN SELECT * FROM employee where id=n; END --定义变量 SET @n=1; --调用存储过程 CALL proc_employee_findById(@n);
JDBC调用存储过程
//Java调用输入参数的存储过程 public void executeProcedure(){ try { /** *callableStatementjava.sql.CallableStatement *connectionjava.sql.Connection *jdbc调用存储过程原型 *{call存储过程名(参数列表1,参数列表2)}可用?代替 */ CallableStatement callableStatement=connection.prepareCall("{call proc_employee_findById(?)}"); callableStatement.setInt(1, 1); //给第一个参数设置值-设置输入参数 resultSet=callableStatement.executeQuery();//执行存储过程 if(resultSet.next()){ System.out.println(resultSet.getInt(1)+""t"+resultSet.getString(2)); } } catch (SQLException e) { e.printStackTrace(); } } }
//Java调用输出参数的存储过程 public void executeProcedure(){ try { /** *callableStatementjava.sql.CallableStatement *connectionjava.sql.Connection *jdbc调用存储过程原型 *{call存储过程名(参数列表1,参数列表2)}可用?代替 */ CallableStatement callableStatement=connection.prepareCall("{call proc_employee_getCount(?)}"); //设置输出参数 callableStatement.registerOutParameter(1, Types.INTEGER); //执行存储过程 resultSet=callableStatement.executeQuery(); if(resultSet.next()){ System.out.println(resultSet.getInt(1)); } } catch (SQLException e) { e.printStackTrace(); } }