mysql存储过程实例for_mysql存储过程实例

先放入mysql存储过程,便于大家了解一下存储过程的整体代码结构:

CREATE PROCEDURE `get_branch_path`(IN company CHAR(32))

BEGIN

DECLARE _branchid CHAR(32) ;

DECLARE _branchpath LONGTEXT;

DECLARE _currentid CHAR(32);

DECLARE fetchSeqOK boolean;

DECLARE cur1 CURSOR FOR SELECT branchid FROM t_branch WHERE companyid=company;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchSeqOK=TRUE;

SET fetchSeqOK=FALSE;

DROP TEMPORARY TABLE IF EXISTS temp_table;

CREATE TEMPORARY TABLE IF NOT EXISTS temp_table (

branchid CHAR(32),

branchpath LONGTEXT

);

OPEN cur1;

FETCH cur1 INTO _currentid;

fetchSeqLoop:LOOP

IF fetchSeqOK THEN

LEAVE fetchSeqLoop;

ELSE

SET _branchid = _currentid;

SET _branchpath = NULL;

CALL generate_branch_path(_currentid, _branchpath);

INSERT INTO temp_table VALUES(_branchid, _branchpath);

FETCH cur1 INTO _currentid;

END IF;

END LOOP;

CLOSE cur1;

SELECT branchid,branchpath FROM temp_table;

DROP TABLE temp_table;

END

CREATE PROCEDURE `generate_branch_path`(INOUT `_subid` varchar(255),INOUT `_subpath` longtext)

BEGIN

DECLARE _path LONGTEXT;

DECLARE _parentid CHAR(32);

DECLARE fetchSeqOK boolean;

DECLARE cur2 CURSOR FOR SELECT `name`,parentid FROM t_branch WHERE branchid=_subid;

SET @@max_sp_recursion_depth = 20;

OPEN cur2;

FETCH cur2 INTO _path,_parentid;

IF( LEFT(_parentid,1) <> 0 ) THEN

SET _subid = _parentid;

IF (_subpath IS NULL) THEN

SET _subpath = _path;

ELSE

SET _subpath = CONCAT(_path,'/',_subpath);

END IF;

CALL generate_branch_path(_subid,_subpath);

ELSE

IF (_subpath IS NULL) THEN

SET _subpath = _path;

ELSE

SET _subpath = CONCAT(_path,'/',_subpath);

END IF;

END IF;

END

上述两个存储过程所需要的数据表及测试数据:

