1.基本用法

drop PROCEDURE if EXISTS sp1; -- 如果存在sp1存储过程则删除掉

create PROCEDURE sp1() SELECT 1; --创建最简单的存储过程,其中存储过程必须加(),调用的时候也一样。

call sp1();  --调用存储过程

show procedure status; --查看所有的存储过程信息

show create procedure sp1; --查看某个存储过程

*注意:存储过程之间可以调用,不可以删除。

简单创建:

drop PROCEDURE if EXISTS sp1;
create PROCEDURE sp1() SELECT * from emp;  --相当于一般的查询语句。

alter procedure : 修改存储过程仅能修改以下的characteristic。(即修改权限可以,存储内容无法修改)

  1. characteristic
  1. ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...
  1. characteristic:
  1.     { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  1.   | SQL SECURITY { DEFINER | INVOKER }
  1.   | COMMENT 'string'

Alter procedure sp3 READS SQL DATA
SQL SECURITY DEFINER;

SELECT SPECIFIC_NAME,SQL_DATA_ACCESS,
SECURITY_TYPE FROM information_schema.Routines WHERE ROUTINE_NAME='emp';

注意:delimiter 分割符使用,sql命令中因";"为默认的分隔符,也是执行语句,因此无法编写存储过程。这个时候就要重新定义分割符。

mysql> select * from emp;
+--------+----------+----------+---------+
| emp_id | emp_name | emp_type | emp_age |
+--------+----------+----------+---------+
| 1 | 张三 | 临时工 | 20 |
| 2 | 李四 | 正式工 | 40 |
| 3 | 王五 | 合同工 | 25 |
+--------+----------+----------+---------+
3 rows in set

mysql> delimiter //
mysql> select * from emp//
+--------+----------+----------+---------+
| emp_id | emp_name | emp_type | emp_age |
+--------+----------+----------+---------+
| 1 | 张三 | 临时工 | 20 |
| 2 | 李四 | 正式工 | 40 |
| 3 | 王五 | 合同工 | 25 |
+--------+----------+----------+---------+
3 rows in set

mysql>

2.变量

1.局部变量

局部变量被定义在begin和end之间使用,且要放在复杂sql语句的前面,如同一个方法的私有变量一样。

声明:DECLARE p varchar(200);  --不带默认值

DECLARE p varchar(200) DEFAULT '王五'; --带默认值

    mysql文档声明:  DECLARE var_name[,...] type [DEFAULT value]

    也就是可以同时对多个变量进行定义。用“,”号隔开

declare t1,t2,t3 int DEFAULT 2;

赋值:set p = '李四';

mysql文档赋值:SET var_name = expr [, var_name = expr] ...   用“,”号隔开

    set t1=5,t3=6;

    set t1=(select count(*) from emp);

select *** into

    select emp.emp_name into v_name from emp LIMIT 0,1;  --变量赋值仅可获得一个结果,变量名不可和表中的输出列名一样,不然拿不到sql中的值。
    select v_name; --显示结果

使用 select var_name; 可以查看结果。  

  1. drop PROCEDURE if EXISTS sp1;
  2. create PROCEDURE sp1()
  3. BEGIN
  4. declare t1,t2,t3 int DEFAULT 2;
  5. set t1=5,t3=6;
  6. select t2;
  7. select t3;
  8. end;
  9. call sp1();

sp1

注意: declare 不但可以对变量声明,而且还可以声明条件,声明处理(多用于异常控制)。

声明条件:

  1. DECLARE condition_name CONDITION FOR condition_value
    声明处理
    DECLARE....HANDLER..FOR
  1. handler_action:
  2. CONTINUE
  3. | EXIT
  4. | UNDO
  5.  
  6. condition_value:
  7. mysql_error_code
  8. | SQLSTATE [VALUE] sqlstate_value
  9. | condition_name
  10. | SQLWARNING
  11. | NOT FOUND
  12. | SQLEXCEPTION

DECLARE foreign_key_error CONDITION FOR 1216;

DECLARE CONTINUE HANDLER FOR foreign_key_error MySQL_statements;

为1216 error_code 起名字 foreign_key_error, 声明当遇到foreign_key_error 这种状态时,程序继续。

 2.用户变量

  用户变量是当本次客户请求连接开始到请求结束之间。当我们在程序中调用一个存储过程A,A存储过程又调用了B存储过程,在A中定义的用户变量,在B中可以        使用。如同一个类中的私有变量一样。

声明: @

 赋值: set = 赋值,select := 赋值

  1. drop PROCEDURE if exists sp2;
  2. create procedure sp2()
  3. BEGIN
  4. set @v1='';
  5. select @v1:='';
  6. select @v1;
  7. end;
  8. call sp2();

3. 系统变量

     分为:全局变量和 会话变量。

           全局变量影响服务器整体操作。要想更改全局变量,必须具有SUPER权限。

   全局变量通过set方式设置,会在当前已经启动的系统中生效,但是如果系统重启,动态设置的全局变量会丢失。静态设置就是在my.ini/my.cnf文件中配置,然后重启服务。

           会话变量不需要权限可以自己修改。会话变量的生命周期和用户变量一致,都是客户端连接时产生,客户端关闭时关闭。但会话变量属于客户的环境使用状况设置,而用户变            量用于存储过程。

    系统变量不可自定义,只能对现有的进行修改。否则报出 unknown system varitables [v_name].

    如果设置SET变量时不指定GLOBAL、SESSION或者LOCAL,默认使用SESSION。查看时如果不设置,则会SESSION-》GLOBAL。

  1. set session identity = 0; -- 修改会话变量
  2. set @@session.identity = 0; --修改会话变量
  3. set @@identity = 0; --修改会话变量
    set identity =0;
    show session VARIABLES like 'identity'; --查看会话变量
    show session VARIABLES;--查看会话变量
  4.  
  5. select @@identity;--查看会话变量
  1. --LOCAL SESSION 是同义词,表达同样的意思

set local identity = 0;
set @@local.identity = 0;

  1.  

show local VARIABLES like 'identity';
show local VARIABLES;
select @@identity;

  1. set global autocommit = 'ON'; --修改系统服务变量
  2. set @@global.autocommit = 'ON'; --修改系统服务变量
  3.  
  4. show global VARIABLES like 'autocommit'; --查看系统服务变量
  5. show global VARIABLES; --查看修改系统服务变量
  6. select @@autocommit; --查看修改系统服务变量

3. 参数

 参数默认是IN,也就是如果是IN的参数可以不用指定。指定有三种:IN, OUT, 或INOUT,这只对PROCEDURE是合法的,Function仅接收IN,且语句中要加强制返回 Return关键     字。

IN:

create procedure sp3(IN v_name varchar(25)) 或create procedure sp3(v_name varchar(25))      ---默认为IN

  1. drop PROCEDURE if EXISTS sp3;
  2. create PROCEDURE sp3(ov VARCHAR(25))
  3. BEGIN
  4. select * from emp where emp.emp_name = ov;
  5. end;
  6. call sp3('张三');

OUT:

  1. create PROCEDURE sp3(OUT ov VARCHAR(25))
  2. BEGIN
  3. select emp.emp_type into ov from emp where emp.emp_name = '张三';
  4. end;
  5. call sp3(@V);
  6. select @V;

INOUT :

  1. drop PROCEDURE if EXISTS sp3;
  2. create PROCEDURE sp3(INOUT ov VARCHAR(25))
  3. BEGIN
  4. select emp.emp_type into ov from emp where emp.emp_name = ov;
  5. end;
  6. set @v_name = '张三';
  7. call sp3(@v_name);
  8. select @v_name;

---------------------------------------------------------------------------------------------------------------------------------------------------------

4.cursor光标

光标可以对查询进行遍历,判断。

 1. 创建光标

declare cur1 cursor for select emp_name from emp;

2. 打开游标

open cur1;

3. 游标查询

fetch cur1 into [v_name];

4. 关闭游标

close cur1;

注意:   emp_names 一定要赋予初始值'',要不然为null,null和任意字符concat结果都为null;

以下例子:实现group_concat 功能;

  1. drop PROCEDURE if EXISTS sp1;
  2. create PROCEDURE sp1()
  3. BEGIN
  4. DECLARE done INT DEFAULT 0;
  5. DECLARE emp_names,temp VARCHAR(150) DEFAULT '';
  6. DECLARE a varchar(15);
  7. declare cursor1 CURSOR for select emp_name from emp;
  8. DECLARE CONTINUE HANDLER FOR SQLSTATE '' SET done = 1; /*这两个是一个意思*/
  9. DECLARE CONTINUE HANDLER FOR NOT FOUND SET @l_last_sale=1; /*定义循环结束后的状态*/
  10. open cursor1;
  11. REPEAT
  12. FETCH cursor1 into a;
  13. if not done then
  14. set emp_names=CONCAT(a,',',emp_names);
  15. end if;
  16. until done end REPEAT;
  17. close cursor1;
  18. select temp;
  19. select emp_names;
  20. end;
  21. call sp1();

 5. 结构控制

1.IF:  

  1. drop PROCEDURE if EXISTS sp3;
  2. create PROCEDURE sp3(INOUT ov VARCHAR(25))
  3. BEGIN
  4. IF ov = '张' THEN
  5. set ov='张三';
  6. ELSEIF ov='李' THEN
  7. set ov='李四';
  8. ELSE
  9. set ov='王五';
  10. end if;
  11. select * from emp where emp.emp_name = ov;
  12. end;
  13. set @ov='样';
  14. call sp3(@ov);

   2. CASE:

  1. drop PROCEDURE if EXISTS sp3;
  2. create PROCEDURE sp3(INOUT ov VARCHAR(25))
  3. BEGIN
  4. CASE ov
  5. when '张' THEN
  6. set ov='张三';
  7. when '李' THEN
  8. set ov='李四';
  9. ELSE
  10. set ov='王五';
  11. end case;
  12. select * from emp where emp.emp_name = ov;
  13. end;
  14. set @ov='样';
  15. call sp3(@ov);
  1. drop PROCEDURE if EXISTS sp3;
  2. create PROCEDURE sp3(INOUT ov VARCHAR(25))
  3. BEGIN
  4. CASE when ov='张' THEN
  5. set ov='张三';
  6. when ov='李' THEN
  7. set ov='李四';
  8. ELSE
  9. set ov='王五';
  10. end case;
  11. select * from emp where emp.emp_name = ov;
  12. end;
  13. set @ov='样';
  14. call sp3(@ov);

3. Loop

  1. [begin_label:] LOOP
  1.     statement_list
  1. END LOOP [end_label]
  2.  
  3. label1 loop
    end loop label1

LOOP允许某特定语句或语句群的重复执行,实现一个简单的循环构造。在循环内的语句一直重复直循环被退出,退出通常伴随着一个LEAVE 语句。

LOOP语句可以被标注。除非begin_label存在,否则end_label不能被给出,并且如果两者都出现,它们必须是同样的。

4. LEAVE语句 (相当于循环中的break,不同点可以跳出任意及循环,而一般java退出为一层一层退出for循环)

  1. LEAVE label

这个语句被用来退出任何被标注的流程控制构造。它和BEGIN ... END或循环一起被使用。

5. ITERATE语句(相当于循环中的continue,不同点可以继续任意循环)

  1. ITERATE label

ITERATE只可以出现在LOOP, REPEAT, 和WHILE语句内。ITERATE意思为:“再次循环。”

  1. drop PROCEDURE if EXISTS sp3;
  2. create PROCEDURE sp3(IN ov INT,OUT a int, out b int)
  3. BEGIN
  4. set a=0,b=0;
  5. label1:LOOP
  6. set ov= ov + 1;
  7. label2:LOOP
  8. set a=a + 1;
  9. set ov=ov+10;
  10. if ov>30 THEN
  11.  
  12. leave label2;
  13. end IF;
  14. end loop label2;
  15. set b=b + 1;
  16. if ov < 60 THEN
  17. ITERATE label1;
  18. ELSE
  19. leave label1;
  20. end if;
  21. end LOOP label1;
  22. select * from emp;
  23. end;
  24. set @ov=0;
  25. call sp3(@ov, @a, @b);
  26. select @a,@b;

6. REPEAT语句(相当于java中go....while()语句,loop是死循环需要内部打断执行才可以,repeat是只要满足条件就退出

  1. [begin_label:] REPEAT
  1.     statement_list
  1. UNTIL search_condition
  1. END REPEAT [end_label]
  1. drop PROCEDURE if EXISTS sp3;
  2. create PROCEDURE sp3(IN ov INT,OUT a int, out b int)
  3. BEGIN
  4. select @a := 20;
  5. REPEAT
  6. set @a=@a+1;
  7. UNTIL @a>ov
  8. end REPEAT;
  9. select * from emp;
  10. set a = @a;
  11. end;
  12. set @ov=50;
  13. call sp3(@ov, @a, @b);
  14. select @a,@b;

7. WHILE语句(相当于java中的while语句)

  1. [begin_label:] WHILE search_condition DO
  1.     statement_list
  1. END WHILE [end_label]
  1. drop PROCEDURE if EXISTS sp3;
  2. create PROCEDURE sp3(IN ov INT,OUT a int, out b int)
  3. BEGIN
  4. select @a := 20;
  5. WHILE @a<ov DO
  6. set @a=@a+1;
  7. end WHILE;
  8. select * from emp;
  9. set a = @a;
  10. end;
  11. set @ov=30;
  12. call sp3(@ov, @a, @b);
  13. select @a,@b;
存储过程:预编译的sql,减少网络之间的数据传输,复杂sql语句多sql语句的处理。

二. FUNCTION

function的创建使用和procedure一样,就是将名字换成function即可。

1.不同点:

  • function一般作为其它查询语句的一部分而存在。而procedure一般独立执行。
  • function只能参数形式仅可为IN,仅通过return返回单个值,procedure有INOUT ,OUT形式。可返回多个值,且不需要声明return。
  • function是为了解决针对性的某个问题,而存储过程多为了满足查找某项输出数据样式而设立。

创建和删除function

  1. drop function if exists f1;
  2. create function f1(v1 VARCHAR(20)) returns VARCHAR(50)
  3. return CONCAT(v1,'HelloWord','!');
  4. select f1('My first Function ');

查看创建的function:     SHOW CREATE FUNCTION f1;

  1. drop function if exists f2;
  2. create function f2(v1 VARCHAR(20)) returns VARCHAR(50)
  3. BEGIN
  4. if v1='张' THEN
  5. set v1='张三';
  6. ELSEIF v1='李' THEN
  7. set v1='李四';
  8. else
  9. set v1='王五';
  10. end if;
  11. return v1;
  12. END;
  13. select f2('My first Function ');

参考文摘:

MySql 存储过程实例(附完整注释) http://www.cnblogs.com/jukan/p/5815470.html
mysql存储过程语法及实例 http://www.cnblogs.com/cxxjohnson/p/5965194.html

MySQL存储过程中的用户变量,系统变量,局部变量 cla http://blog.csdn.net/qq_29027865/article/details/52623205

Procedure-Function mysql的更多相关文章

  1. MySQL:procedure, function, cursor,handler

    Procedure & Function Procedure 语法: CREATE [DEFINER = { user | CURRENT_USER }] PROCEDURE sp_name ...

  2. 修改Mysql procedure,function and view definer

    1 一次性修改遇到错误 update mysql.proc set definer='root@%'; update mysql.proc set definer='root@%'; ERROR 10 ...

  3. 所有子节点、Procedure、MySQL

    在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点.但很遗憾,在MySQL的目前版本中还没有对应的功能. ...

  4. oracle 备份数据库对象(存储过程PROCEDURE,FUNCTION,VIEW,TRIGGER...)

    开发过程中,需要不停的备份数据库对象, 特别是存储过程, 每次手动备份不免很低能啊 历经几次修改终于, 完美了,O(∩_∩)O哈哈~      (当然,你也可以再改简便一点~~~) select db ...

  5. What is the difference between routine , method , procedure , function ? please explain it with example?

    a method is named and attached to an object. so, for example, a method is like a function but is con ...

  6. 存储过程和函数 PROCEDURE & FUNCTION

    SQL语句执行的时候,要首先编译,然后在被执行.在大型数据库系统中,为了提高效率,将为了完成特定功能的SQL语句集进行编译优化后,存储在数据库服务器中,用户通过指定存储过程的名字来调用执行. 具体而言 ...

  7. MySQL 权限?

    一.权限表 mysql数据库中的3个权限表:user .db. host 权限表的存取过程是: 1)先从user表中的host. user. password这3个字段中判断连接的IP.用户名.密码是 ...

  8. MySQL权限说明

    --MySQL权限说明 ----------------------2014/06/09 一.权限表 mysql数据库中的3个权限表:user .db. host 权限表的存取过程是: 1)先从use ...

  9. MySQL数据库权限分类

    一.权限表 mysql数据库中的3个权限表:user .db. host 权限表的存取过程是: 1)先从user表中的host. user. password这3个字段中判断连接的IP.用户名.密码是 ...

  10. Mysql 用户和权限管理

    用户和权限管理: 语法 grant 权限 on 数据库.数据表 to '用户' @ '主机名'; 例:给 xiaogang 分配所有的权限 grant all on *.* to 'xiaogang' ...

