mysql存储函数和过程函数学习

想借鉴的不用看我写,我纯粹做笔记,因为水平有限,所以可能说不清楚.
我认为的过程函数:
1,新建第一个存储函数: 测试表示test1 只有字段 id int name varchar(32)

delimiter //
create procedure t1()
begin
select * from test1;
end//
delimiter ;
调用 call t1(); 显示和直接select * from test1;一样的结果

2 上面是无参的,这是一个有两个参数的.

delimiter //
create procedure t2(in id int,in name varchar(32))
begin
insert into test1 (id,name) values (id,name);
end //
delimiter ;
调用 call t2(1,‘hahah’);

3,上面是有参in 的,这是是out的

delimiter //
create procedure t3(out num int)
begin
select count(*) into num from test1;
end //
delimiter ;
调用 call t3(@sun);
我个人感觉,@加随意字符串就是定义一个接受值的变量而已,要不然传出来的值放哪里?
然后 select @sun; 就能查看输出的值.

4,删除 直接 drop procedure name;

5,边抄边改的过程函数

drop procedure if exists t5;
delimiter //
create procedure t5(
in x int,in y int,in a boolean,out z decimal(8,3)) – declare input and output parameter
begin
declare o int default 1; – declare parameter
declare p int default 2;
declare q decimal(8,3);
select count() from test1 into o; – query value to parameter
if o=x then
select (id
p) into q from test1;
end if; – judge then do
if a then
select (id*o) into q from test1;
select q into z; – put value to output parameter
end //
delimiter ;

6,declare 定义一个变量,可以有默认的值,set 用来赋值,直接set x=y;个人使用的简单,感觉和select y into x;一样… 只是set后 可以连续加逗号,对多个变量赋值. 所有关键字不区分大小写.

7,开始我的循环里程,

drop procedure if exists t7;
create procedure t7(out outnum decimal,in innum int)
begin
declare x int default 2;
declare y decimal(8,3);
set x=3;
while x<5 do
insert into test2 (id) values(uuid());
set x = x+1;
end while;
select x into outnum;
end//
delimiter ;
很熟悉吧,其实都是大同小异,我是特别烦这种明明意思一样,写法不一样的语言…看来他们抄袭也是讲究改字的,避免重复.

下面是 repeat
略去一些代码,写多了,感觉像文科了.
repeat
insert into test1(id) values(uuid());
set x=x+1;
until x>5
end repeat;
select x into outnum;
end //
delimiter ;

下面是loop
此处还是省略代码
sun:loop
insert into …(和前面一样,我自以为是的认为我非常熟悉这几个单词了)
set x=x+1;
if x>5 then
leave sun;
end if;
end loop;
end//

下面是迭代iterate
drop procedure if exists t10;
delimiter //
create procedure t10(out outnum decimal,in innum int)
begin
declare x int default 2;
sun:loop
set x = x+1;
if x = 5 then
iterate sun; – 类似java中的continue ,这个超出我狭隘的理解了.哈哈.
end if;
insert into test1(id) values(uuid());
if x>6 then
leave sun;
end if;
end loop;
select x into outnum;
end//
delimiter ;

8,学习教程中有游标,补充一下游标知识,我这人懒,其实我都学过,也都记得,但是只是记得名字…这就是缺少练习的坏处.

刚看了游标定义,:一条sql对应N条数据,取出资源的接口,就是游标.,沿着游标可以一次取出一行…感觉像java的next,hasnext的.nextline??? 都像(这就是菜鸟级别的我)
drop procedure if exists t12;
delimiter //
create procedure t12()
begin
declare x varchar(100) default “1”;
declare y varchar(32);
declare z int default 1;
declare total int default 1;
declare have int;
declare exit handler for not found set have=0; – 如果出错赋值为0,让后来判断好退出 exit遇到查不出的情况会自动退出,但是continue会继续执行一次.暂时不理解continue的作用.
declare oo cursor for select id,name,num from test1;
select count(*) from test1 into total;
open o;
repeat
set total=total+1;
fetch oo into x,y,z;
select x,y,z;
– 可以干好多事,比如
if x = 1 then
update test1 set name=‘123’,num=234 ;
– 爽不爽…
until have =0 end repeat; – 用这个去判断
close o;
end//
delimiter ;
我这种级别的菜鸟,愣是疑问,怎么输出结果只有一个…结果原来在navicat中是个在两个Result中分别显示的…

9,好了,突然发现一个好牛逼的功能,就是指哪打哪,比如说我在java中为了灵活的调用对象的方法,只能用反射.mysql这个有预编译.prepare 编译字符串连接.

drop procedure if exists t17;
delimiter
create procedure t17(in tablename varchar(32),first varchar(32),firstnum int,second varchar(32),three varchar(32))
begin
set @sqltable = concat(‘update’,tablename,‘set’,first,’ = ‘,firstnum,’ where ‘,second,’ = ‘,three);
– 如果有多个sql逻辑,可以 set@sqltotal = concat(@sqltable,’,’,@sqltable…) 最后输出即可.

