[关闭]
@a5635268 2017-01-19T14:54:25.000000Z 字数 3774 阅读 1244

【mysql的编程专题④】存储过程

Mysql


类似函数,但是没有返回值,把sql进行封装,便于多次使用或多种应用程序共享使用.不能用在SQL语句中,只能使用CALL调用;

创建存储过程

语法

  1. CREATE PROCEDURE sp_name ([proc_parameter[,...]])
  2. [characteristic ...] routine_body

sp_name是存储过程的名称;proc_parameter表示存储过程的参数列表; characteristic指定存储过程的特性;routine_body参数是SQL代码的内容,多条sql以;隔开,可以用BEGIN…END来标志SQL代码的开始和结束。

参数

proc_parameter中的每个参数由3部分组成。这3部分分别是输入输出类型、参数名称和参数类型。

  1. [ IN | OUT | INOUT ] param_name type
  2. ```
  3. > IN表示输入参数(可以看做声明参数为函数的局部变量,内部做改变外部不被影响);OUT表示输出参数(调用结束后外部可以访问到这个变量,内部能改变外部的变量); INOUT表示既可以是输入,也可以是输出;
  4. ```sql
  5. CREATE PROCEDURE pr_param_in(in id int)
  6. BEGIN
  7. IF id is not null THEN
  8. set id = id + 1;
  9. END IF;
  10. SELECT id as id_inner;
  11. END //
  12. mysql> call pr_param_in(10); -- 如果存储过程的输出类型为in的话,不会报错;
  13. +----------+
  14. | id_inner |
  15. +----------+
  16. | 11 |
  17. +----------+
  18. mysql> call pr_param_in(@id);
  19. +----------+
  20. | id_inner |
  21. +----------+
  22. | 101 |
  23. +----------+
  24. 1 row in set
  25. Query OK, 0 rows affected
  26. mysql> select @id as id_out; -- in是不会影响外部的变量的;
  27. +--------+
  28. | id_out |
  29. +--------+
  30. | 100 |
  31. +--------+
  32. 1 row in set
  33. CREATE PROCEDURE pr_param_out (OUT id INT)
  34. BEGIN
  35. SELECT id AS id_inner_1; -- 如果参数的输出类型为out的话,那外面的int必须是一个变量,并且无论传什么参数进来都为null
  36. IF id IS NOT NULL THEN
  37. SET id = id + 1;
  38. SELECT id AS id_inner_2;
  39. ELSE
  40. SELECT 1 INTO id;
  41. END IF;
  42. SELECT id as id_inner_3;
  43. END //
  44. call pr_param_out(10); -- 1411错误:子程序%sOUTINOUT参量不是变量。
  45. 1414 - OUT or INOUT argument 1 for routine test.pr_param_out is not a variable or NEW pseudo-variable in BEFORE trigger
  46. mysql> set @var = 10;
  47. Query OK, 0 rows affected
  48. mysql> call pr_param_out(@var);
  49. +------------+
  50. | id_inner_1 |
  51. +------------+
  52. | NULL |
  53. +------------+
  54. 1 row in set
  55. +------------+
  56. | id_inner_3 |
  57. +------------+
  58. | 1 |
  59. +------------+
  60. 1 row in set
  61. mysql> select @var as id_out; -- 如果参数的输出类型为out的话,传入什么值都会变为NULL,然后在内部都会改变外部变量的值;
  62. +--------+
  63. | id_out |
  64. +--------+
  65. | 1 |
  66. +--------+
  67. 1 row in set
  68. CREATE PROCEDURE pr_param_inout (INOUT id INT)
  69. BEGIN
  70. SELECT id AS id_inner_1; -- 如果参数的输出类型为inout的话,那外面的int必须是一个变量。外面传的变量是能够进来的;
  71. IF id IS NOT NULL THEN
  72. SET id = id + 1;
  73. SELECT id AS id_inner_2;
  74. ELSE
  75. SELECT 1 INTO id;
  76. END IF;
  77. SELECT id as id_inner_3;
  78. END //
  79. mysql> set @var = 100;
  80. mysql> call pr_param_inout(@var);
  81. +------------+
  82. | id_inner_1 |
  83. +------------+
  84. | 100 |
  85. +------------+
  86. 1 row in set
  87. +------------+
  88. | id_inner_2 |
  89. +------------+
  90. | 101 |
  91. +------------+
  92. 1 row in set
  93. +------------+
  94. | id_inner_3 |
  95. +------------+
  96. | 101 |
  97. +------------+
  98. 1 row in set
  99. mysql> select @var; -- 能够被改变;
  100. +------+
  101. | @var |
  102. +------+
  103. | 101 |
  104. +------+
  105. <div class="md-section-divider"></div>
  1. DELIMITER //
  2. CREATE PROCEDURE p1() SELECT * FROM t;// -- 如果只有一句sql的话,可以不用写begin和end;
  3. <div class="md-section-divider"></div>

存储过程的特性

characteristic参数有多个取值。其取值说明如下:

技巧:创建存储过程时,系统默认指定CONTAINS SQL,表示存储过程中使用了SQL语句。但是,如果存储过程中没有使用SQL语句,最好设置为NO SQL。而且,存储过程中最好在COMMENT部分对存储过程进行简单的注释,以便以后在阅读存储过程的代码时更加方便。

Example1

  1. CREATE PROCEDURE num_from_employee (IN emp_id INT, OUT count_num INT )
  2. READS SQL DATA
  3. COMMENT 'this is a test_pro'
  4. BEGIN
  5. SELECT COUNT(*) INTO count_num
  6. FROM employee
  7. WHERE d_id=emp_id ;
  8. END
  9. <div class="md-section-divider"></div>

上述代码中,存储过程名称为num_from_employee;输入变量为emp_id;输出变量为count_num。SELECT语句从employee表查询d_id值等于emp_id的记录,并用COUNT(*)计算d_id值相同的记录的条数,最后将计算结果存入count_num中,comment为注释;

更多的例子请看流程控制

查看存储过程

  1. SHOW PROCEDURE STATUS\G
  2. *************************** 1. row ***************************
  3. Db: test
  4. Name: p1
  5. Type: PROCEDURE
  6. Definer: root@localhost
  7. Modified: 2015-05-01 09:49:20
  8. Created: 2015-05-01 09:49:20
  9. Security_type: DEFINER
  10. Comment:
  11. character_set_client: utf8
  12. collation_connection: utf8_general_ci
  13. Database Collation: latin1_swedish_ci
  14. <div class="md-section-divider"></div>

删除存储过程

  1. mysql> drop procedure p1; -- p1 存储过程的名称
  2. Query OK, 0 rows affected
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注