首页 > 技术文章 > MYSQL 存储过程与函数

cqyy 2018-09-10 18:39 原文

存储过程 :一组可编程的函数,是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

  (1)创建一个简单存储过程语法:   

    首先将数据库以分号结束的语法修改:delimiter $$ #将语句的结束符号从分号;临时改为两个$$(可以是自定义)

    然后开始创建:

          CREATE PROCEDURE delete_mat(IN p_in INTEGER)
            BEGIN
              DELETE FROM MATCHES
              WHERE playerno = p_playerno;
            END $$
    最后:delimiter ;  #将语句的结束符号恢复为分号

(2)调用存储存储过程:call 存储过程名称(参数);
 (3)存储过程体:过程体格式:以begin开始,以end结束(可嵌套);
 (4)为语句块贴标签:
      label1: BEGIN
        label2: BEGIN
          label3: BEGIN
            statements; 
          END label3 ;
        END label2;
      END label1
   存储过程的参数:
      
IN输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)
      OUT输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
      INOUT输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)

  注意:

    ①如果过程没有参数,也必须在过程名后面写上小括号

      例:CREATE PROCEDURE sp_name ([proc_parameter[,...]]) ……

    ②确保参数的名字不等于列的名字,否则在过程体中,参数名被当做列名来处理

      输入值使用in参数;

 

返回值使用out参数;

 

inout参数就尽量的少用。

 删除存储过程和函数:Drop procedure 过程名称。函数的话,将procedure换成function;

存储过程和函数的区别:存储过程没有返回值,函数必须有返回值。

查看存储过程或函数
   (1)查看存储过程或者函数的状态:show {procedure|function} status {like 'pattern'};
   (2) 查看存储过程或者函数的定义:show create {procedure | function} 名称;
   (3)查看information_schema.Routines了解函数和存储过程信息:select * from information_schema.routines where routine_name = '名称';

函数创建
  
create function 名称(参数名称 类型,...) return 数据类型 begin [定义变量] 。。。return 结果 end $$


变量的使用
  (1)定义变量:declare 变量名 type [default value];eg:declare last_month_start Date;
   (2)变量赋值:变量可以直接赋值木业可以通过查询赋值(结果必须返回的是一行)。直接赋值使用set,可以赋值常量或者表达式。
定义条件和处理
  (1)定义条件:declare 条件名称 condition for condition_value;
          condition_value:SQLstate[value] sqlstate_vale|mysql_error_code
  (2)条件处理:declare handler_type handler for condition_value[...] sp_statement;
          handler_type:continue|exit|undo
          condition_value:sqlstate[value] sqlstate_value|condition_name|sqlwarning|not found|sqlexception|mysql_error_code
          sqlwarning是对所有以01开头的sqlstate代码速记;
          not found 是对所有以02开头的sqlstate大妈速记;
          sqlexception是对没有被sqlwarning或not found
捕获的sqlstate代码速记。
光标的使用
      
   (1)声明光标:declare cursor_name Cursor for select_statement;
   (2)Open光标:Open cursor_name;
   (3)fetch光标:fetch cursor_name into var_name[,var_name]...;
   (4)close光标:closer cursor_name;
eg:
    

  mysql> delimiter $$
  mysql> create procedure t_start()
  -> begin
  -> declare i_staff_id int;
  -> declare d_amount decimal(5,2);
  -> declare cur_payment cursor for select id,amount from t;
  -> declare exit handler for not found close cur_payment;
  -> set @x1=0;set @x2=0;
  -> open cur_payment;
  -> repeat
  -> fetch cur_payment into i_staff_id,d_amount;
  -> if i_staff_id = 2 then set @x1=@x1+d_amount;
  -> else set @x2=@x2+d_amount;
  -> end if;
  -> until 0 end repeat;
  -> close cur_payment;
  -> end;
  -> $$    #注:变量、条件、处理程序、光标都是通过declare定义,有先后顺序。变量和条件必须在最前面声明,然后才能是光标的声明,最后才是处理程序的声明。

 流程控制
  主要使用的流程控制语句:if、case、loop、leave、iterate、repeat和while语句进行流程控制。
  (1)if语句:if search_condition then statement_list[elseif search_condition then statement_list]...[else statement_list] end if;
  (2)case语句:case case_value when when_value then statement_list [when when_value then statement_list]...[else statement_list] end case;
      或
case when when_value then statement_list [when when_value then statement_list]...[else statement_list] end case;
  (3)loop语句:[begin_label:]loop statement_list end loop [end_label];
  (4)leave语句:用来从标注的流程构造中退出,通常和begin...end或者循环一起使用。eg: ...   begin_label:loop ...;leave begin_label;....end loop end_label;...
  (5)iterate语句:必须用在循环中,作用是跳过当前循环的剩下语句,直接进入下一轮循环(与基础循环中的continue类似)。
  (6)repeat语句:当满足条件的时候退出循环,[begin_label:]repeat statement_list until search_condition end repeat [end_label];
  (7)while语句:[begin_label:]while search_condition do statement_list end while [end_label];

事件调度器
  事件调度器语法:create event 事件名称 on schedule 何时以及频次 do 操作。
  eg:

      mysql> create event test_event
      -> on schedule every 10 second
      -> do
      -> insert into txk.t(id,context,amount) values(12,'test',2);
      Query OK, 0 rows affected (0.08 sec)

  查看调度器状态:show events;
  查看事件调度器状态: show variables like '%scheduler%';(默认是关闭)
  打开事件调度器: set global event_scheduler = 1;
  查看后台进程:show processlist;
  创建一个每隔1分钟清空一次表:

        mysql> create event trunc_test
        -> on schedule every 1 minute
        -> do truncate table t;
        Query OK, 0 rows affected (0.00 sec)

  禁用或者删除时间调度器:alter event 事件调度器名称 disable;drop event 时间调度器名称;



推荐阅读