存储过程原理

一、描述
  存储过程是一组可以完成特定功能的SQL语句集,经编译后存储在数据库中

  statement语句(DDL[数据库模式定义语言]、DML、导出及管理语句等)、异常处理、流程控制

二、创建存储过程

      系统做语句分析,如果没有出现词、语法等的错误则存入系统表mysql.proc中
三、调用存储过程

存储过程的执行就是从该组指令集的第一个指令开始顺序执行
   系统对存储过程的解析是以语句或结构为单位的,该部分处理在YACC中完成
   注意:语句和指令之间并非一对一的对应关系

存储过程体中的语句集会被解析为一组指令集


2、执行
  当调用存储过程的命令(CALL...)发送到服务端时,该语句会被解析并触发对系统表mysql.proc的读取以及对存储过程语句集的解析,在该解析过程中会创建sp_head对象以及sp_instr各子类的对象,生成指令集并进行优化(如果此存储过程在当前session中已被调用过,则解析后的相关信息会被存储在缓存中,此时可略过db_load_routine()中各步骤,直接使用)
  在执行指令集之前,需将传入的参数进行对应项的改写与填充,并根据指令类型的不同进行不同的处理,并最终由net_end_statement()将结果集发送回客户端

四、指令集
  打开动态游标、部分declare语句、SET语句、LEAVE语句、LOOP结构、IF结构、CASE    结构、REPEAT结构和WHILE结构会被拆分为多条指令
  其余和statement语句则不会被拆分为多条指令,即自身就对应一条指令

1、DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement;
  此语句会被拆分为3部分:
  1)记录handler信息指令,对应 sp_instr_hpush_jump子类,指定跳转位置
  2)sp_statement 代表处理器指令,是用户自定义的语句部分
  3)根据handler类型指定跳转位置,对应 sp_instr_hreturn子类
2、DECLARE var_name[,...] type [DEFAULT value];
  此语句随定义var_name的个数被拆分成若干赋值指令,对应sp_instr_set子类
3、DECLARE <游标名称> CURSOR FOR <SELECT 语句>;
  定义静态游标指令,对应sp_instr_cpush子类,负责记录cursor信息
4、SET var_name = expr [, var_name = expr];
  此语句随定义var_name的个数被拆分成若干赋值指令。若var_name为存储过程的局部变量,则指令对应sp_instr_set子类
  若var_name为系统或用户级变量,则指令对应sp_instr_stmt子类
5、OPEN <游标名称>;
  打开静态游标指令,对应sp_instr_copen子类,负责执行<SELECT 语句>
6、DECLARE <游标名称> REF CURSOR;
  定义动态游标指令,对应sp_instr_cpush子类,负责记录cursor信息
7、OPEN <游标名称> FOR <SELECT 语句>;
  打开动态游标,此语句会被拆分为2部分:
  1)定义动态游标指令,对应sp_instr_cpush子类,负责记录cursor信息
  2)打开动态游标指令,对应sp_instr_copen子类,负责执行<SELECT 语句>
8、FETCH <游标名称> INTO <局部变量>;
  获取结果指令,对应sp_instr_cfetch子类,负责从游标中获取数据
9、CLOSE <游标名称>;
  关闭游标指令,对应sp_instr_cclose子类
10、IF <判断条件> THEN <执行体> END IF;
  此语句会被拆分为3部分:
  1)条件判断指令,对应 sp_instr_jump_if_not子类,指定跳转位置
  2)<执行体> 代表指令集,包是用户自定义的语句部分
  3)分支跳转指令,对应 sp_instr_jump子类,指定跳转位置
11、IF <判断条件> THEN <执行体1> ELSE <执行体2> END IF;
  此语句会被拆分为4部分:
  1)条件判断指令,对应 sp_instr_jump_if_not子类,指定跳转位置
  2)<执行体1> 代表指令集,是用户自定义的语句部分
  3)分支跳转指令,对应 sp_instr_jump子类,指定跳转位置
  4)<执行体2> 代表指令集,是用户自定义的语句部分
12、ITERATE<标签名>;
  分支跳转指令,对应 sp_instr_jump子类,指定跳转位置
13、LEAVE <标签名>;
  分支跳转指令,对应 sp_instr_jump子类,指定跳转位置
  如果在跳出当前的BEGIN...END语句块中存在handler,则会在sp_instr_jump子类之前增加删除handler记录的指令,对应sp_instr_hpop子类
  如果在跳出当前的BEGIN...END语句块中存在cursor,则会在sp_instr_jump子类之前增加删除cursor记录的指令,对应sp_instr_cpop子类
14、LOOP <执行体> END LOOP;
  此语句会被拆分为2部分:
  1)<执行体>代表指令集,是用户自定义的语句部分
  2)分支跳转指令,对应 sp_instr_jump子类,指定跳转位置
15、CASE WHEN <条件1> THEN <执行语句1> ELSE <执行语句X> END CASE;
  CASE结构体中可有若干WHEN...THEN...复合语句,此处只对单一情况做说明,此时语句会被拆分为4部分:
  1)条件判断指令,对应 sp_instr_jump_if_not子类,指定跳转位置
  2)<执行语句1>代表指令集,是用户自定义的语句部分
  3)分支跳转指令,对应 sp_instr_jump子类,指定跳转位置
  4)<执行语句X>代表指令集,是用户自定义的语句部分
  对于语句中不存在ELSE <执行语句X>,则第4)部分变为错误信息记录指令,对应    sp_instr_error子类
16、CASE <判定条件> WHEN <值1> THEN <执行语句1> ELSE <执行语句X> END CASE ;
  CASE结构体中可有若干WHEN...THEN...复合语句,此处只对单一情况做说明,此时语句会被拆分为5部分:
  1)表达式计算指令,对应sp_instr_set_case_expr子类,计算<判定条件>
  2)<值1>条件判断指令,对应 sp_instr_jump_if_not子类,指定跳转位置
  3)<执行语句1>代表指令集,是用户自定义的语句部分
  4)分支跳转指令,对应 sp_instr_jump子类,指定跳转位置
  5)<执行语句 X>代表指令集,是用户自定义的语句部分
  对于语句中不存在ELSE <执行语句X>,则第5)部分变为错误信息记录指令,对应sp_instr_error子类
17、REPEAT <执行体> UNTIL<退出条件> END REPEAT;
  此循环结构被拆分为2部分:
  1)<执行体>代表指令集,是用户自定义的语句部分
  2)条件判断指令,对应 sp_instr_jump_if_not子类,指定跳转位置
18、WHILE <执行条件> DO <执行体> END WHILE;
  此循环结构被拆分为3部分:
  1)条件判断指令,对应 sp_instr_jump_if_not子类,指定跳转位置
  2)<执行体>代表指令集,是用户自定义的语句部分
  3)分支跳转指令,对应 sp_instr_jump子类,指定跳转位置
19、[begin_label:] BEGIN [statement_list] END [end_label]
  [statement_list]代表指令集,是用户自定义的语句部分
  如果在当前BEGIN...END语句块中存在handler,则会在语句末尾增加删除handler记录的指令,对应sp_instr_hpop子类
  如果在当前BEGIN...END语句块中存在cursor,则会在语句末尾增加删除cursor记录的指令,对应sp_instr_cpop子类



存储过程语句集指令集
  
  
  
  
  
  
  
  
  


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值