MySQL 存储过程 经常使用语法
“pr_add” 是个简单的 MySQL 存储过程,这个存储过程有两个 int 类型的输入參数 “a”、“b”,返回这两个參数的和。
(
a int,
b int
)
begin
declare c int;
set a = 0;
end if;
set b = 0;
end if;
return c;- 不能在 MySQL 存储过程中使用。return 仅仅能出如今函数中。
/
end;
二、调用 MySQL 存储过程
call pr_add(10, 20);
运行 MySQL 存储过程,存储过程參数为 MySQL 用户变量。
set @b = 20;
三、MySQL 存储过程特点
创建 MySQL 存储过程的简单语法为:
(
[in|out|inout] 參数 datatype
)
begin
MySQL 语句;
end;
MySQL 存储过程參数假设不显式指定“in”、“out”、“inout”,则默觉得“in”。习惯上,对于是“in” 的參数,我们都不会显式指定。
(
@a int,- 错误
b int - 正确
)
3. MySQL 存储过程的參数不能指定默认值。
(
a int,
b int
)
as - 错误,MySQL 不须要 “as”
begin
mysql statement ...;
end;
5. 假设 MySQL 存储过程中包括多条 MySQL 语句,则须要 begin end keyword。
(
a int,
b int
)
begin
mysql statement 1 ...;
mysql statement 2 ...;
end;
6. MySQL 存储过程中的每条语句的末尾,都要加上分号 “;”
set a = 0;
end if;
end;
7. MySQL 存储过程中的凝视。
这是个
多行 MySQL 凝视。
/
set a = 0;
end if;
end;
8. 不能在 MySQL 存储过程中使用 “return” keyword。
return c;- 不能在 MySQL 存储过程中使用。return 仅仅能出如今函数中。
/
end;
9. 调用 MySQL 存储过程时候,须要在过程名字后面加“()”,即使没有一个參数,也须要“()”
10. 由于 MySQL 存储过程參数没有默认值,所以在调用 MySQL 存储过程时候,不能省略參数。能够用 null 来替代。
须要MySQL 5
2,Hello World
MySQL存储过程之Hello World
- DELIMITER $$
- DROP PROCEDURE IF EXISTS HelloWorld$$
- CREATE PROCEDURE HelloWorld()
- BEGIN
- SELECT "Hello World!";
- END$$
- DELIMITER ;
DELIMITER $$DROP PROCEDURE IF EXISTS HelloWorld$$ CREATE PROCEDURE HelloWorld() BEGINSELECT "Hello World!"; END$$DELIMITER ;
3,变量
使用DECLARE来声明,DEFAULT赋默认值,SET赋值
- DECLARE counter INT DEFAULT 0;
- SET counter = counter+1;
DECLARE counter INT DEFAULT 0; SET counter = counter+1;
4,參数
IN为默认类型,值必须在调用时指定,值不能返回(值传递)
OUT值能够返回(指针传递)
INOUT值必须在调用时指定,值能够返回
- CREATE PROCEDURE test(a INT, OUT b FLOAT, INOUT c INT)
CREATE PROCEDURE test(a INT, OUT b FLOAT, INOUT c INT)
5,条件推断
IF THEN、ELSEIF、ELSE、END IF
- DELIMITER $$
- DROP PROCEDURE IF EXISTS discounted_price$$
- CREATE PROCEDURE discunted_price(normal_price NUMERIC(8, 2), OUT discount_price NUMERIC(8, 2))
- BEGIN
- IF (normal_price > 500) THEN
- SET discount_price = normal_price * .8;
- ELSEIF (normal_price > 100) THEN
- SET discount_price = normal_price * .9;
- ELSE
- SET discount_price = normal_price;
- END IF;
- END$$
- DELIMITER ;
DELIMITER $$DROP PROCEDURE IF EXISTS discounted_price$$ CREATE PROCEDURE discunted_price(normal_price NUMERIC(8, 2), OUT discount_price NUMERIC(8, 2)) BEGINIF (normal_price > 500) THENSET discount_price = normal_price * .8;ELSEIF (normal_price > 100) THENSET discount_price = normal_price * .9;ELSESET discount_price = normal_price;END IF; END$$DELIMITER ;
6,循环
LOOP、END LOOP
- DELIMITER $$
- DROP PROCEDURE IF EXISTS simple_loop$$
- CREATE PROCEDURE simple_loop(OUT counter INT)
- BEGIN
- SET counter = 0;
- my_simple_loop: LOOP
- SET counter = counter+1;
- IF counter = 10 THEN
- LEAVE my_simple_loop;
- END IF;
- END LOOP my_simple_loop;
- END$$
- DELIMITER ;
DELIMITER $$DROP PROCEDURE IF EXISTS simple_loop$$CREATE PROCEDURE simple_loop(OUT counter INT) BEGINSET counter = 0;my_simple_loop: LOOPSET counter = counter+1;IF counter = 10 THENLEAVE my_simple_loop;END IF;END LOOP my_simple_loop; END$$DELIMITER ;
WHILE DO、END WHILE
- DELIMITER $$
- DROP PROCEDURE IF EXISTS simple_while$$
- CREATE PROCEDURE simple_while(OUT counter INT)
- BEGIN
- SET counter = 0;
- WHILE counter != 10 DO
- SET counter = counter+1;
- END WHILE;
- END$$
- DELIMITER ;
DELIMITER $$DROP PROCEDURE IF EXISTS simple_while$$CREATE PROCEDURE simple_while(OUT counter INT) BEGINSET counter = 0;WHILE counter != 10 DOSET counter = counter+1;END WHILE; END$$DELIMITER ;
REPEAT、UNTILL
- DELIMITER $$
- DROP PROCEDURE IF EXISTS simple_repeat$$
- CREATE PROCEDURE simple_repeat(OUT counter INT)
- BEGIN
- SET counter = 0;
- REPEAT
- SET counter = counter+1;
- UNTIL counter = 10 END REPEAT;
- END$$
- DELIMITER ;
DELIMITER $$DROP PROCEDURE IF EXISTS simple_repeat$$CREATE PROCEDURE simple_repeat(OUT counter INT) BEGINSET counter = 0;REPEATSET counter = counter+1;UNTIL counter = 10 END REPEAT; END$$DELIMITER ;
7,异常处理
假设用cursor获取SELECT语句返回的全部结果集时应该定义NOT FOUND error handler来防止存储程序提前终结
假设SQL语句可能返回constraint violation等错误时应该创建一个handler来防止程序终结
8,数据库交互
INTO用于存储单行记录的查询结果
- DECLARE total_sales NUMERIC(8, 2);
- SELECT SUM(sale_value) INTO total_sales FROM sales WHERE customer_id=in_customer_id;
DECLARE total_sales NUMERIC(8, 2); SELECT SUM(sale_value) INTO total_sales FROM sales WHERE customer_id=in_customer_id;
CURSOR用于处理多行记录的查询结果
- DELIMITER $$
- DROP PROCEDURE IF EXITS cursor_example$$
- CREATE PROCEDURE cursor_example()
- READS SQL DATA
- BEGIN
- DECLARE l_employee_id INT;
- DECLARE l_salary NUMERIC(8,2);
- DECLARE l_department_id INT;
- DECLARE done INT DEFAULT 0;
- DECLARE cur1 CURSOR FOR SELECT employee_id, salary, department_id FROM employees;
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
- OPEN cur1;
- emp_loop: LOOP
- FETCH cur1 INTO l_employee_id, l_salary, l_department_id;
- IF done=1 THEN
- LEAVE emp_loop;
- END IF;
- END LOOP emp_loop;
- CLOSE cur1;
- END$$
- DELIMITER ;
DELIMITER $$DROP PROCEDURE IF EXITS cursor_example$$ CREATE PROCEDURE cursor_example()READS SQL DATA BEGINDECLARE l_employee_id INT;DECLARE l_salary NUMERIC(8,2);DECLARE l_department_id INT;DECLARE done INT DEFAULT 0;DECLARE cur1 CURSOR FOR SELECT employee_id, salary, department_id FROM employees;DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;OPEN cur1;emp_loop: LOOPFETCH cur1 INTO l_employee_id, l_salary, l_department_id;IF done=1 THENLEAVE emp_loop;END IF;END LOOP emp_loop;CLOSE cur1; END$$ DELIMITER ;
unbounded SELECT语句用于存储过程返回结果集
- DELIMITER $$
- DROP PROCEDURE IF EXISTS sp_emps_in_dept$$
- CREATE PROCEDURE sp_emps_in_dept(in_employee_id INT)
- BEGIN
- SELECT employee_id, surname, firstname, address1, address2, zipcode, date_of_birth FROM employees WHERE department_id=in_employee_id;
- END$$
- DELIMITER ;
DELIMITER $$ DROP PROCEDURE IF EXISTS sp_emps_in_dept$$ CREATE PROCEDURE sp_emps_in_dept(in_employee_id INT) BEGINSELECT employee_id, surname, firstname, address1, address2, zipcode, date_of_birth FROM employees WHERE department_id=in_employee_id; END$$DELIMITER ;
UPDATE、INSERT、DELETE、CREATE TABLE等非查询语句也能够嵌入存储过程里
- DELIMITER $$
- DROP PROCEDURE IF EXITS sp_update_salary$$
- CREATE PROCEDURE sp_update_salary(in_employee_id INT, in_new_salary NUMERIC(8,2))
- BEGIN
- IF in_new_salary < 5000 OR in_new_salary > 500000 THEN
- SELECT "Illegal salary: salary must be between $5000 and $500, 000";
- ELSE
- UPDATE employees SET salary=in_new_salary WHERE employee_id=in_employee_id;
- END IF:
- END$$
- DELIMITER ;
DELIMITER $$DROP PROCEDURE IF EXITS sp_update_salary$$ CREATE PROCEDURE sp_update_salary(in_employee_id INT, in_new_salary NUMERIC(8,2)) BEGINIF in_new_salary < 5000 OR in_new_salary > 500000 THENSELECT "Illegal salary: salary must be between $5000 and $500, 000";ELSEUPDATE employees SET salary=in_new_salary WHERE employee_id=in_employee_id;END IF: END$$DELIMITER ;
9,使用CALL调用存储程序
- DELIMITER $$
- DROP PROCEDURE IF EXISTS call_example$$
- CREATE PROCEDURE call_example(employee_id INT, employee_type VARCHAR(20))
- NO SQL
- BEGIN
- DECLARE l_bonus_amount NUMERIC(8,2);
- IF employee_type='MANAGER' THEN
- CALL calc_manager_bonus(employee_id, l_bonus_amount);
- ELSE
- CALL calc_minion_bonus(employee_id, l_bonus_amount);
- END IF;
- CALL grant_bonus(employee_id, l_bonus_amount);
- END$$
- DELIMITER ;
DELIMITER $$DROP PROCEDURE IF EXISTS call_example$$ CREATE PROCEDURE call_example(employee_id INT, employee_type VARCHAR(20))NO SQL BEGINDECLARE l_bonus_amount NUMERIC(8,2);IF employee_type='MANAGER' THENCALL calc_manager_bonus(employee_id, l_bonus_amount);ELSECALL calc_minion_bonus(employee_id, l_bonus_amount);END IF;CALL grant_bonus(employee_id, l_bonus_amount); END$$ DELIMITER ;
10,一个复杂的样例
- CREATE PROCEDURE putting_it_all_together(in_department_id INT)
- MODIFIES SQL DATA
- BEGIN
- DECLARE l_employee_id INT;
- DECLARE l_salary NUMERIC(8,2);
- DECLARE l_department_id INT;
- DECLARE l_new_salary NUMERIC(8,2);
- DECLARE done INT DEFAULT 0;
- DECLARE cur1 CURSOR FOR
- SELECT employee_id, salary, department_id
- FROM employees
- WHERE department_id=in_department_id;
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
- CREATE TEMPORARY TABLE IF NOT EXISTS emp_raises
- (employee_id INT, department_id INT, new_salary NUMERIC(8,2));
- OPEN cur1;
- emp_loop: LOOP
- FETCH cur1 INTO l_employee_id, l_salary, l_department_id;
- IF done=1 THEN /* No more rows */
- LEAVE emp_loop;
- END IF;
- CALL new_salary(1_employee_id, l_new_salary); /* Get new salary */
- IF (l_new_salary <> l_salary) THEN /* Salary changed */
- UPDATE employees
- SET salary=l_new_salary
- WHERE employee_id=l_employee_id;
- /* Keep track of changed salaries */
- INSERT INTO emp_raises(employee_id, department_id, new_salary)
- VALUES (l_employee_id, l_department_id, l_new_salary);
- END IF:
- END LOOP emp_loop;
- CLOSE cur1;
- /* Print out the changed salaries */
- SELECT employee_id, department_id, new_salary from emp_raises
- ORDER BY employee_id;
- END;
CREATE PROCEDURE putting_it_all_together(in_department_id INT)MODIFIES SQL DATA BEGINDECLARE l_employee_id INT;DECLARE l_salary NUMERIC(8,2);DECLARE l_department_id INT;DECLARE l_new_salary NUMERIC(8,2);DECLARE done INT DEFAULT 0;DECLARE cur1 CURSOR FORSELECT employee_id, salary, department_idFROM employeesWHERE department_id=in_department_id;DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;CREATE TEMPORARY TABLE IF NOT EXISTS emp_raises(employee_id INT, department_id INT, new_salary NUMERIC(8,2));OPEN cur1;emp_loop: LOOPFETCH cur1 INTO l_employee_id, l_salary, l_department_id;IF done=1 THEN /* No more rows */LEAVE emp_loop;END IF;CALL new_salary(1_employee_id, l_new_salary); /* Get new salary */IF (l_new_salary <> l_salary) THEN /* Salary changed */UPDATE employeesSET salary=l_new_salaryWHERE employee_id=l_employee_id;/* Keep track of changed salaries */INSERT INTO emp_raises(employee_id, department_id, new_salary)VALUES (l_employee_id, l_department_id, l_new_salary);END IF:END LOOP emp_loop;CLOSE cur1;/* Print out the changed salaries */SELECT employee_id, department_id, new_salary from emp_raisesORDER BY employee_id; END;
11,存储方法
存储方法与存储过程的差别
1,存储方法的參数列表仅仅同意IN类型的參数,并且不是必需也不同意指定INkeyword
2,存储方法返回一个单一的值,值的类型在存储方法的头部定义
3,存储方法能够在SQL语句内部调用
4,存储方法不能返回结果集
语法:
- CREATE
- [DEFINER = { user | CURRENT_USER }]
- PROCEDURE sp_name ([proc_parameter[,...]])
- [characteristic ...] routine_body
- CREATE
- [DEFINER = { user | CURRENT_USER }]
- FUNCTION sp_name ([func_parameter[,...]])
- RETURNS type
- [characteristic ...] routine_body
- proc_parameter:
- [ IN | OUT | INOUT ] param_name type
- func_parameter:
- param_name type
- type:
- Any valid MySQL data type
- characteristic:
- LANGUAGE SQL
- | [NOT] DETERMINISTIC
- | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
- | SQL SECURITY { DEFINER | INVOKER }
- | COMMENT 'string'
- routine_body:
- Valid SQL procedure statement
CREATE[DEFINER = { user | CURRENT_USER }]PROCEDURE sp_name ([proc_parameter[,...]])[characteristic ...] routine_bodyCREATE[DEFINER = { user | CURRENT_USER }]FUNCTION sp_name ([func_parameter[,...]])RETURNS type[characteristic ...] routine_bodyproc_parameter:[ IN | OUT | INOUT ] param_name typefunc_parameter:param_name typetype:Any valid MySQL data typecharacteristic:LANGUAGE SQL| [NOT] DETERMINISTIC| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }| SQL SECURITY { DEFINER | INVOKER }| COMMENT 'string'routine_body:Valid SQL procedure statement
各參数说明见CREATE PROCEDURE and CREATE FUNCTION Syntax
样例:
- DELIMITER $$
- DROP FUNCTION IF EXISTS f_discount_price$$
- CREATE FUNCTION f_discount_price
- (normal_price NUMERIC(8,2))
- RETURNS NUMERIC(8,2)
- DETERMINISTIC
- BEGIN
- DECLARE discount_price NUMERIC(8,2);
- IF (normal_price > 500) THEN
- SET discount_price = normal_price * .8;
- ELSEIF (normal_price >100) THEN
- SET discount_price = normal_price * .9;
- ELSE
- SET discount_price = normal_price;
- END IF;
- RETURN(discount_price);
- END$$
- DELIMITER ;
DELIMITER $$DROP FUNCTION IF EXISTS f_discount_price$$ CREATE FUNCTION f_discount_price(normal_price NUMERIC(8,2))RETURNS NUMERIC(8,2)DETERMINISTIC BEGINDECLARE discount_price NUMERIC(8,2);IF (normal_price > 500) THENSET discount_price = normal_price * .8;ELSEIF (normal_price >100) THENSET discount_price = normal_price * .9;ELSESET discount_price = normal_price;END IF;RETURN(discount_price); END$$DELIMITER ;
12,触发器
触发器在INSERT、UPDATE或DELETE等DML语句改动数据库表时触发
触发器的典型应用场景是重要的业务逻辑、提高性能、监控表的改动等
触发器能够在DML语句运行前或后触发
- DELIMITER $$
- DROP TRIGGER sales_trigger$$
- CREATE TRIGGER sales_trigger
- BEFORE INSERT ON sales
- FOR EACH ROW
- BEGIN
- IF NEW.sale_value > 500 THEN
- SET NEW.free_shipping = 'Y';
- ELSE
- SET NEW.free_shipping = 'N';
- END IF;
- IF NEW.sale_value > 1000 THEN
- SET NEW.discount = NEW.sale_value * .15;
- ELSE
- SET NEW.discount = 0;
- END IF;
- END$$
- DELIMITER ;
转自:http://fyb613.blog.163.com/blog/static/325460922010044417672/
MySQL 存储过程 经常使用语法相关推荐
- mysql存储过程语法 if_mysql存储过程语法 if
MySql存储过程 MySQL 存储过程是从 MySQL 5.0 开始增加的新功能.存储过程的优点有一箩筐.不过最主要的还是执行效率和SQL 代码封装.特别是 SQL 代码封装功能,如果没有存储过程, ...
- Mysql 存储过程基本语法
delimiter // 一般情况下MYSQL以:结尾表示确认输入并执行语句,但在存储过程中:不是表示结束,因此可以用该命令将:号改为//表示确认输入并执行. 一.创建存储过程 1.基本语法: cre ...
- Mysql存储过程基本语法
Mysql 存储过程基本语法 转载自这篇文章 delimiter // 一般情况下MYSQL以:结尾表示确认输入并执行语句,但在存储过程中:不是表示结束,因此可以用该命令将:号改为//表示确认输入并执 ...
- MySQL 存储过程的基本用法
http://database.51cto.com/art/201006/203159.htm 我们大家都知道MySQL 存储过程是从 MySQL 5.0 开始逐渐增加新的功能.存储过程在实际应用中也 ...
- mysql存储过程和自定义函数
2019独角兽企业重金招聘Python工程师标准>>> 存储过程简介 SQL语句需要先编辑后执行,而存储过程是一组为了完成特定功能的SQL语句集,经编译后存储过程在数据库中,用户通过 ...
- mysql存储过程select into_mysql存储过程select into
mysql数据库存储过程 存储过程简介 存储过程可以简单理解为一条或者多条sql语句的集合,存储过程用来实现将一组关于表的操作的sql语句当作一个整体来执行,存储过程在实际应用中最主要的特点的事提高执 ...
- 华纳云:PHP如何调用MySQL存储过程
这篇文章主要介绍了PHP如何调用MySQL存储过程的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇PHP如何调用MySQL存储过程文章都会有所收获,下面我们一起来看看吧. ...
- mysql存储过程 limit_mysql存储过程 limit
SQL分页查询代码 SQL Server 关于分页 SQL 的资料许多,有的使用存储过程,有的使用游标.本人不喜欢使用游标,我觉得它耗资.效率低:使用存储过程是个不错的选择,因为存储过程是颠末预编译的 ...
- mysql存储过程call_mysql call 存储过程
PHP调用MYSQL存储过程实例 PHP调用MYSQL存储过程实例 标签: mysql存储phpsqlquerycmd 2010-09-26 11:10 11552人阅读 评论(3) 收藏 举报 实例 ...
最新文章
- 为什么不记录慢速查询?
- eclips mysql jndi_Eclipse +Tomcat配置JNDI数据源
- Objective-C中block的底层原理
- 如何使计算机为您读取文档
- 报表打印问题整体解决方案
- Dart的日期时间操作
- 性能测试工具 wrk 安装与使用
- Android 导入导出excel xls、xlsx
- 如何用计算机tan角度换算,tan角度换算(tan值求角度计算器)
- 安卓实战之登录界面设计
- struts2中表现层的数据展现(bean,list,iterator,format,etc)
- 本周大新闻|苹果首款MR没有主打卖点;Meta认为AI是AR OS的基础
- com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #1 of SELECT list is not in GR
- Python 类的继承和组合
- git本地无法上传到远程的问题解决方法
- Python实现计算圆周率π的值到任意位的方法示例
- 解决华为笔记本安装驱动后浏览器频闪
- Andorid IData95手持设备开发过程
- 更加全面、高效,网易云易盾手游智能反外挂服务7月31日发布
- 高等数学18讲(19版)7.26