MySQL存储过程和函数

存储过程就是一条或多条SQL语句的集合

 创建存储过程和函数

创建存储过程:create procedure

创建函数:create function

调用存储过程:CALL

创建存储过程

create procedure sp_name([proc_parameter])

[characteristics...] routine_body

[in|out|inout] param_name type

 

mysql> delimiter $

mysql> create procedureavgfruitprice()

   -> begin

   -> select avg(f_price) as avgprice

   -> from fruits;

   -> end$

创建存储函数

create function func_name([func_parameter])

returns type

[characteristic...] routine_body

[in|out|inout]param_name type

 

mysql> delimiter //

mysql> create function namebyzip()

   -> returns char(50)//RETURN子句只能对FUNCTION做指定

   -> return (select s_name from suppliers where s_call='48075');

   -> //

Query OK, 0 rows affected (0.05sec)

 

mysql> delimiter ;

变量的使用

范围BEGIN....END程序中起做用

定义变量

declare var_name[,varname].... date_type[default value];

eg: declare myparam int default100;

为变量赋值

set var_name=expr[,var_name=expr]...;

declare var1,var2,var3 int;

set var1=10,var2=20

set var3=var1+var2;

为多个值赋值:

select col_name[...] intovar_name[,...] table_expr;

定义条件和处理程序:

定义条件

declare condition_name conditionfor [condition_type]

[condition_type]:

       sqlstate[value]sqlstate_value | mysql_error_code

eg:

declare command_not_allowedcondition for sqlstate '42000';

declare command_not_allowedcondition for 1148

定义处理程序

declare handler_type handler forcondition_value[,...] sp_statement

handler_type:

       continue|exit|undo

condition_value:

       sqlstate[value] sqlstate_value

|condition_name

|sqlwarning

|not found

|sqlexeception

|mysql_error_code

eg:

declare continue handler forsqlstate '42s02' set @info='no_such_table';

 

declare continue handler for 1146set @info='no_such_table';

 

declare no_such_table condition for1146;

declare continue handler forno_such_table set @info='no_such_table';

 

declare exit handler for sqlwarningset @info='error';

 

declare exit handler for not foundset @info='no_such_table';

 

declare exit handler forsqlexception set @info='error';

 

定义条件和处理程序:

mysql> create table test.t(s1int,primary key(s1));

Query OK, 0 rows affected (0.03sec)

mysql> delimiter //

mysql> create procedurehandlerdemo()

   -> begin

   -> declare continue handler for sqlstate '23000' set @x2=1;     // @var_name 表示用户变量

   -> set @x=1;

   -> insert into test.tvalues(1);

    -> set @x=2;

    -> insert into test.t values(1);

    -> set @x=3;

    -> end;

    -> //

Query OK, 0 rows affected (0.00sec)

mysql> delimiter ;

mysql> callhandlerdemo();   //调用存储过程

mysql> insert into t(s1)values(1);

ERROR 1062 (23000):Duplicate entry '1' for key 'PRIMARY'

光标的使用:

光标必须在声明处理程序之前被声明,并且变量和条件还必须在声明光标或处理程序之前被声明

声明:

declare cursor_name cursor forselect_statement

eg:declare cursor_fruit cursorfor select f_name,f_price from fruits;

打开光标:

open cursor_name{光标名称}

eg:open cursor_fruit;

使用光标:

fetch cursor_name into var_name[,var_name]...{参数名称}

eg:fetch cursor_fruit intofruit_name,fruit_price  //fruit_name,fruit_price 必须在前面已定义

关闭光标;

close cursor_name{光标名称}

eg:close cursor_fruit;

光标只能在存储过程和函数中使用

流程控制的使用

语句:

IF  CASE LOOP  WHILE   LEAVE ITERATE  REPEAT  WHILE

 

IF语句:

if expr_condition  then statement_list

       [elseifexpr_condition then statement_list]...

       [elsestatement_list]

end if

eg:

if val is null

       thenselect 'val is null';

       elseselect 'val is not null';

end if;

CASE语句:类型1

case case_expr

       whenwhen_value then statement_list

       [whenwhen_value then statement_list]...

       [elsestatement_list]

end case

eg:

case val

       when1 then select 'val is 1';

       when2 then select 'val is 2';

       elseselect 'val is not 1 or 2';

end case;

CASE语句:类型2

case

       whenexpr_condition then statement_list

       [whenexpr_condition then statement_list]...

       [elsestatement_list]

