存储过程详解:把SQL逻辑“打包”存起来,下次一键调用!|转行学DB第12天
不用每次都重复写复杂操作数据库也能“写脚本”大家好呀我是数据库小学妹前几篇我们学会了视图可以把复杂的查询存成虚拟表。但如果我们遇到这种情况如何解决如果我想执行一连串的操作比如先更新A表再插入B表再删除C表每次都要写好几条SQL。有没有办法把这一整套动作“打包”存起来下次直接调用当然有今天我就把自己学会的存储过程分享出来——它就像给数据库写“脚本”把一堆SQL语句封装成一个整体以后一句命令就能执行全部。一、什么是存储过程数据库里的“脚本文件”存储过程是一段预先编译好并存储在数据库中的SQL代码。你可以给它起个名字然后像调用函数一样执行它。 类比你在设计软件里录了一个“动作”宏一键完成多步操作。存储过程就是数据库的“宏”。为什么需要它复用性写一次调用无数次减少网络传输只需要发一条CALL命令而不是几十行SQL逻辑封装把复杂的业务逻辑藏在存储过程里应用层调用更简单二、什么是存储过程基本语法DELIMITER//CREATEPROCEDURE过程名()BEGIN-- 这里写SQL语句SELECTHello, Database!;END//DELIMITER;DELIMITER //是改变MySQL的语句结束符因为过程体里可能有分号执行完再改回;BEGIN...END之间放你要执行的SQL调用存储过程CALL过程名();实战无参存储过程示例创建一个向日志表插入当前时间的存储过程DELIMITER//CREATEPROCEDUREInsertLog()BEGININSERTINTOlogs(message,created_at)VALUES(存储过程被执行了,NOW());END//DELIMITER;调用CALLInsertLog();每次调用logs表里就会多一行记录。三、存储过程的参数类型参数可以让存储过程处理不同的数据。参数有三种类型示例1IN参数——根据用户ID查询姓名DELIMITER//CREATEPROCEDUREGetUserName(INuser_idINT)BEGINSELECTnameFROMusersWHEREiduser_id;END//DELIMITER;调用CALLGetUserName(1);示例2OUT参数——统计用户数量并返回DELIMITER//CREATEPROCEDUREGetUserCount(OUTtotalINT)BEGINSELECTCOUNT(*)INTOtotalFROMusers;END//DELIMITER;调用CALLGetUserCount(count);SELECTcount;-- 查看输出参数的值示例3INOUT参数——对传入值做运算DELIMITER//CREATEPROCEDUREDoubleNumber(INOUTnumINT)BEGINSETnumnum*2;END//DELIMITER;调用SETa5;CALLDoubleNumber(a);SELECTa;-- 结果是 10四、存储过程的控制结构在存储过程内部可以定义变量、使用条件判断和循环语句。定义变量DECLARE变量名 数据类型[DEFAULT默认值];IF-ELSE判断示例根据分数返回等级DELIMITER//CREATEPROCEDUREGetGrade(INscoreINT,OUTgradeVARCHAR(10))BEGINIFscore90THENSETgrade优秀;ELSEIFscore60THENSETgrade及格;ELSESETgrade不及格;ENDIF;END//DELIMITER;调用CALLGetGrade(85,g);SELECTg;-- 及格CASE语句多个条件时更清晰比IF更适合多个固定值的匹配DELIMITER//CREATEPROCEDUREGetWeekName(INday_numINT,OUTweek_nameVARCHAR(10))BEGINCASEday_numWHEN1THENSETweek_name星期一;WHEN2THENSETweek_name星期二;WHEN3THENSETweek_name星期三;WHEN4THENSETweek_name星期四;WHEN5THENSETweek_name星期五;WHEN6THENSETweek_name星期六;WHEN7THENSETweek_name星期日;ELSESETweek_name无效数字;ENDCASE;END//DELIMITER;WHILE循环先判断后执行批量插入数据1到nDELIMITER//CREATEPROCEDUREBatchInsert(INnINT)BEGINDECLAREiINTDEFAULT1;WHILEinDOINSERTINTOtest_table(value)VALUES(i);SETii1;ENDWHILE;END//DELIMITER;LOOP循环需配合 LEAVE 退出DELIMITER//CREATEPROCEDURELoopExample(INnINT)BEGINDECLAREiINTDEFAULT1;loop_label:LOOPIFinTHENLEAVEloop_label;-- 退出循环ENDIF;INSERTINTOtest_table(value)VALUES(i);SETii1;ENDLOOP;END//DELIMITER;什么时候用哪种简单条件分支 →IF多个固定值匹配 →CASE已知循环次数 →WHILE需要灵活控制如无限循环条件跳出 →LOOP注意循环在数据量大时性能很差实战中尽量避免。这里仅做语法演示。五、查看和删除存储过程查看所有存储过程SHOWPROCEDURESTATUSWHEREDb你的数据库名;查看存储过程的创建语句SHOWCREATEPROCEDURE过程名;删除存储过程DROPPROCEDUREIFEXISTS过程名;六、新手避坑指南血泪总结七、存储过程与视图的区别简单总结只是查数据→视图需要返回单个计算结果→函数需要执行一系列操作包括更新→存储过程八、今日学习心得今天的内容总结成三句话存储过程就是数据库里的“函数”封装复杂逻辑一次编写多次调用什么时候用复杂业务逻辑、批量数据处理、提高性能关键命令CREATE PROCEDURE→CALL→DROP PROCEDURE 我是数据库小学妹一个用设计师思维学数据库的转行人我们一起把复杂的技术变得简单有趣**—本文为个人学习总结所有命令均在MySQL 8.0环境下验证。存储过程是进阶技能先掌握基础语法再考虑实际应用。