#创建存储子程序需要CREATE ROUTINE权限。
#· 提醒或移除存储子程序需要ALTER ROUTINE权限。这个权限自动授予子程序的创建者。
#· 执行子程序需要EXECUTE权限。然而,这个权限自动授予子程序的创建者。同样,子程序默认的SQL SECURITY 特征是DEFINER,它允许用该子程序访问数据库的用户与执行子程序联系到一起
#-------------------------------------------------------------------------------------------------------#
#mysql函数即使重启mysqld服务后函数依然会存在,只存在指定的数据库,不会跨数据库
drop database if exists test_1;
create database test_1;
use test_1;
drop table if exists test1;
#create table test1 (user_id int(11) auto_increment,user_sn int() not null,primary key(user_id));
select year(now()),month(now()),dayofmonth(now()); #年月日
select concat(year(now()),month(now()),dayofmonth(now())); #年月日
create table userorder (userorder_id int(11) auto_increment,primary key(userorder_id),order_sn bigint(15) not null);#用户订单表
#sql自定义函数的总结
delimiter $$ #定义结束符 $$
drop function if exists hello; #判断hello函数是否存在,如果存在则删除
create function test_1.hello (name char(20),age int(2)) returns char(225) #sql 顾名思义 是创建函数的意思 , 注意:语言是强类型语言因此要声明参数的类型 和返回值的类型
begin #函数体的开始
#set @i=0; #声明一个全局变量@i sql也有局部和全局变量
declare greeting char(20); #声明一个局部变量 注意:函数内部不能同时有局部变量和全局变量的存在
declare num int(20);
declare str char(20);
declare restr char(225);
declare max int(20);
if hour(now()) < 12 then
set greeting ='早上好'; #set 一般用来赋值 赋值给局部变量 全局变量一样
elseif hour(now()) >12 then
set greeting ='下午好';
end if; #end if这里一定要分开
if (age < 18) then #判断条件可以加上括号
set str='未成年';
else
set str='成年';
end if;
set num=0;
while num < age do
set num=age+1;
end while; #注意分开 end while
set max =0;
w:while age < 100 do
set age=age+1;
if age = 4 then
#leave w; #leave 相当于break 跳出循环 w 是指明关键字leave跳出那个循环的
iterate w; #iterate 相当于continue 跳过循环
end if;
set max=max+1;
end while w;
#select concat(name,greeting,'你的幸运数字是') into restr;
select concat(name,greeting,'你的幸运数字是',max,str) into restr;
return restr;
end
$$
delimiter ;
select test_1.hello('huangyanxiong',12); #函数调用
#-------------------------------------------------------------------------------------------------------------------------------------#
#创建一个自动生成订单序号的函数20140103001
#作用:可以减少连接数据库的次数,减少数据库的负担,加快程序的的运行
drop function if exists create_sn;
delimiter $$
create function test_1.create_sn() returns bigint(15) #编写程序时要注意数据类型
begin
declare order_sn bigint(15);
declare prev bigint(15);
declare prevdatetime bigint(15);
declare sn bigint(15);
declare nowdate bigint(15);
select order_sn from userorder order by userorder_id desc limit 1 into prev; #赋值prev
select concat(year(prev),month(prev),dayofmonth(prev)) into prevdatetime;
select right(prev,4) into sn;
select concat(year(now()),month(now()),dayofmonth(now())) into nowdate;
#if isnull(prev) && nowdate = prevdatetime then mysql不支持这样写
if isnull(prev) then
select concat(nowdate,'0001') into order_sn;
return order_sn;
elseif nowdate = prevdatetime then
select concat(nowdate,'0001') into order_sn;
return order_sn;
else
select concat(prevdatetime,(sn+1)) into order_sn;
return order_sn;
end if;
end
$$
delimiter ;
select create_sn();
#---------------------------------------------------------------------------------------------------
#产生随机字符串,用于测试数据库
drop function if exists randstr;
delimiter $$
create function test_1.randstr(num int(11)) returns char(255) #为了容易区分那个函数或者存储过程是那个数据库的,可以在函数名中加上数据库前缀test_randstr;
begin
declare str char(255) default 'q1we23r4t5y6u7i8o9p0asdfghjklzxcvbnm';
declare nums int(11);
declare returnstr char(255); #SQL变量名不能和列名一样
declare i int(11) default 0; #在声明变量时一定要在begin语句之后,除begin外的任何语句之前
select floor(truncate(rand(),1)*36)+1 into nums; #加1时为了防止产生随机数生成0的情况
select substring(str,nums,1) into returnstr;
#declare i int(11) default 0; #在声明变量时一定要在begin语句之后,除begin外的任何语句之前,像这个语句是不允许的
while i
select floor(truncate(rand(),1)*36)+1 into nums;
select concat(substring(str,nums,1),returnstr) into returnstr;
#set returnstr=concat(substring(str,nums,1),returnstr);
set i=i+1;
end while;
return returnstr;
end
$$
delimiter ;
#-----------------------------------------------------------------------------------------------------------------------#
show function status like '%rand%'; #查看函数的状态 包括:函数所属数据库,函数名,类型,创建时间,创建者,安全类型 注释 ,数据库字符集,客户端字符集
show procedure status like '%procedure_name'; #同上
#------------------------------------------------------------------------------------------------------------------------------#
insert into userorder values(null,test_1.create_sn());
#-------------------------------------------------------------------------------------------------------------------------------------#
drop function if exists ceshi;
delimiter $$
create function ceshi() returns char(255)
begin
declare ceshistr1 char(255);
declare ceshistr2 char(255);
declare ceshistr char(255);
#select order_sn,userorder_id from userorder limit 1 into ceshistr; #ERROR 1222 (21000): The used SELECT statements have a different number of columns
select order_sn,userorder_id into ceshistr1,ceshistr2 from userorder limit 1 ; #在mysql中一个列的数据必须占用一个变量,否则会出现上面的错误
select concat(ceshistr1,ceshistr2) into ceshistr;
#select * from userorder; #存储函数的限制:不能再存储函数中返回整个表的数据ERROR 1415 (0A000): Not allowed to return a result set from a function
return ceshistr; #而存储过程可以返回整张表的数据
end
$$
delimiter ;
#-------------------------------------------------------------------------------------------------------------------------------------------#
drop procedure if exists simpleproc;
delimiter $$
CREATE PROCEDURE simpleproc (OUT param1 INT)
BEGIN
SELECT * FROM userorder; #而存储过程可以返回整张表的数据
END
$$
delimiter ;
call simpleproc(); #调用存储过程
#---------------------------------------------------------------------------------------
drop procedure if exists pr_param_in;
delimiter $$
create procedure pr_param_in ( in id int)
begin
if (id is not null) then
set id = id + 1;
end if;
select id as id_inner;
end;
$$
delimiter ;
#----------------------------------------------------------------------------------------------------------------------------------------------------#
#----------------------------------------------------------------------------------------------------------------------#
#第一个自己的存储过程
drop procedure if exists test; #判断一个存储过程是否存在存在则删除
delimiter $$
create procedure test ()
begin
select 'hello world!' as helloworld;
end;
$$
delimiter ;
call test();
#--------------------------------------------------------------------------------------------------------#
#存储过程学习声明变量
drop procedure if exists test2;
delimiter $$
create procedure test2 ()
begin
declare str char(255) default 'huangyanxiong'; #在存储过程声明局部变量并赋值
set @color='red'; #在存储过程中声明全局变量并赋值, 注意:函数内不能同时有局部变量和全局变量
#select * from userorder;
select @color as colors; #一般采用这种方式输出到终端
end
$$
delimiter ;
call test2();
#--------------------------------------------------------------------------------------#
#存储过程传递参数
drop procedure if exists test3;
delimiter $$
create procedure test3(in username char(50))
begin
select username as user_name;
end
$$
delimiter ;
call test3('huangyanxiong');
drop procedure if exists test4;
delimiter $$
#----------------------------------------------------------------------------------#
create procedure test4(username char(50))
begin
declare str char(50);
select concat(username,'xxxxxx') into str;
select str as string; #设置别名返回
#select 'dds' as d;
#return strs; # ERROR 1313 (42000): RETURN is only allowed in a FUNCTION return 语句只能在函数中使用
end;
$$
delimiter ;
call test4('huangyanxiong');
#------------------------------------------------------------------------------------#
drop procedure if exists test5;
delimiter $$
create procedure test5 (username char(50)) #默认使用in
begin
set @age=12;
select username as usernames,@age as age; #使用同一张表返回
end
$$
delimiter ;
call test5('huangyanxiong');
#-------------------------------------------------------------------------------------#
#把函数改变为存储过程很简单,把函数改改就可以
#把上面的订单序号改为存储过程
drop procedure if exists create_sn;
delimiter $$
create procedure create_sn()
begin
declare order_sn bigint(15);
declare prev bigint(15);
declare prevdatetime bigint(15);
declare sn bigint(15);
declare nowdate bigint(15);
select order_sn into prev from userorder order by userorder_id desc limit 1 ; #赋值prev
SELECT prev;
select concat(year(prev),month(prev),dayofmonth(prev)) into prevdatetime;
select right(prev,4) into sn;
select concat(year(now()),month(now()),dayofmonth(now())) into nowdate;
#if isnull(prev) && nowdate = prevdatetime then mysql不支持这样写
if isnull(prev) then
select concat(nowdate,'0001') into order_sn;
select order_sn as ordersn;
elseif nowdate != prevdatetime then
select concat(nowdate,'00011') into order_sn;
select order_sn as ordersn;
else
select concat(prevdatetime,(sn+1)) into order_sn;
select order_sn as ordersn;
end if;
end
$$
delimiter ;
select * from userorder;
call create_sn();
#-------------------------------------------------------------------------------#
#产生随机字符串,用于测试数据库
drop procedure if exists randstr;
delimiter $$
create procedure randstr(num int(11)) #为了容易区分那个函数或者存储过程是那个数据库的,可以在函数名中加上数据库前缀test_randstr;
begin
declare str char(255) default 'q1we23r4t5y6u7i8o9p0asdfghjklzxcvbnm';
declare nums int(11);
declare returnstr char(255); #SQL变量名不能和列名一样
declare i int(11) default 0; #在声明变量时一定要在begin语句之后,除begin外的任何语句之前
select floor(truncate(rand(),1)*36)+1 into nums; #加1时为了防止产生随机数生成0的情况
select substring(str,nums,1) into returnstr;
#declare i int(11) default 0; #在声明变量时一定要在begin语句之后,除begin外的任何语句之前,像这个语句是不允许的
while i
select floor(truncate(rand(),1)*36)+1 into nums;
select concat(substring(str,nums,1),returnstr) into returnstr;
#set returnstr=concat(substring(str,nums,1),returnstr);
set i=i+1;
end while;
select returnstr as randstr;
end
$$
delimiter ;
call randstr(5);
#----------------------------------------------------------------------#