prepare one from @sqltable;
execute one;
– dealloate prepare one;
end//
delimiter ;
当然,肯定是越简单越能灵活用,我如果后期使用的话,肯定是写好多的小功能,然后用的时候,去调用需要的功能接口.

10,现在是存储函数,以上应该是过程函数…
定义是 封装一段sql代码,完成一种特定功能,返回结果. 这个定义有点问题…对于我来说有疑问.哈哈

drop function if exists f1;
delimiter //
create function f1()
returns int
begin
declare x int default 1;
return x;
end//
delimiter ;
最简单的一个函数,这个东西很没意思了,因为里面不能处理表.所以就是干巴巴的逻辑.
这个东西就看你的逻辑想象力了,和java代码就是写法不同…主要是里面的api我不熟悉,我也不知道和java的api有啥区别

11,今天继续,还是存储函数,我觉得,我觉得这个函数可能就是为了处理字段,而过程函数是为了处理表.这样好多逻辑就能实现了.

drop function if exists f8;
delimiter //
create function f8(instring varchar(32) returns varchar(32)
begin
declare x int default 1;
declare y varchar(32) default ‘’; – 这个养成添加默认值的好习惯,要不然不出结果,具体原理我还没去了解
while x<5 do
set x=x+1;
set y= concat(instring,y);
end while;
return y;
end//
delimiter ;

12,另起一行,我突然注意到procedure函数中,在begin之前,有reads sql data ,no sql,modifieds sql data ,默认情况下系统为contains sql; 这个好像是标识这个函数中sql的增删改查的类型.应该也有利于函数提前进行与判断吧.增加速度.

drop procedure if exists t18;
delimiter //
create procedure t18(in instring varchar(32),out outnum decimal(8,3))
reads sql data
begin
declare o varchar(32) default ‘’;
declare p varchar(32) default ‘’;
declare q decimal(8,2);
declare cur cursor for select id,name,num from test1;
select count() from test1 into outnum;
open cur;
fetch cur into o,p,q;
select o,p,q;
close cur; – 我经常忘记关机游标…在游标里面单独将o,p或q ,赋值给out 好像不管用…专门用了一个count(
)
end//
delimiter ;

13, 网上看到一个简单的逻辑if 结果发现他用的 if else if 的形式…这个记录一下.

drop function if exists f18;
delimiter //
create function f18(idid varchar(32) return varchar(32)
begin
declare x varchar(32) default ‘’;
select id into x from test1 where id = idid;
if x=‘1’ then return ‘boy’;
elseif x=‘2’ then return ‘girl’;
end if; – 差别就是 连起来的elseif 结尾只需要一个end if;
– if x=‘1’ then return (select ‘boy’); else if x=‘2’ then return (select ‘girl’); end if ;end if;
end//
delimiter ;
这次看到的学习资料 begin前面有deterministic 确定性的意思,注释提高where 查询的子句性能.

14,继续补充,发现了一个case 这个和sql语句有点差别

drop function if exists f10;
delimiter //
create function f10(innum int) return varchar(32)
begin
declare x int default 0;
case when innum=1 then select count(*) from test1 into x;
when innum=2 then select num from test1 into x where id=‘1’;
else (select num into x where id=‘2’);
end case;
return x;
end//
delimiter ;
这个case when …then …end case; 像我这种人,也不看定义,就是先试试,结果还挺好.然后再看定义,绝对 不会忘了.

15,继续补充,这就是网上自己找资料学习的坏处,一直是自学,一直自学,所以,肯定要遇到好多遗漏.

有个教程,加注释用了commit ,结果弄的总是报错,实际应该是在你begin 之前放 comment ‘***’ 这样就行,同样的这个注释之后,你可以加上 sql security definer (意思是只有创建的人才能执行…这个其实很好啊.)
也可以这样写
drop function if exists f11;
delimiter //
create function f11(idid varchar(32)) returns varchar(32)
comment ‘how handsome i am’
sql security definer
return (select name from test1 where id =idid)//
delimiter ;
这里摘抄一段mysql的错误代码,希望我以后自己能够看懂英文.
可以定义执行遇到错误的处理方式,handler…
SQLWARNING 匹配所有以01开头的SQLSTATE错误代码;
NOT FOUND 匹配02
SQLEXCEPTION 匹配 除以上的错误
MYSQL_error_code:匹配数值类型错误代码.

16,又见大神语句点悟…存储函数和过程函数定义不同,但是可以实现相同功能.
函数中

create function() return varchar(32)
begin
return (复杂的sql语句) – 我感觉没有过程函数复杂,哈哈.
end

17,如果想查询到底有多少的函数或者过程.

select * from infromation_schema.ROUTINES where ROUTINE_NAME like ‘f%’
可以用show显示具体的详情

show create function f1;

就这样吧.

你可能感兴趣的:(学习笔记)