end case

eg:

case

       whenval is null then select 'val is null';

       whenval<0 then select 'val is less than 0';

       whenval>0 then select 'val is greater than 0';

       elseselect 'val is 0';

end case;

 

Loop语句:

Loop循环语句可以用来重复执行某些语句,leave子句跳出循环

[loop_label:] LOOP

       statement_list

end loop[loop_label]

eg:

declare id int default 0;

add_loop:LOOP

       SETid=id+1;

       ifid>=10 then leave add_loop;

       endif;

end loop add_loop;

LEAVE语句:

LEAVE label

eg:

add_num:LOOP

       SET@count=@count+1;

       IF@count=50 THEN LEAVE add_num;

END LOOP add_num;

 

ITERATE语句:

将执行顺序转到语句开头处,(意思为再次循环)只能出现在LOOP,REPEATWHILE语句内

ITERATE label

eg:

mysql> create proceduredoiterate()

    -> begin

    -> declare p1 int default 0;

    -> my_loop:LOOP

    -> set p1=p1+1;

    -> if p1<10 then iterate my_loop;

    -> elseif p1>20 then leave my_loop;

    -> end if;

    -> SELECT 'p1 is between 10 and 20';

    -> END LOOP my_loop;

    -> END//

REPEAT语句:

REPEAT语句创建一个带条件判断的循环过程,每次语句执行完毕之后,会对条件表达式进行判断,如果表达式式的真,则循环结束,否则重复执行循环中的语句

[repeat_label:]REPEAT

       statement_list

UNTIL expr_condition

END REPEAT [repeat_label]

eg:

declare id int default 0;

REPEAT

       SETid=id+1;

       UNTILid>=10;

END REPEAT;

WHILE语句:

[while_label:] WHILEexpr_condition DO

       statement_list

END WHILE [while_label]

eg:

declare i int default 0;

WHILE i<10 DO

       SETi=i+1;

END WHILE;

调用存储过程和函数

存储过程使用:CALL来调用,如果是不同的数据库,要用CALL dbname.procename

调用存储过程:

CALL sp_name([parameter[,...]])

mysql> create procedure rsc(insid int,out num int)

    -> begin

    -> select count(*) into num fromfruits where s_id=sid;

    -> end//

Query OK, 0 rows affected (0.04sec)

mysql> delimiter ;

mysql> call rsc(101,@num);

Query OK, 0 rows affected (0.07sec)

mysql> select @num;

+------+

| @num |

+------+

|    3 |

+------+

1 row in set (0.00 sec)

mysql> select * from fruitswhere s_id=101

    -> ;

+------+------+------------+---------+

| f_id | s_id | f_name     | f_price |

+------+------+------------+---------+

| a1   |  101| apple      |    5.20 |

| b1   |  101| blackberry |   10.20 |

| c0   |  101| cherry     |    3.20 |

+------+------+------------+---------+

3 rows in set (0.00 sec)

调用存储函数

mysql> delimiter //

mysql> create function rsc(sidint)

    -> returns int

    -> begin

    -> return(select count(*) from fruitswhere s_id=sid);

    -> end//

Query OK, 0 rows affected (0.05sec)

mysql> delimiter ;

mysql> select rsc(101);

+----------+

| rsc(101) |

+----------+

|        3 |

+----------+

1 row in set (0.01 sec)

查看存储过程和函数

1.SHOW STATUS 语句查看存储过程和函数的状态

show {procedure|function} status[like 'pattern']

eg:

mysql> show procedure statuslike 'r%'\G;

*************************** 1.row ***************************

                  Db: test

                Name: rsc

                Type: PROCEDURE

             Definer: root@localhost

            Modified: 2014-09-16 22:14:29

             Created: 2014-09-16 22:14:29

       Security_type: DEFINER

             Comment:

character_set_client: utf8

collation_connection:utf8_general_ci

 Database Collation: utf8_general_ci

1 row in set (0.05 sec)

 

ERROR:

No query specified

SHOW CREATE 语句查看存储过程和函数的定义

show create {procedure | function} sp_name

mysql> show create function test.rsc\G;

*************************** 1.row ***************************

            Funcdtion: rsc

            sql_mode:

     Create Function: CREATEDEFINER=`root`@`localhost` FUNCTION `rsc`(sid int) RETURNS int(11)

begin

return(select count(*) from fruitswhere s_id=sid);

end

character_set_client: utf8

