mysql 函数和存储过程的学习

#创建存储子程序需要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 <num do
    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 <num do
    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);
#----------------------------------------------------------------------#



你可能感兴趣的:(mysql 函数和存储过程的学习)