CREATE TABLE `t_branch` (

`branchid` char(32) NOT NULL,

`companyid` char(32) NOT NULL,

`name` varchar(50) NOT NULL,

`parentid` char(32) NOT NULL,

`sortid` int(11) NOT NULL,

`remark` varchar(200) DEFAULT NULL,

`isshare` int(11) DEFAULT NULL,

`lastupdatetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

`createtime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',

PRIMARY KEY (`branchid`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `t_branch` VALUES ('402880ff2d6f871a012d6f871cf30000','402880ff2d5f53cd012d5f53d43d0000','销售部门','0','2','就是湖北销售部门!','0','2011-01-11 18:13:35','2011-01-10 18:46:32'),

('402880ff2d6f871a012d6f8788210001','402880ff2d5f53cd012d5f53d43d0000','hbdev','402880ff2d744a06012d74531f8e0002','1','就是湖北研发','1','2011-01-11 17:16:42','2011-01-10 18:47:00'),

('402880ff2d6f871a012d6f8816f30002','402880ff2d5f53cd012d5f53d43d0000','abc team','402880ff2d6f871a012d6f8788210001','2','就是 abc team!','1','2011-01-11 18:21:34','2011-01-10 18:47:36'),

('402880ff2d744a06012d745231660000','402880ff2d5f53cd012d5f53d43d0000','人力资源部','0','3','就是湖北人力资源部!','0','2011-01-11 18:18:11','2011-01-11 17:06:47'),

('402880ff2d744a06012d7452930e0001','402880ff2d5f53cd012d5f53d43d0000','市场部','0','4','就是湖北市场部!','0','2011-01-11 18:18:11','2011-01-11 17:07:12'),

('402880ff2d744a06012d74531f8e0002','402880ff2d5f53cd012d5f53d43d0000','PTC','0','1','就是EFG!','0','2011-01-11 17:17:23','2011-01-11 17:07:48'),

('402880ff2d749155012d7492e8e70000','402880ff2d5f53cd012d5f53d43d0000','HDK team','402880ff2d6f871a012d6f8788210001','1','就是HDK team!','0','2011-01-11 18:17:28','2011-01-11 18:17:28'),

('ff8080812e3792bb012e50492fad0018','402880ff2d5f53cd012d5f53d43d0000','新部门','402880ff2d6f871a012d6f871cf30000','1','','0','2011-02-23 10:11:37','2011-02-23 10:11:37');

1.1存储过程代码结构:

CREATE PROCEDURE 存储过程名(参数列表,有三种类型:IN,OUT,INOUT)

BEGIN

1.变量和条件声明

2. Cursor声明

3. Handler声明

4. 程序代码

END

注意:

由括号包围的参数列必须总数存在的。如果没有参数,也要使用一个空参数列()。每个参数默认都是一个IN参数,可在参数名之间加入OUT,INOUT等关键字指定为其他类型。

变量和条件声明不需放在Cursor声明等代码块之前,否则该存储过程编译不能通过。

1.2变量声明

DECLARE _branchid CHAR(32) ;

DECLARE 关键字

_branchid 变量名

CHAR(32) 变量类型

1.3指针和Handler声明

定义游标

cur1 CURSOR FOR SELECT branchid FROM t_branch WHERE companyid=company;

使用游标

open cur1;

fetch数据

FETCH cur1 INTO _currentid;

关闭游标

close cur1;

用到游标cur1,都会离不开循环语句。

一般使用Loop和while来进行循环语句的编写。

这里使用Loop为例

fetchSeqLoop:LOOP

fetch cur1 into _currentid;

end Loop;

现在是死循环,还没有退出的条件,那么在这里和oracle有区别,OraclePL/SQL的指针有个隐性变量%notfound,

Mysql是通过一个Error handler的声明来进行判断的,

DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchSeqOK=TRUE;

在Mysql里当游标遍历溢出时,会出现一个预定义的NOT FOUND的Error,我们处理这个Error并定义一个continue的handler就可以了,

关于Mysql Error handler可以查询Mysql手册。定义一个flag,在NOT FOUND,标示Flag,在Loop里以这个flag为结束循环的判断就可以了。

具体代码可以参考上面的存储过程:get_branch_path();

注意:在循环语句中,记得使用FETCH cur1 into _currentid来进行指针的数据移动,否则指针会一直指向你初次赋值的地方,而不指向下一个值。

1.4程序代码

根据上述定义的变量,临时表,指针等运用循环语句,IF/ELSE语句,函数等内容完成一定的业务逻辑。

IF语句的结构:

IF 逻辑表达式 THEN

程序语句;

ELSE

程序语句;

END IF;

WHILE语句的结构:

WHILE 逻辑表达式 DO

程序语句;

END WHILE;

LOOP语句的结构:

LOOP

程序语句;

END LOOP;

可以给代码块加lebel,这样END匹配比较直观,还可以用LEAVE语句来终结代码块:

fetchSeqLoop:LOOP

IF fetchSeqOK THEN

LEAVE fetchSeqLoop;

ELSE

程序语句;

END IF;

END LOOP;

2.1存储过程调用

CALL generate_branch_path(_currentid, _branchpath);

存储过程中的参数有三种IN,OUT,INOUT.具体用法可以看看下面的这篇文章,就能够明白:

http://www.blogjava.net/nonels/archive/2009/04/22/233324.html

2.2存储过程的结果集返回

上述存储过程中,创建了一个临时表temp_table,用于存储调用方(持久层中间件:hibenate,ibatis,JDBC)所需要的结果集。如果不考虑临时表的回收问题,在调用方可以在调用存储过程之后,再直接用sql语句查询该临时表获取结果集。但考虑到临时表的回收问题,需要在存储过程结束时,删除该临时表,并返回该结果集。使用如下代码即可达到目的。

SELECT branchid,branchpath FROM temp_table;

DROP TABLE temp_table;

在有了上面的SELECT语句之后,在DAO层调用存储过程之后,通过代码就可以获取结果集了。

使用JDBC等接口代码完成结果集的返回。

String url = "jdbc:mysql://127.0.0.1:3306/test";

try {

DriverManager.registerDriver(new com.mysql.jdbc.Driver());

Connection conn = DriverManager.getConnection(url, "root","");

CallableStatement stmt = conn.prepareCall("{call xx()}");

stmt.execute();

ResultSet rs = (ResultSet)stmt.getResultSet();

while(rs.next()){

System.out.print (rs.getString(1));

System.out.print (" , ");

System.out.println (rs.getString(2));

}

} catch (SQLException e) {

e.printStackTrace();

}

行了,关于mysql总结的经验主要就是这些了,上述代码很多借鉴了其他的一些文章,有雷同之处还望大家见谅。关于上述贴出的存储过程,数据表等是可以编译通过,并运行的。大家想学习的话,可以拷贝下来测试一下。

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2011-02-25 19:15

浏览 945

分类:数据库

评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 存储过程是一种封装了 SQL 语句的代码块,可以在 MySQL 数据库中创建、存储和调用。存储过程可以接受输入参数、输出参数和返回值,可以使用分支、循环、异常处理等复杂的编程语言结构,适用于处理复杂的数据操作和业务逻辑。 下面是一个简单的 MySQL 存储过程实例: ```mysql DELIMITER // CREATE PROCEDURE sp_get_customer(IN customer_id INT, OUT customer_name VARCHAR(50)) BEGIN SELECT customer_name INTO customer_name FROM customers WHERE customer_id = customer_id; END // DELIMITER ; ``` 这个存储过程名为 `sp_get_customer`,有一个输入参数 `customer_id` 和一个输出参数 `customer_name`。存储过程的作用是根据传入的 `customer_id` 查询 `customers` 表中对应的客户名,并将其赋值给输出参数 `customer_name`。 使用以下语句调用这个存储过程: ```mysql CALL sp_get_customer(1, @customer_name); SELECT @customer_name; ``` 这个语句会查询 `customers` 表中 `customer_id` 为 1 的客户名,并将其赋值给变量 `@customer_name`,然后输出变量的值。 存储过程可以简化复杂的数据操作和业务逻辑,提高数据库的性能和安全性。但是,存储过程也有一些限制和注意事项: 1. 存储过程的语法比较复杂,需要熟悉 MySQL 的编程语言和语法规则。 2. 存储过程可能会影响数据库的性能和可维护性,应该谨慎使用和设计。 3. 存储过程可能会影响数据库的安全性,应该限制存储过程的访问权限和操作权限。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值