循环
-- 求 1-n 的和 /* while循环语法: while 条件 DO 循环体; end while; */ create procedure sum1(a int) begin declare sum int default 0; -- default 是指定该变量的默认值 declare i int default 1; while i<=a DO -- 循环开始 set sum=sum+i; set i=i+1; end while; -- 循环结束 select sum; -- 输出结果 end; -- 执行存储过程 call sum1(100); -- 删除存储过程 drop procedure if exists sum1;
/*loop 循环语法: loop_name:loop if 条件 THEN -- 满足条件时离开循环 leave loop_name; -- 和 break 差不多都是结束训话 end if; end loop; */ create procedure sums(a int) begin declare sum int default 0; declare i int default 1; loop_name:loop -- 循环开始 if i>a then leave loop_name; -- 判断条件成立则结束循环 好比java中的 boeak end if; set sum=sum+i; set i=i+1; end loop; -- 循环结束 select sum; -- 输出结果 end; -- 执行存储过程 call sums(100); -- 删除存储过程 drop procedure if exists sums;
/*repeat 循环语法 repeat 循环体 until 条件 end repeat; */ -- 实例; create procedure sum55(a int) begin declare sum int default 0; declare i int default 1; repeat -- 循环开始 set sum=sum+i; set i=i+1; until i>a end repeat; -- 循环结束 select sum; -- 输出结果 end; -- 执行存储过程 call sum55(100); -- 删除存储过程 drop procedure if exists sum55;
存储过程批量插入大量数据
CREATE DEFINER=`root`@`%` PROCEDURE `idata4`() begin declare i int; START TRANSACTION; -- 开启事务 set i=1; while(i<=100000)do insert into t2 values(i, i, i); set i=i+1; end while; COMMIT; -- 提交事务 end
游标
DROP PROCEDURE IF EXISTS processorder; CREATE PROCEDURE processorder() BEGIN -- 定义游标 DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders; END;
DROP PROCEDURE IF EXISTS processorder; CREATE PROCEDURE processorder() BEGIN -- 定义局部变量 DECLARE num INT; -- 定义游标 DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders; -- 打开游标 OPEN ordernumbers; -- 获取第一行数据 FETCH ordernumbers INTO num; -- 查询结果 SELECT num; -- 关闭游标 CLOSE ordernumbers; END; CALL processorder();
DROP PROCEDURE IF EXISTS processorder; CREATE PROCEDURE processorder() BEGIN -- 定义局部变量 DECLARE done BOOLEAN DEFAULT false; DECLARE num INT; -- 定义游标 DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders; -- 定义CONTINUE HANDLER DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=true; -- 打开游标 OPEN ordernumbers; -- 循环所有行 REPEAT -- 获取第一行数据 FETCH ordernumbers INTO num; -- 结束循环 UNTIL done END REPEAT; -- 查询结果 SELECT num; -- 关闭游标 CLOSE ordernumbers; END; CALL processorder();
-- 临时表 CREATE TEMPORARY TABLE StgSummary( Name VARCHAR(50) NOT NULL, StgId INT NOT NULL DEFAULT 0 ); INSERT INTO StgSummary(Name,StgId) select '临时数据1',1; INSERT INTO StgSummary(Name,StgId) select '临时数据2',2; INSERT INTO StgSummary(Name,StgId) select '临时数据3',3; INSERT INTO StgSummary(Name,StgId) select '临时数据4',4; INSERT INTO StgSummary(Name,StgId) select '临时数据5',5; INSERT INTO StgSummary(Name,StgId) select '临时数据6',6; INSERT INTO StgSummary(Name,StgId) select '临时数据7',7; INSERT INTO StgSummary(Name,StgId) select '临时数据8',8; INSERT INTO StgSummary(Name,StgId) select '临时数据9',9; INSERT INTO StgSummary(Name,StgId) select '临时数据10',10; select * from StgSummary; -- 不能用RENAME来重命名一个临时表,但是可以用ALTER TABLE代替 -- ALTER TABLE orig_name RENAME new_name; -- 临时表使用完以后需要主动Drop掉 DROP TEMPORARY TABLE IF EXISTS StgTempTable;
CREATE TABLE StgSummary_bak( Name VARCHAR(50) NOT NULL, StgId INT NOT NULL DEFAULT 0 );
-- 存储过程 drop procedure if exists ry.pro_test; delimiter $$ create procedure if not exists ry.pro_test() begin -- 定义变量 DECLARE done INT DEFAULT FALSE; DECLARE field_1 VARCHAR(20); DECLARE field_2 VARCHAR(20); -- 创建游标,并存储数据 DECLARE cur_list CURSOR FOR SELECT StgId, name FROM StgSummary; -- 游标中的内容执行完后将done设置为true DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true; -- 打开游标 OPEN cur_list; -- 执行循环 read_loop : LOOP -- 取游标中的值 FETCH cur_list INTO field_1, field_2; -- 判断是否结束循环,一定要放到FETCH之后,因为在fetch不到的时候才会设置done为true -- 如果放到fetch之前,先判断done,这个时候done的值还是之前的循环的值,因此就会导致循环一次 IF done THEN LEAVE read_loop; END IF; -- 执行SQL操作 SET @sql_insert = CONCAT("insert into StgSummary_bak(StgId, name) VALUES ('", field_1, "','", field_2 ,"')"); PREPARE sqlli FROM @sql_insert; EXECUTE sqlli; COMMIT; END LOOP read_loop; -- 释放游标 CLOSE cur_list; end $$ delimiter ; -- 调用存储过程 call pro_test() select * from StgSummary_bak;
游标
- 优点:游标是面向集合与面向行的设计思想之间的一种桥梁,因为游标是针对行操作的,所以对从数据库中 SELECT 查询得到的每一行可以进行分开的独立的相同或不同的操作,是一种分离的思想。可以满足对某个结果行进行特殊的操作。如基于游标位置的增删改查能力。
- 缺点:
- 速度较慢
- 会产生死锁现象
- 内存大