定义:
我的理解就是将sql语句 放到一起定义可以用来使用;它中间是可以添加一些特殊的方法和语句块。
特点:
1.灵活性:可以用流程控制语句编写,也可以像java方法那样封装起来多个sql语句实现一个复杂的功能,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
2.重复性:存储过程在创建以后就永久的保存到了数据库中,可以随时调用,方便快捷。
3.高效性:存储过程在刚被创建以后就会编译,以后每次使用不会再次编译,SQL语句在每次运行时都要进行编译和优化,提高运行效率。
4安全性:系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。
一、CREATE PROCEDURE (创建)
1.定义格式:
CREATE + PROCEDURE 存储过程名(参数列表)
BEGIN
SQL语句代码块
END
调用:
CALL + 存储过程名(参数列表);
2.例子:
mysql>DELIMITER //
mysql>CREATE PROCEDURE proc1()
->BEGIN
-> SELECT COUNT(*) FROM user;
->END
->//
mysql>DELIMITER ;
mysql>CALL proc1();
注:
(1)
DELIMITER(后面跟的符号 // ; ) :
两句,DELIMITER是分割符的意思,因为MySQL默认以";"为分隔符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字申明当前段分隔符,这样MySQL才会将";"当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。
(2)过程体的开始与结束使用BEGIN与END进行标识。
3.查看存储过程命令:
1.show procedure status
显示数据库中所有存储的存储过程基本信息,包括所属数据库,存储过程名称,创建时间等
2.show create procedure sp_name
显示某一个MySQL存储过程的详细信息
3.删除存储过程
DROP PROCEDURE IF EXISTS sp_name
二、存储过程几种
MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT,形式如:
CREATE PROCEDURE([[IN |OUT |INOUT ] 参数名数据类形...])
IN输入参数:
表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
OUT 输出参数:
该值可在存储过程内部被改变,并可返回
INOUT 输入输出参数:
调用时指定,并且可被改变和返回
1.多参数的例子:
mysql> CREATE PROCEDURE proc_all(IN p int, OUT c int)
-> BEGIN
-> SELECT MAX(e_salary) INTO c FROM employe WHERE e_no=p;
-> END
-> //
Query OK, 0 rows affected
mysql> DELIMITER ;
mysql> select * from employe;
+------+--------+-------+---------+----------+----------+-----------+
| e_no | e_name | e_sex | dept_no | e_job | e_salary | hire_date |
+------+--------+-------+---------+----------+----------+-----------+
| 1001 | 李强 | 1 | 20 | 会计 | 800 | 2015-9-9 |
| 1002 | 王刚 | 1 | 30 | HR | 1600 | 2014-10-9 |
| 1003 | 姗姗 | 0 | 30 | HR | 1250 | 2014-11-7 |
| 1004 | 张阳 | 1 | 20 | 出纳 | 2975 | 2015-4-9 |
| 1005 | 小丽 | 0 | 40 | 销售经理 | 2850 | 2015-2-10 |
| 1006 | 王二 | 1 | 10 | 产品策划 | 2450 | 2015-4-23 |
| 1007 | 小冬 | 1 | 40 | 销售经理 | 2750 | 2015-3-10 |
+------+--------+-------+---------+----------+----------+-----------+
7 rows in set
mysql> set @p=1002;
Query OK, 0 rows affected
mysql> CALL proc_all(@p,@c);
Query OK, 0 rows affected
mysql> SELECT @c AS 对应工资;
+----------+
| 对应工资 |
+----------+
| 1600 |
+----------+/**
* 如何在程序中实现储存过程proc_all(IN p int, OUT c int)(两个参数)上表为对应的mysql数据库操作过程
*/
public void executeProcedureInOut(){
String sql = "CALL proc_all(?,?)";
Connection connect = null;
CallableStatement cs = null;
try {
connect=ConnectDB.getConnection();//这里的getConnection方法是我自己封装的一个静态方法,作用是用来建立连接
cs = connect.prepareCall(sql);
cs.setInt(1, 1002); //设置输入参数
cs.registerOutParameter(2, Types.INTEGER); //设置输出参数类型
cs.execute();
int max = cs.getInt(2); //第2参数据为输出参数,用第2个输出参数接收返回结果
System.out.println("编号1002对应工资="+ max);
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (cs != null)
cs.close();
} catch (SQLException e) {
e.printStackTrace();
}
ConnectDB.closeConnection(connect);//这里是关闭连接
}
}
对应输出的结果为如下
编号1002对应工资=1600
2.无参数例子:
mysql>DELIMITER //
mysql>CREATE PROCEDURE proc1()
->BEGIN
-> SELECT * FROM employe;
->END
->// Query OK, 0 rows affected
mysql> DELIMITER ;mysql> CALL p_addms;
+------+--------+-------+---------+----------+----------+-----------+
| e_no | e_name | e_sex | dept_no | e_job | e_salary | hire_date |
+------+--------+-------+---------+----------+----------+-----------+
| 1001 | 李强 | 1 | 20 | 会计 | 800 | 2015-9-9 |
| 1002 | 王刚 | 1 | 30 | HR | 1600 | 2014-10-9 |
| 1003 | 姗姗 | 0 | 30 | HR | 1250 | 2014-11-7 |
| 1004 | 张阳 | 1 | 20 | 出纳 | 2975 | 2015-4-9 |
| 1005 | 小丽 | 0 | 40 | 销售经理 | 2850 | 2015-2-10 |
| 1006 | 王二 | 1 | 10 | 产品策划 | 2450 | 2015-4-23 |
| 1007 | 小冬 | 1 | 40 | 销售经理 | 2750 | 2015-3-10 |
+------+--------+-------+---------+----------+----------+-----------+
7 rows in set
Query OK, 0 rows affected
对应的程序实现为:/**
* 显示所有的员工的信息
*/
public void startCall(){
String sql="{CALL P_addms}";
Connection connect=null;
PreparedStatement ps=null;
ResultSet rs=null;//结果集
try {
connect=ConnectDB.getConnection();
ps=connect.prepareStatement(sql);
rs=ps.executeQuery();
while(rs.next()){
int number=rs.getInt("e_no");
String name=rs.getString("e_name");
int sex=rs.getInt("e_sex");
int number1=rs.getInt("dept_no");
String job=rs.getString("e_job");
int salary=rs.getInt("e_salary");
String date=rs.getString("hire_date");
System.out.println(number+"\t"+name+"\t"+sex+"\t"+number1+"\t"+job+"\t"+salary+"\t"+date);
}
} catch (SQLException e) {
e.printStackTrace();
}
ConnectDB.closeConnection(connect);
}
其输出结果为:
1001李强 1 20 会计 800 2015-9-9
1002 王刚 1 30 HR1600 2014-10-9
1003 姗姗 0 30 HR1250 2014-11-7
1004 张阳 1 20 出纳2975 2015-4-9
1005 小丽 0 40 销售经理2850 2015-2-10
1006 王二 1 10 产品策划2450 2015-4-23
1007 小冬 1 40 销售经理2750 2015-3-10
3. 带输出参数返回值的存储过程:
--删除存储过程
DROP PROCEDURE IF EXISTS proc_getcount
--设置分割符为//
mysql> DELIMITER //
--创建存储过程
mysql> CREATE PROCEDURE proc_getcount(out count int)
-> BEGIN
-> SELECT COUNT(*) INTO count FROM employee;
-> END
-> //
--设置分割符为;
mysql> DELIMITER ;
--调用存储过程
mysql> CALL proc_getcount(@count);
--查看输出变量值
mysql> SELECT @count;
+--------+
| @count |
+--------+
| 7 |
+--------+
4.带输入参数的存储过程:
--设置分割符为//
mysql> DELIMITER //
--创建存储过程
mysql> CREATE PROCEDURE proc_find_by_id(in n int)
-> BEGIN
-> SELECT * FROM employee WHERE e_no = n;
-> END
-> //
--设置分割符为;
mysql> DELIMITER ;
--定义变量
mysql> SET @n=1002;
--调用存储过程
mysql> CALL proc_find_by_id(@n);
+------+--------+-------+---------+-------+----------+-----------+
| e_no | e_name | e_sex | dept_no | e_job | e_salary | hire_date |
+------+--------+-------+---------+-------+----------+-----------+
| 1002 | 王刚 | 1 | 30 | HR | 1600 | 2014-10-9 |
+------+--------+-------+---------+-------+----------+-----------+
5.带输入输出参数
mysql> DELIMITER //
mysql> CREATE PROCEDURE proc_inout(INOUT p int)
-> BEGIN
-> SELECT p;
-> SET p = 10;
-> SELECT p;
-> END
-> //
mysql> DELIMITER ;
mysql> SET @p = 2;
mysql> CALL proc_inout(@p);
+------+
| p |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
+------+
| p |
+------+
| 10 |
+------+
mysql> SELECT @p;
+------+
| @p |
+------+
| 10 |
+------+
1 row in set (0.00 sec)
三、代码调用
四、变量
DECLARE 变量名 变量类型 [DEFAULT 默认值]
如:
declare x varchar(5) default 'outer';
七、基本控制语句
1.if语句
if(条件成立){
语句
}
IF 条件成立 THEN
语句
END IF
if-else语句
if(){
语句1;
}else{
语句2;
}
IF 条件 THEN
语句1;
ELSE
语句2;
END IF
mysql> CREATE PROCEDURE proc_declare()
-> BEGIN
-> DECLARE x int default 1;
-> SELECT x;
-> IF x = 1 THEN
-> SELECT * FROM employee WHERE e_no = 1001;
-> ELSE
-> SELECT COUNT(*) FROM employee;
-> END IF;
-> END;
-> //
2.多分支语句
switch(值){
case 值1:
语句块1;
case 值2:
语句块2
}
CASE 值
WHEN 值1 THEN
语句块1;
WHEN 值2 THEN
语句块2;
WHEN 值3 THEN
语句块3;
END CASE;
->case var
->when 0 then
-> insert into t values(17);
->when 1 then
-> insert into t values(18);
->else
-> insert into t values(19);
-> end case;
3.循环语句
while(条件){
语句块;
}
WHILE 条件 do
语句块;
END WHILE;
->while var<6 do
-> insert into t values(var);
-> set var=var+1;
->end while;