mysql 存储过程简单使用

一、使用场景

需要将一个复杂的逻辑单元进行封装,屏蔽使用者对细节关注

案例:因为数据库单表增量较大,考虑将该表水平拆分,分成32张表,路由字段为用户id,按照用户id%32将数据散落到各个分表中,中间件采用sharding-sphere。表拆分完成以后,遇到尴尬的问题,生成相同结构的表,所以此处采用了存储过程辅助生成表。

 

二、存储过程说明

存储过程将一段通用的操作封装在一起,这样在不同平台都可以通用了。

存储过程没有返回值,而且没有sql语句调用,只能是call 调用,而且不返回结果集,执行就执行了。

 

三、存储过程语法说明

一、输入/输出参数(in,out,inout)

1)IN 输入参数

1. 表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值

2. 仅需要将数据传入存储过程,并不需要返回计算后的该值。

3. 只能当做传入参数

2)OUT 输出参数

1. 该值可在存储过程内部被改变,并可返回

2. 不接受外部传入的数据,仅返回计算之后的值。

3. 只能当做转出参数

3)INOUT 输入输出参数

1. 调用时指定,并且可被改变和返回

2. 需要数据传入存储过程经过调用计算后,再传出返回值

3. 可当做传入转出参数

二、变量声明(declare,set)

mysql存储过程中declare 和set 定义变量的区别:

1) declare :

declare 变量名 数据类型

例如:

declare i int;

修改变量值:

set 变量名 =  值;

例如:

set i = 0;  

2)set:

使用set 或者select 直接赋值,变量名以@开头

例如:

set @temp=1;

 

可以在会话的任何地方声明,作用域是整个会话,称为会话变量,也是全局变量。

以declare关键字声明的变量,只能在存储过程中使用,称为存储过程变量。 这种变量需要设置变量类型,而且只存在begin....end  这段内

两者区别:

在调用存储过程时,declare声明的变量都会别初始化为null,而会话变量(以@开头的变量)则不会再被初始化,在一个会话内只被初始化一次,之后是对上一次会话的计算结果,相当于这个会话的全局变量。

三、打印参数(输出)

执行计划中,用select + 变量打印变量值。

四、调用存储过程

call + 存储过程

例如:

call copyTable('channel','',5);

五、查看删除存储过程

显示所有存储过程:

show procedure status;

删除指定存储过程:

drop procedure 存储过程名 ;

 

踩坑:mysql 存储过程中不能把变量赋值到表名处,所以,采用预sql,将要执行的sql批出来,再去执行,最后通过deallocate释放执行存储过程中使用的数据库资源。 

六、 示例(复制表)

问题描述:将demo表分成demo0,demo1....,demo31共32张分表。

我们知道,根据现有表结构创建表对应sql

create table ${tableName} like ${copyTable};

 根据上面复制表sql,我们将其转为存储过程:

-- 创建建表存储过程
delimiter //                            #定义标识符为双斜杠
drop procedure if exists copyTable;          
create procedure copyTable(in copyTableName varchar(250),in separatorName varchar(250),in cNums INT)       
begin
    declare i int;
    set i = 0;                   
    repeat
        set @temp := CONCAT(copyTableName,separatorName,i);    #拼接临时生成的表名
        set @sqlTemp := CONCAT('create table ',@temp,' like ',copyTableName);    #拼接要执行的sql语句
        PREPARE stmt from @sqlTemp;          #创建预sql
        EXECUTE stmt;                        #执行预sql
        DEALLOCATE PREPARE stmt;             #释放执行中使用的所有数据库资源
        select CONCAT(@temp,' create success !') as msg ;    #打印
        set i = i + 1; 
    until i > cNums end repeat;               
end
//

 最后,我们调用存储过程

call copyTable('demo', '', 31);

 

posted @ 2021-03-04 13:09  不喝北冰洋  阅读(306)  评论(0编辑  收藏  举报