创建存储过程
MySQL中,创建存储过程的基本形式如下:
1.CREATE PROCEDURE sp_name//存储过程的名称自行定义
([proc_parameter[,...]]) //proc_parameter表示存储过程的参数列表
2.[characteristic ...] //characteristic参数指定存储过程的特性
routine_body //routine_body参数是SQL代码的内容,可以用BEGIN…END来标志SQL代码的开始和结束。
proc_parameter中的每个参数由3部分组成。这3部分分别是输入输出类型、参数名称和参数类型。其形式如下:
[ IN | OUT | INOUT ] param_name type
//1.IN表示输入参数
//2.OUT表示输出参数
//3.INOUT表示既可以输入也可以是输出参数
//param_name表示参数的名称自行定义
//type表示参数的类型,该类型可以是MySQL数据库的任意数据类型
characteristic参数有多个取值。其取值说明如下:
说明routine_body部分是由SQL语言的语句组成,这也是数据库系统默认的语言.
指明存储过程的执行结果是否是确定的。
DETERMINISTIC表示结果是确定的。每次执行存储过程时,相同的输入会得到相同的输出。
NOT DETERMINISTIC表示结果是非确定的,相同的输入可能得到不同的输出。
默认情况下,结果是非确定的。
指明子程序使用SQL语句的限制。
CONTAINS SQL表示子程序包含SQL语句,但不包含读或写数据的语句;
NO SQL表示子程序中不包含SQL语句;
READS SQL DATA表示子程序中包含读数据的语句;
MODIFIES SQL DATA表示子程序中包含写数据的语句。
默认情况下,系统会指定为CONTAINS SQL。
指明谁有权限来执行。DEFINER表示只有定义者自己才能够执行;INVOKER表示调用者可以执行。
默认情况下,系统指定的权限是DEFINER。
下面创建一个名为num_from_employee的存储过程。代码如下:
CREATE PROCEDURE num_from_employee (IN emp_id INT, OUT count_num INT )
READS SQL DATA
BEGIN
SELECT COUNT(*) INTO count_num
FROM employee
WHERE d_id=emp_id ;
END
上述代码中,存储过程名称为num_from_employee;输入变量为emp_id;输出变量为count_num。SELECT语句从employee表查询d_id值等于emp_id的记录,并用COUNT(*)计算d_id值相同的记录的条数,最后将计算结果存入count_num中。代码的执行结果如下:
mysql> DELIMITER &&
mysql> CREATE PROCEDURE num_from_employee
(IN emp_id INT, OUT count_num INT )
-> READS SQL DATA
-> BEGIN
-> SELECT COUNT(*) INTO count_num
-> FROM employee
-> WHERE d_id=emp_id ;
-> END &&
Query OK, 0 rows affected (0.09 sec)
mysql> DELIMITER ;
代码执行完毕后,没有报出任何出错信息就表示存储函数已经创建成功。以后就可以调用这个存储过程,数据库中会执行存储过程中的SQL语句。
说明:MySQL中默认的语句结束符为分号(;)。存储过程中的SQL语句需要分号来 结束。为了避免冲突,首先用"DELIMITER &&"将MySQL的结束符设置为&&。最后再用"DELIMITER ;"来将结束符恢复成分号。这与创建触发器时是一样的。
COMMENT 'string':注释信息。
技巧:创建存储过程时,系统默认指定CONTAINS SQL,表示存储过程中使用了SQL语句。但是,如果存储过程中没有使用SQL语句,最好设置为NO SQL。而且,存储过程中最好在COMMENT部分对存储过程进行简单的注释,以便以后在阅读存储过程的代码时更加方便。
创建存储函数
在MySQL中,创建存储函数的基本形式如下:
CREATE FUNCTION sp_name //函数名自行定义
([func_parameter[,...]]) //函数参数表
RETURNS type //指定返回值的类型
[characteristic ...] //参数指定存储函数的特性,该参数的取值与存储过程中的取值是一样的,具体参考上面
routine_body //SQL代码的内容,可以用BEGIN…END来标志SQL代码的开始和结束。
func_parameter可以由多个参数组成,其中每个参数由参数名称和参数类型组成,其形式如下:
param_name//参数是存储函数的参数名称
type //指定存储函数的参数类型,该类型可以是MySQL数据库的任意数据类型
下面创建一个名为name_from_employee的存储函数。代码如下:
CREATE FUNCTION name_from_employee (emp_id INT )
RETURNS VARCHAR(20)
BEGIN
RETURN (SELECT name
FROM employee
WHERE num=emp_id );
END
上述代码中,存储函数的名称为name_from_employee;该函数的参数为emp_id;返回值是VARCHAR类型。SELECT语句从employee表查询num值等于emp_id的记录,并将该记录的name字段的值返回。代码的执行结果如下:
mysql> DELIMITER &&
mysql> CREATE FUNCTION name_from_employee (emp_id INT )
-> RETURNS VARCHAR(20)
-> BEGIN
-> RETURN (SELECT name
-> FROM employee
-> WHERE num=emp_id );
-> END&&
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
结果显示,存储函数已经创建成功。该函数的使用和MySQL内部函数的使用方法一样。
变量的使用
在存储过程和函数中,可以定义和使用变量。用户可以使用DECLARE关键字来定义变量。然后可以为变量赋值。这些变量的作用范围是BEGIN…END程序段中。本小节将讲解如何定义变量和为变量赋值。
定义变量
MySQL中可以使用DECLARE关键字来定义变量。定义变量的基本语法如下:
DECLARE //DECLARE关键字是用来声明变量的
var_name[,...] //变量的名称,这里可以同时定义多个变量
type//用来指定变量的类型
[DEFAULT value] //将变量默认值设置为value,没有使用DEFAULT子句时,默认值为NULL
下面定义变量my_sql,数据类型为INT型,默认值为10。代码如下:
DECLARE my_sql INT DEFAULT 10 ;
为变量赋值
MySQL中可以使用SET关键字来为变量赋值。SET语句的基本语法如下:
SET//SET关键字是用来为变量赋值的
var_name//变量的名称
= expr//赋值表达式
[, var_name = expr] ... //一个SET语句可以同时为多个变量赋值,各个变量的赋值语句之间用逗号隔开
`下面为变量my_sql赋值为30。代码如下:
SET my_sql = 30 ;
MySQL中还可以使用SELECT…INTO语句为变量赋值。其基本语法如下:
SELECT
col_name[,…] //表示查询的字段名称
INTO
var_name[,…] //变量的名称
FROM
table_name //表的名称
WEHRE
condition //查询条件
下面从employee表中查询id为2的记录,将该记录的d_id值赋给变量my_sql。代码如下:
SELECT
d_id
INTO
my_sql
FROM
employee
WEHRE
id=2 ;
用 JDBC 如何调用存储过程
import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Types;
publicclass JdbcTest {
/**
* @paramargs */
public static voidmain(String[] args) {
// TODO Auto-generated method stub
Connection cn = null;
CallableStatement cstmt =null;
try {
//这里最好不要这么干,因为驱动名写死在程序中了 Class.forName("com.mysql.jdbc.Driver");
//实际项目中,这里应用 DataSource 数据,如果用框架,
//这个数据源不需要我们编码创建,我们只需 Datasource ds =context.lookup()
//cn = ds.getConnection();
cn = DriverManager.getConnection("jdbc:mysql:///test","root","root");
cstmt = cn.prepareCall("{callinsert_Student(?,?,?)}");
cstmt.registerOutParameter(3,Types.INTEGER);
cstmt.setString(1,"wangwu");
cstmt.setInt(2, 25);
cstmt.execute();
//get 第几个,不同的数据库不一样,建议不写 System.out.println(cstmt.getString(3));
} catch (Exception e) {
// TODO Auto-generated catchblock e.printStackTrace();
}
finally
{
} }
}
/*try{cstmt.close();}catch(Exceptione){} try{cn.close();}catch(Exceptione){}*/ try {
if(cstmt !=null) cstmt.close();
if(cn !=null) cn.close();
} catch (SQLException e) {
// TODO Auto-generatedcatch block e.printStackTrace();