每天分享技术栈,开发工具等
存储过程小白系列,专注讲一个知识点,配实战示例,通俗易懂,手把手教你写!
小伙伴们,有没有遇到过这样的尴尬?
你写了个存储过程,里面写死了某些值,比如欢迎语里写死“张三”, 结果一旦要换“李四”,你就得改过程代码,反复跑修改、部署,好麻烦!
现实生活中,咱们写程序都是要通用的,不能每次改名字都重写代码啊! 这时候,存储过程的参数就派上大用场了——参数就是给存储过程传值的“输入口”,让它“灵活”起来。
testdb
参数类型 | 作用 | 传递方向 | 特点说明 |
---|---|---|---|
IN | 输入参数,给存储过程传入值 | 调用时传入,过程内只读 | 过程内不能修改传入值(改变不影响调用者) |
OUT | 输出参数,存储过程把值返回给调用者 | 过程内写,调用后拿结果 | 调用时不传值,过程内部给它赋值,调用后取出值 |
INOUT | 输入输出参数,既传入又返回结果 | 调用时传入,过程内读写 | 过程内可以读取初始值并修改,调用结束后返回新值 |
传入一个名字,过程返回一句欢迎语。
DELIMITER//
CREATEPROCEDURE welcome_in(IN user_name VARCHAR())
BEGIN
-- 使用传入的 user_name 拼接欢迎语,输出一条查询结果
SELECT CONCAT('欢迎你,', user_name,',关注 IT咸鱼!')AS welcome_msg;
END;
//
DELIMITER;
IN user_name VARCHAR(50)
:定义了一个输入参数 user_name
,类型是字符串,最长50字符。调用时需要传入值。CONCAT
是 MySQL 字符串连接函数,把 '欢迎你,' + user_name + ',关注 IT咸鱼!' 拼成一句话。SELECT
查询结果返回给客户端。
CALL welcome_in('小明');
结果应该是:
+---------------------------+
| welcome_msg |
+---------------------------+
| 欢迎你,小明,关注 IT咸鱼!|
+---------------------------+
创建一个过程,内部写死一条欢迎语,返回给调用者。
DELIMITER//
CREATEPROCEDURE welcome_out(OUT msg VARCHAR())
BEGIN
-- 把固定字符串赋值给 OUT 参数 msg
SET msg ='欢迎关注 IT咸鱼,和咸鱼一起成长!';
END;
//
DELIMITER;
OUT msg VARCHAR(100)
:定义了一个输出参数 msg
,过程内部给它赋值。SET msg = '...'
是给参数赋值的标准写法。
-- 定义一个变量用来接收输出参数
SET@msg='';
-- 调用存储过程,将输出参数赋值给变量
CALL welcome_out(@msg);
-- 查看变量值
SELECT @msg;
结果:
+----------------------------------------+
| @msg |
+----------------------------------------+
| 欢迎关注 IT咸鱼,和咸鱼一起成长! |
+----------------------------------------+
给传入的名字加点修饰,比如叫“小明”,过程把名字改成“尊敬的小明”,并返回。
DELIMITER//
CREATEPROCEDURE welcome_inout(INOUT user_name VARCHAR())
BEGIN
-- 修改传入的参数值
SET user_name = CONCAT('尊敬的', user_name);
END;
//
DELIMITER;
INOUT user_name
参数既传入,也传出,调用时传入初始值,执行后变量变更。
-- 定义变量,给它赋初值
SET@user_name='小明';
-- 调用存储过程,传入变量,过程内修改变量值
CALL welcome_inout(@user_name);
-- 查看变量的新值
SELECT@user_name;
结果:
+------------+
| @user_name |
+------------+
| 尊敬的小明 |
+------------+
存储过程内部语句多有分号,MySQL客户端默认用分号结束语句,必须改成别的符号(//)让它识别完整过程。
mysql.proc
表中(用户一般不直接操作它)。CALL
命令,DataGrip 是客户端,连接到 MySQL 服务器后发命令。CALL
调用,不能直接看代码,除非用 SHOW CREATE PROCEDURE
。现在写一个存储过程,传入用户名和年龄,过程判断年龄是否满18岁,然后:
DELIMITER//
CREATEPROCEDURE check_age(
IN user_name VARCHAR(),
IN user_age INT,
OUT message VARCHAR()
)
BEGIN
IF user_age >=THEN
SET message = CONCAT(user_name,',你已经成年了,欢迎关注 IT咸鱼!');
ELSE
SET message = CONCAT(user_name,',你未成年,注意保护自己!');
END IF;
END;
//
DELIMITER;
-- 定义输出变量
SET@msg='';
-- 调用存储过程,传入参数和输出参数
CALL check_age('小红',,@msg);
-- 查看结果
SELECT@msg;
输出:
+------------------------------+
| @msg |
+------------------------------+
| 小红,你已经成年了,欢迎关注 IT咸鱼! |
+------------------------------+
SET@msg='';
CALL check_age('小强',,@msg);
SELECT@msg;
输出:
+----------------------------+
| @msg |
+----------------------------+
| 小强,你未成年,注意保护自己! |
+----------------------------+
传入过程的值,过程只读,不改变调用者变量
如果你执行过程中有任何不懂,截图发给我,咱们一起来排查。 关注“IT咸鱼”,不要错过后续更硬核的MySQL存储过程系列!