collation_connection:utf8_general_ci

 Database Collation: utf8_general_ci

1 row in set (0.00 sec)

ERROR:

No query specified

information_schema.Routines表中查看存储器过程和函数的信息(表中存储所有的存储过程和函数的定义)

select * frominformation_schema.Routines where routine_name='rsc' androutine_type='function'\G;

*************************** 8.row ***************************

       SPECIFIC_NAME: rsc

     ROUTINE_CATALOG: NULL

      ROUTINE_SCHEMA: test

        ROUTINE_NAME: rsc

        ROUTINE_TYPE: PROCEDURE

      DTD_IDENTIFIER: NULL

        ROUTINE_BODY: SQL

 ROUTINE_DEFINITION: begin

select count(*) into num fromfruits where s_id=sid;

end

       EXTERNAL_NAME: NULL

  EXTERNAL_LANGUAGE: NULL

     PARAMETER_STYLE: SQL

    IS_DETERMINISTIC: NO

     SQL_DATA_ACCESS: CONTAINS SQL

            SQL_PATH: NULL

       SECURITY_TYPE: DEFINER

             CREATED: 2014-09-16 22:14:29

        LAST_ALTERED: 2014-09-16 22:14:29

            SQL_MODE:

     ROUTINE_COMMENT:

             DEFINER: root@localhost

CHARACTER_SET_CLIENT: utf8

COLLATION_CONNECTION:utf8_general_ci

 DATABASE_COLLATION: utf8_general_ci

8 rows in set (0.00 sec)

修改存储过程和函数

alter {procedure|function}sp_name [characteristic...]

characteristic:

       containssql

       nosql

       readssql data

       modifiessql data

       sqlsecurity{definer|invoker}

eg:

mysql> alter function rsc

    -> reads sql data comment 'findname';

Query OK, 0 rows affected (0.00sec)

mysql> show create functionrsc\G;

*************************** 1.row ***************************

            Function: rsc

            sql_mode:

     Create Function: CREATEDEFINER=`root`@`localhost` FUNCTION `rsc`(sid int) RETURNS int(11)

    READS SQL DATA

    COMMENT 'find name'

begin

return(select count(*) fromfruits where s_id=sid);

end

character_set_client: utf8

collation_connection:utf8_general_ci

 Database Collation: utf8_general_ci

1 row in set (0.00 sec)

删除存储过程和函数

DROP{procedure|function} [if exists] sp_name

eg:

mysql> drop procedure rsc;

Query OK, 0 rows affected (0.05sec)

综合实列:

mysql> delimiter //

mysql> create procedureadd_id(out count int)

    -> begin

    -> declare itmp int;

    -> declare cur_id cursor for select idfrom sch;

    -> declare exit handler for not foundclose cur_id;

    -> select count_sch() into count;

    -> set @sum=0;

    -> open cur_id;

    -> repeat

    -> fetch cur_id into itmp;

    -> if itmp<10

    -> then set @sun= @sum+itmp;

    -> end if;

    -> until 0 end repeat;

    -> close cur_id;

    -> end//

Query OK, 0 rows affected (0.00sec)

 

mysql> select @a,@sum//

+------+------+

| @a   | @sum |

+------+------+

| NULL | NULL |

+------+------+

1 row in set (0.01 sec)

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

 

 

 

 

 

 

 

 

 

 

存储:procedure (相当于函数,段码代)

1.修改语句定界符:

mysql>\c //

2.创建存储

mysql> create procedure t1()

    -> begin

    -> set @i=3;

    -> while @i<=100 do

   -> insert into t1(name)values(concat("user",@i));

    -> set @i=@i+1;

    -> end while;

    -> end//

3.查看存储:

mysql> show procedurestatus\G;

mysql> show create proceduret1\G;  查看具体创建时的语句

4.执行存储:

mysql>call t1;

 

查询存储引擎

show engines;

查看当前支持那些存储引擎:

mysql> showengines;

+------------+---------+----------------------------------------------------------------+

| Engine     | Support | Comment                                                       |

+------------+---------+----------------------------------------------------------------+

| MyISAM     | DEFAULT | Default engine as ofMySQL 3.23 with great performance        |

| MEMORY     | YES     | Hash based, stored in memory, useful fortemporary tables      |

| InnoDB     | YES     | Supports 分割线

感谢打赏
江西数库信息技术有限公司
YWSOS.COM 平台代运维解决方案
 评论
 发表评论
姓   名:

Powered by AKCMS