随机推荐

  1. Reaction 开源可自定义实时的电商平台

    Reaction 开源可自定义实时的电商平台,支持以下特性 拖放商品 订单处理 支付 物流 税 折扣 Analytics(分析) 与许多第三方应用程序集成 graphql 开发api 简单demo 使 ...

  2. sqlserver 2008 r2 下载地址和序列号,可用迅雷下载

    sqlserver 2008 r2 下载地址,可用迅雷下载 下载sqlserver 2008 r2 ,微软用了一个下载器,经过从下载器上,将他的地址全部用键盘敲了下来.最终的简体中文版地址如下: 32 ...

  3. FastAdmin 开发时对数据库进行版本管理 (非 think-migration)

    因为开必项目,暂时还不没用 think-migration,先用 脚本处理. 在导出 SQL 时将相关字段数据还原,比如 admin logitime updatetime token. 把 admi ...

  4. python 之 python3内置函数

    一. 简介 python内置了一系列的常用函数,以便于我们使用,python英文官方文档详细说明:点击查看, 为了方便查看,将内置函数的总结记录下来. 二. 使用说明 以下是Python3版本所有的内 ...

  5. JavaScript中类似PHP的uniqid()方法

    JavaScript中类似PHP的uniqid()方法: function generateUIDNotMoreThan1million() { return ("0000" + ...

  6. FineUI与百度地图简单示例 (转帖)

    http://www.fineui.com/bbs/forum.php?mod=viewthread&tid=4191&extra=page%3D1 前台代码 <%@ Page ...

  7. ToString yyyy-MM-dd ,MM 小写的故事。

    ToString MM 小写,有可能时间转为 :2013-49-02,放到数据库中查询,就报错.

  8. java实验四——测试梯形类

    package hello; public class TestTixing { public static void main(String[] args) { // TODO Auto-gener ...

  9. Class.forName和ClassLoader.loadClass的比较【转载】

    Class的装载分了三个阶段,loading,linking和initializing,分别定义在The Java Language Specification的12.2,12.3和12.4.Clas ...

  10. [UE4]蒙太奇动画运行时不播放,预览是好的

    动画实例里面没有添加“DefaultSlot”就会出现这样的问题