|
Posted on
2011-08-05 10:39
feisky
阅读( 659)
评论()
编辑
收藏
举报
mysql 5.0存储过程学习总结
一.创建存储过程 1.基本语法: create procedure sp_name() begin end 2.参数传递
二.调用存储过程 1.基本语法:call sp_name() 注意:存储过程名称后面必须加括号,哪怕该存储过程没有参数传递
三.删除存储过程 1.基本语法: drop procedure sp_name// 2.注意事项 (1)不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程
四.区块,条件,循环 1.区块定义,常用 begin end; 也可以给区块起别名,如: lable:begin end lable; 可以用leave lable;跳出区块,执行区块以后的代码 2.条件语句 3.循环语句 :while循环 loop循环 repeat until循环 repeat until循环
五.其他常用命令 1.show procedure status 显示数据库中所有存储的存储过程基本信息,包括所属数据库,存储过程名称,创建时间等 2.show create procedure sp_name 显示某一个存储过程的详细信息
mysql存储过程基本函数 一.字符串类 CHARSET(str) //返回字串字符集 CONCAT (string2 [,... ]) //连接字串 INSTR (string ,substring ) //返回substring首次在string中出现的位置,不存在返回0 LCASE (string2 ) //转换成小写 LEFT (string2 ,length ) //从string2中的左边起取length个字符 LENGTH (string ) //string长度 LOAD_FILE (file_name ) //从文件读取内容 LOCATE (substring , string [,start_position ] ) 同INSTR,但可指定开始位置 LPAD (string2 ,length ,pad ) //重复用pad加在string开头,直到字串长度为length LTRIM (string2 ) //去除前端空格 REPEAT (string2 ,count ) //重复count次 REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替换search_str RPAD (string2 ,length ,pad) //在str后用pad补充,直到长度为length RTRIM (string2 ) //去除后端空格 STRCMP (string1 ,string2 ) //逐字符比较两字串大小, SUBSTRING (str , position [,length ]) //从str的position开始,取length个字符, 即参数position必须大于等于1 TRIM([[BOTH|LEADING|TRAILING] [padding] FROM]string2) //去除指定位置的指定字符 UCASE (string2 ) //转换成大写 RIGHT(string2,length) //取string2最后length个字符 SPACE(count) //生成count个空格
二.数学类 ABS (number2 ) //绝对值 BIN (decimal_number ) //十进制转二进制 CEILING (number2 ) //向上取整 CONV(number2,from_base,to_base) //进制转换 FLOOR (number2 ) //向下取整 FORMAT (number,decimal_places ) //保留小数位数 HEX (DecimalNumber ) //转十六进制 注:HEX()中可传入字符串,则返回其ASC-11码,如HEX(’DEF’)返回4142143 也可以传入十进制整数,返回其十六进制编码,如HEX(25)返回19 LEAST (number , number2 [,..]) //求最小值 MOD (numerator ,denominator ) //求余 POWER (number ,power ) //求指数 RAND([seed]) //随机数 ROUND (number [,decimals ]) //四舍五入,decimals为小数位数] 三.日期时间类 ADDTIME (date2 ,time_interval ) //将time_interval加到date2 CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) //转换时区 CURRENT_DATE ( ) //当前日期 CURRENT_TIME ( ) //当前时间 CURRENT_TIMESTAMP ( ) //当前时间戳 DATE (datetime ) //返回datetime的日期部分 DATE_ADD (date2 , INTERVAL d_value d_type ) //在date2中加上日期或时间 DATE_FORMAT (datetime ,FormatCodes ) //使用formatcodes格式显示datetime DATE_SUB (date2 , INTERVAL d_value d_type ) //在date2上减去一个时间 DATEDIFF (date1 ,date2 ) //两个日期差 DAY (date ) //返回日期的天 DAYNAME (date ) //英文星期 DAYOFWEEK (date ) //星期(1-7) ,1为星期天 DAYOFYEAR (date ) //一年中的第几天 EXTRACT (interval_name FROM date ) //从date中提取日期的指定部分 MAKEDATE (year ,day ) //给出年及年中的第几天,生成日期串 MAKETIME (hour ,minute ,second ) //生成时间串 MONTHNAME (date ) //英文月份名 NOW ( ) //当前时间 SEC_TO_TIME (seconds ) //秒数转成时间 STR_TO_DATE (string ,format ) //字串转成时间,以format格式显示 TIMEDIFF (datetime1 ,datetime2 ) //两个时间差 TIME_TO_SEC (time ) //时间转秒数] WEEK (date_time [,start_of_week ]) //第几周 YEAR (datetime ) //年份 DAYOFMONTH(datetime) //月的第几天 HOUR(datetime) //小时 LAST_DAY(date) //date的月的最后日期 MICROSECOND(datetime) //微秒 MONTH(datetime) //月 MINUTE(datetime) //分
## **********first test,procedure********** #<1> use testprocedure; delimiter // create procedure simpleproce1 (out par1 int) begin select count(*) into par1 from proce; end //
delimiter ; call simpleproce1(@a); select @a; #<2>,每次只有单一的行可以被取回select id,name into par1,par2 from proce LIMIT 1;中的LIMIT 1;
use testprocedure;
delimiter // DROP procedure IF EXISTS simpleproce2 create procedure simpleproce2 (out par1 int,out par2 char(30)) begin select id,name into par1,par2 from proce LIMIT 1; end //
delimiter ; call simpleproce2(@a,@b); select @a,@b;
## *********second test,function************ #<3> delimiter //
DROP FUNCTION IF EXISTS hello // create function hello(s char(20)) returns char(50) return concat('Hello, ',s,'!'); // delimiter ; select hello('world'); show create function testprocedure.hello\G #它返回子程序的特征,如数据库,名字,类型,创建者及创建和修改日期 show function status like 'hello'\G
#<4> #注意name不能和字段名相同 delimiter // DROP procedure IF EXISTS test //
CREATE PROCEDURE test () BEGIN DECLARE name VARCHAR(5) DEFAULT 'bob'; DECLARE newname VARCHAR(5); DECLARE xid INT; SELECT name,id INTO newname,xid FROM proce WHERE name = name; SELECT newname; END; // call test1() // #*** delimiter // DROP procedure IF EXISTS test2 //
CREATE PROCEDURE test2 () BEGIN DECLARE newname VARCHAR(5); DECLARE xid INT; SELECT name,id INTO newname,xid FROM proce limit 1; SELECT newname,xid; END; //
call test2() // #<5> use testprocedure; CREATE PROCEDURE p1 () SELECT * FROM proce;
call p1();
#<6>注意此处的handler是设置SQLSTATE值,SQLWARNING是对所有以01开头的SQLSTATE代码的速记 #NOT FOUND是对所有以02开头的SQLSTATE代码的速记 #SQLEXCEPTION是对所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE代码的速记 #DECLARE CONTINUE HANDLER声明CONTINUE异常处理 #事实上这里的23000SQLSTATE是更常用的,当外键约束出错或主键约束出错就被调用了。 #当没有发生该23000异常时, select @x2的值将是null,而不是1, #并且后面的第2个语句执行时将会报主键约束错误,此时@x2=1,@x=4,虽然第2句有了异常,但是后面的语句继续执行 #保存到数据的数据是3,test3和5,test5
use testprocedure; delimiter // DROP procedure IF EXISTS handlerdemo //
create procedure handlerdemo() begin declare continue handler for sqlstate '23000' set @x2=1; set @x=1; insert into proce values(3,'test3'); set @x=2; insert into proce values(3,'test4'); set @x=3; insert into proce values(5,'test5'); set @x=4; end; //
call handlerdemo()//
select @x // select @x2 //
## ************光标**************** #<7>光标必须在声明处理程序之前被声明,并且变量和条件必须在声明光标或处理程序之前被声明 #在这里先声明变量a,b,c,后声明cursor create procedure curdemo() begin declare done int default 0; declare a char(16); declare b,c int; declare cur1 cursor for select id,name from proce; declare cur2 cursor for select id from proce2; declare continue handler for sqlstate '02000' set done=1; open cur1; open cur2;
repeat fetch cur1 into b,a; fetch cur2 into c; if not done then if b insert into proce3 values(b,a); else insert into proce3 values(c,a); end if; end if; until done end repeat; close cur1; close cur2; end
## **************** Case ******************* #<8>when ... then ;case ... end case; delimiter // DROP procedure IF EXISTS p13 // create procedure p13(in par1 int) begin declare var1 int; set var1=par1+1; case var1 when 0 then insert into casetest values(17); when 1 then insert into casetest values(18); else insert into casetest values(19); end case; end; //
call p13(-1)// call p13(0)// call p13(1)// call p13(null)//
## **************** while **************** #<9>while ... do ... end while;为了防止null的错误,set v=0是必须的 delimiter // DROP procedure IF EXISTS p14 //
create procedure p14() begin declare v int; set v=0; while v < 5 do insert into casetest values (v); set v=v+1; end while; end;//
call p14()//
## ***************** repeat ***************** #<10>repeat ...until ... end repeat; 是执行后检查(until v>=5),而while是执行前检查(while v<5) delimiter // DROP procedure IF EXISTS p15 //
create procedure p15() begin declare v int; set v=0; repeat insert into casetest values(v); set v=v+1; until v >=5
end repeat; end; //
call p15()//
## ***************** loops ***************** #<11> loop 和while一样不需要初始条件,同时和repeat一样不需要结束条件 # loop_label: loop # ... # if .. then # leave loop_label # end if # end loop
delimiter // DROP procedure IF EXISTS p16 //
create procedure p16() begin declare v int; set v=0; loop_label: loop insert into casetest values(v); set v=v+1; if v >=5 then leave loop_label; end if; end loop; end;//
call p16()//
## ***************** Labels ***************** # <12>labels标号; 注意此处的until 0=0后面没有分号“;” delimiter // DROP procedure IF EXISTS p17//
create procedure p17() label_1:begin
label_2:while 0=1 do leave label_2; end while;
label_3:repeat leave label_3;until 0=0 end repeat;
label_4:loop leave label_4; end loop;
end;//
call p17()//
#<13>labels 标号结束符; delimiter // DROP procedure IF EXISTS p18//
create procedure p18() label_1:begin
label_2:while 0=1 do leave label_2; end while label_2;
label_3:repeat leave label_3;until 0=0 end repeat label_3;
label_4:loop leave label_4; end loop label_4;
end label_1;//
call p18()//
#<14>leave和labels 跳出和标号;leave 使程序跳出复杂的语句 delimiter // DROP procedure IF EXISTS p19//
create procedure p19(par char)
label_1:begin label_2:begin label_3:begin
if par is not null then if par='a' then leave label_1; else begin if par='b' then leave label_2; else leave label_3; end if; end; end if; end if;
end label_3; end label_2; end label_1;
//
call p19('a')//
#<15>iterate迭代,必须用leave;iterate意思是重新开始复合语句,相当于 continue #该结果中3将不被保存到数据库表中 delimiter // DROP procedure IF EXISTS p20//
create procedure p20() begin declare v int; set v=0; loop_label:loop
if v=3 then set v=v+1; iterate loop_label; end if; insert into casetest values(v); set v=v+1;
if v>=5 then leave loop_label; end if;
end loop loop_label; end;//
call p20()//
#<16>Grand combination大组合
delimiter // DROP procedure IF EXISTS p21//
create procedure p21(in par1 int,out par2 int) language sql deterministic sql security invoker begin declare v int;
label goto_label;
start_label:loop if v=v then leave start_label; else iterate start_label; end if; end loop start_label; repeat while 1=0 do begin end; end while; until v=v end repeat;
goto goto_label;
end; //
call p21()//
## **************** trigger *************************** #<17> use testprocedure;
CREATE TABLE trig1(a1 int); CREATE TABLE trig2(a2 int); CREATE TABLE trig3(a3 int not null AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE trig4( a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b4 INT DEFAULT 0 );
insert into trig3(a3) values(null),(null),(null),(null),(null),(null),(null),(null),(null),(null); insert into trig4(a4) values(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
delimiter // DROP trigger trigtest//
create trigger trigtest before insert on trig1 for each row begin insert into trig2 set a2=NEW.a1; delete from trig3 where a3=NEW.a1; update trig4 set b4=b4+1 where a4=NEW.a1; end;
http://blog.zol.com.cn/893/article_892123.html
![](http://img.zemanta.com/pixy.gif?x-id=b2607f84-3aa7-8d1b-9dc0-d232597135de)
|