数据库编程必杀技:解锁存储过程与函数的秘密数据库编程看似高深莫测,但掌握了存储过程与存储函数,你就能轻松驾驭复杂的业务逻辑,提高效率,甚至让数据库“听你指挥”!这些隐藏在数据库中的“必杀技”不仅能优化性能,还能让代码更优雅、安全性更高。本文将带你揭开存储过程与函数的神秘面纱,从基础到实战,手把手教
数据库编程看似高深莫测,但掌握了存储过程与存储函数,你就能轻松驾驭复杂的业务逻辑,提高效率,甚至让数据库“听你指挥”!这些隐藏在数据库中的“必杀技”不仅能优化性能,还能让代码更优雅、安全性更高。本文将带你揭开存储过程与函数的神秘面纱,从基础到实战,手把手教你解锁它们的秘密,助你在数据库编程的道路上一飞冲天!
本文为你献上一套数据库编程的“必杀技”——存储过程与存储函数的全面解析!存储过程是一组预编译的SQL“武器”,能高效完成特定任务,兼具高性能与安全性;而存储函数则以灵活的返回值,解决精准计算需求。我们将从基本概念入手,深入讲解创建方法、流程控制、游标操作等技巧,并通过MySQL实战案例带你上手。想知道如何用最少的代码实现最大的效率?这里有你想要的所有秘密!
DELIMITER 命令的使用语法格式是:
DELIMITER $$
$$
是用户定义的结束符,通常这个符号可以是一些特殊的符号,例如两个“#”,或两个“¥”等DELIMITER
命令时,应该避免使用反斜杠(“\”)字符,因为它是MySQL的转义字符例子:将 MySQL 结束符修改为两个感叹号“!!”。
mysql> DELIMITER !!
换回默认的分行“;”
mysql> DELIMITER ;
创建存储过程
CREATE PROCEDURE sp_name ([proc_parameter[,...]])
routine_body
"proc_parameter" 的语法格式:
[IN | OUT | INOUT] param_name type
# 参数的取名不要与数据表的列名相同
例子:在数据库 mysql_test 中创建一个存储过程,用于实现给定表 customers 中一个客户 id 号即可修改表 customers 中该客户的性别为一个指定的性别。
➜ mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1850
Server version: 8.0.32 Homebrew
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use mysql_test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> delimiter $$
mysql> create procedure sp_update_sex(in cid int,in csex char(1))
-> begin
-> update customers set cust_sex=csex where cust_id=cid;
-> end $$
Query OK, 0 rows affected (0.03 sec)
mysql>
DECLARE var_name[,...] type [DEFAULT value]
例子:声明一个整形局部变量 cid。
DECLARE cid INT(10);
SET var_name = expr [, var_name = expr] ...
例子:为声明的局部变量 cid 赋予一个整数值 910
SET cid=910;
SELECT col_name [,...] INTO var_name[,...] table_expr
在MySQL中,使用游标的具体步骤如下:
DECLARE cursor_name CURSOR FOR select_statement
OPEN cursor_name
FETCH cursor_name INTO var_name [, var_name] ...
CLOSE cursor_name
例子:在数据库 mysql_test 中创建一个存储过程,用于计算表 customers 中数据行的行数。
首先,在MySQL命令行客户端输入如下 SQL语句创建存储过程 sq_sumofrow:
➜ mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2286
Server version: 8.0.32 Homebrew
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use mysql_test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> delimiter $$
mysql> create procedure sp_sumofrow(OUT ROWS INT)
-> begin
-> declare cid int;
-> declare found boolean default true;
-> declare cur_cid cursor for
-> select cust_id from customers;
-> declare continue handler for not found
-> set found=false;
-> set rows=0;
-> open cur_cid;
-> fetch cur_cid into cid;
-> while found do
-> set rows=rows+1;
-> fetch cur_cid into cid;
-> end while;
-> close cur_cid;
-> end$$
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ROWS INT)
begin
declare cid int;
declare found boolean default true;
declare cur' at line 1
mysql>
mysql> CREATE PROCEDURE sp_sumofrow(OUT ROWS INT)
-> BEGIN
-> DECLARE cid INT;
-> DECLARE FOUND BOOLEAN DEFAULT TRUE;
-> DECLARE cur_cid CURSOR FOR
-> SELECT cust_id FROM customers;
-> DECLARE CONTINUE HANDLER FOR NOT FOUND
-> SET FOUND=FALSE;
-> SET ROWS=0;
-> OPEN cur_cid;
-> FETCH cur_cid INTO cid;
-> WHILE FOUND DO
-> SET ROWS=ROWS+1;
-> FETCH cur_cid INTO cid;
-> END WHILE;
-> CLOSE cur_cid;
-> END$$
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ROWS INT)
BEGIN
DECLARE cid INT;
DECLARE FOUND BOOLEAN DEFAULT TRUE;
DECLARE cur' at line 1
mysql>
mysql> CREATE PROCEDURE sp_sumofrow(OUT `ROWS` INT) BEGIN DECLARE cid INT; DECLARE FOUND BOOLEAN DEFAULT TRUE; DECLARE cur_cid CURSOR FOR SELECT cust_id FROM customers; DECLARE CONTINUE HANDLER FOR NOT FOUND SET FOUND=FALSE; SET `ROWS`=0; OPEN cur_cid; FETCH cur_cid INTO cid; WHILE FOUND DO SET `ROWS`=`ROWS`+1; FETCH cur_cid INTO cid; END WHILE; CLOSE cur_cid; END$$
Query OK, 0 rows affected (0.01 sec)
mysql>
然后,在 MySQL 命令行客户端输入如下 SQL语句对存储过程 sp_sumofrow 进行调用:
mysql> call sp_sumofrow(@rows);
->
->
-> $$
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ;
mysql> select @rows;
+-------+
| @rows |
+-------+
| 4 |
+-------+
1 row in set (0.00 sec)
mysql>
最后,查看调用存储过程 sp_sumofrow后的结果:
mysql> select @rows;
+-------+
| @rows |
+-------+
| 4 |
+-------+
1 row in set (0.00 sec)
mysql>
由此例可以看出:
在使用游标的过程中,需要注意以下几点:
CALL sp_name([parameter[,...]])
CALL sp_name[()]
例子:调用数据库 mysql_test 中的存储过程 sp_update_sex,将客户 id 号位 909 的客户性别修改为男性“M”。
mysql> call sp_update_sex(909,'M');
Query OK, 0 rows affected (0.00 sec)
mysql>
DROP PROCEDURE [IF EXISTS] sp_name
例子:删除数据库 mysql_test 中的存储过程 sp_update_sex。
mysql> DROP PROCEDURE sp_update_sex;
Query OK, 0 rows affected (0.01 sec)
mysql>
存储函数与存储过程的区别:
CREATE FUNCTION sp_name ([func_parameter[,...]])
RETURNS type
routine_body
其中,语法项“func_parameter”的语法格式是:
param_name type
例子:在数据库 mysql_test 中创建一个存储函数,要求该函数能根据给定的客户 id 号返回客户的性别,如果数据库中没有给定的 id 号,则返回“没有该客户”。
➜ mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 659
Server version: 8.0.32 Homebrew
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use mysql_test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> DELIMITER $$
mysql> CREATE FUNCTION fn_search(cid INT)
-> RETURNS CHAR(2)
-> DETERMINISTIC
-> BEGIN
-> DECLARE SEX CHAR(2);
-> SELECT cust_sex INTO SEX FROM customers
-> WHERE cust_id=cid;
-> IF SEX IS NULL THEN
-> RETURN(SELECT '没有该客户');
-> ELSE IF SEX='F' THEN
-> RETURN(SELECT '女');
-> ELSE RETURN(SELECT '男');
-> END IF;
-> END IF;
-> END $$
Query OK, 0 rows affected (0.02 sec)
mysql>
SELECT sp_name ([func_parameter[,...]])
例子:调用数据库 mysql_test 中的存储函数 fn_search。
mysql> delimiter ;
mysql> SELECT fn_search(904);
+----------------+
| fn_search(904) |
+----------------+
| 男 |
+----------------+
1 row in set (0.00 sec)
mysql>
DROP FUNCTION [IF EXISTS] sp_name
例子:删除数据库 mysql_test 中的存储函数 fn_search。
mysql> DROP FUNCTION IF EXISTS fn_search;
Query OK, 0 rows affected (0.00 sec)
mysql>
存储过程与存储函数,堪称数据库编程中的“双剑合璧”。通过本文,你不仅掌握了它们的创建与调用,还学会了用游标、变量等技巧解锁更复杂的操作。存储过程让你批量处理如虎添翼,存储函数让结果返回精准高效。无论是优化性能、减少流量,还是提升安全性,这些“必杀技”都能助你事半功倍。赶快将这些秘密应用到你的项目中,开启数据库编程的新篇章吧!
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!