您现在的位置是:网站首页 > 博客日记 >

mysql进阶篇之变量及存储过程

作者:YXN-sql 阅读量:215 发布日期:2021-11-18

变量

1、系统变量

是mysql服务器提供,不是用户自定义的,属于服务器层面。分为全变量global、会话变量session。

# 查看系统变量
 show [session|global] variables; --查看所有的系统变量
 show [session|global] variables like ‘...’; --可以通过like模糊匹配方式查找变量
 select @@[session/global.]系统变量名; --查看指定变了的值,注意可选参数里面的.
 
 # 设置系统变量
 set [session|global] 系统变量名字 = 值; --不需要@,查询是才需要@
 上面这种设置全局变量方法重启后就失效,不想失效就修改参数文件, 然后重启mysqld
 vi /etc/my.cnf
 [mysqld]
 wait_timeout=10
 
 例子:
 show session variables like 'auto%'
 select @@global.autocommit;
 select @@session.autocommit;
     
 set session auto_increment = 1 ;

2、用户变量

是用户根据需求自己定义的变量,用户变量不用提前声明,在用是时候直接用‘@变量名’使用就可以。其作用域为当前连接。

赋值
 set @var_name = 值;
 set @var_name := 值; --推荐使用这种冒号等于的方式定义
 
 select @var_name := 值;
 select 字段名 into @var_name from 表名;
 
 查看变量
 select @var_name ;   --如果直接select 一个不存在的用户变量名会返回null而不会报错
 
 例子:--赋值
     set @myname := 'xiaoming';
     set @myage := 18;
    --使用
     select @myname,@myage

3、局部变量

是根据需要定义在局部生效的变量,访问之前,需要declare声明。可用作存储过程内的局部变量和输入参数,局部变量的作用范围是在其内声明的begin...end模块。

声明:
 declare 变量名 变量类型(长度) [default 默认值]
 变量类型就是数据库字段类型:int、bigint、char、varchar、date、time
 
 赋值:
 set 变量名 = 值;
 set 变量名 := 值;
 select 字段名 into 变量名 from 表名;
 
 ps:区分技巧:系统变量有2个@@,用户变量1个@,局部变量在存储过程或存储函数内部用declare声明。

存储过程

# 创建存储过程(函数)
 # 语法形式
 create procedure 存储过程名([[IN |OUT |INOUT ] 参数名 数据类形(长度)...])
 begin
 sql语句;
 end;
 
 # IN 输入参数:表示调用者向过程传入值(传入值可以是自变量或变量)
 # OUT 输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
 # INOUT 输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)
 
 # 查看存储过程
 select * from information_schema.routines where routine_schema = 'xxx'; --查看指定数据库的存储过程及状态信息
 show create procedure 存储过程名字 ; --查看某个存储过程的定义sql语句
 
 # 删除存储过程
 drop procedure [if exists] 存储过程名字;
 
 
 # 举例
 # 带有输入参数的存储过程
 create procedure a(in test1 varchar(15))
 begin
 select char_length(test1);
 end;
 # 调用存储过程
 call a('上海');
 
 # 带有输入参数与输出参数的存储过程
 create procedure a1(in test1 varchar(15),out len1 int)
 begin
 select char_length(test1) into len1;
 end;
 
 call a1('乌鲁木齐',@len1);
 select @len1;

 实践

1、创建一个存储过程,输入一个分数后返回是分数的评判等级

create procedure p1(in score int, out result varchar(10))
begin 
     if score >= 85 then
        set result := '优秀';
     elseif score >= 60 then
        set result := '及格';
     eles
        set result := '不及格';
     end if;
end;
 
call p1(85,@result); --来一个用户自定义变量来接收out返回的值
select @result;
 

2、将传入的200分制的分数,进行换算,换成百分制,然后返回分数---> inout

create procedure p2(inout score duble)
begin
     set score := score * 0.5;
end;
 
set @score = 78;
call p2(@score);
select @score;
 

3、while实现1到n的累加

create procedure p3(in n int)
begin
     declare total int default 0;
     while n>0 do
           set total := total + n;
           set n := n -1;
     end while;
     select total;
end;
 

4、repeat实现计算1到n的累加,n为传入参数值 --a.定义局部变量,记录累加之后的值; --b.每循环一次,就对n➖1,n为0则退出循环

create procedure p4(in n int)
begin 
     declare total int default 0;
    
     repeat
           set total := total + n;
           set n := n-1;
     until n<=0
     end repeat;
     select total;
 
end;
 

5、loop实现1到n的奇数的累加

create procedure p5(in n int)
begin 
     declare total int default 0;
    
     sum:loop
 
         if n<=0 then
            leave sum;
         end if;
         
         if n%2 = 1 then
            set n := n -1;
            iterate sum;
         end if;
 
         set total := total + n;
         set n := n -1;
 
     end loop sum;
   
     select total;
 
end;
 

6、case when使用

create procedure p6(in month int)
begin
     declare result varchar(10);
   
     case 
         when month >= 1 and month <= 3 then
              set result := '第一季度';
         when month >=4 and month <= 6 then
              set result := '第二季度';
         when month >= 7 and month <= 9 then
              set result := '第三季度';
         when month >=10 and month <= 12 then
              set result := '第四季度';
         else
              set result := '非法参数';
    end case;
    select result;
 
end;
 
call p6(6)
 

7、游标的使用, 输入一个年龄,把tb_user表中小于这个年龄的用户的信息插入到另一个表tb_user_pro中

create procedure p7(int uage int)
begin
     declare u_cursor cursor for select name,profession from tb_user where age <=uage;
     declare uname varchar(10);
     declare upro varchar(100);
 
     declare exit handler for NOT FOUND close u_cuesor; --条件处理程序,当下面while循环时游标的数据为空时就不会报错了。
 
     drop table id exists tb_user_pro;
     create table if exists tb_user_pro(
          id int primary key auto_increment,
          name varchar(10),
          profession varchar(100)
     );
 
     open u_cursor;
 
     while true do
          fetch u_cursor into uname,upro;
          insert into tb_user_pro values(null,uname,upro);
     end while;
     close u_cursor;
 
end;

YXN-sql

2021-11-18