存储过程是预先编译、命名并存入mysql服务器的sql代码集合,调用时直接执行已编译路径;创建必须改delimiter以避免分号冲突;参数in/out/inout决定数据流向;调用需注意库名、权限及过程存在性。

存储过程到底是什么?一句话说清
存储过程就是一段**预先编译、命名并存进 MySQL 服务器**的 SQL 代码集合,不是临时写的语句,也不是客户端拼出来的字符串——它像一个数据库内置的“可执行函数”,调用时直接走服务端已编译路径,省去每次解析、优化、生成执行计划的开销。
怎么创建?必须改 DELIMITER 吗?
必须改。因为存储过程中大量使用分号 ; 结束每条 SQL,而 MySQL 默认把分号当语句终结符,不改就会在 BEGIN 里就报错中断。
- 标准写法是先执行
DELIMITER $$(或//、##等非分号符号) -
CREATE PROCEDURE定义体内部仍用;分隔语句 - 定义结束再执行
DELIMITER ;恢复默认
漏掉这步,99% 的新手会卡在 ERROR 1064 语法错误,且提示位置极其误导(往往指向 BEGIN 或第一行 SELECT)。
IN / OUT / INOUT 参数怎么选?
参数方向决定数据流向,不是可有可无的修饰:
本文档主要讲述的是mybatis语法和介绍;MyBatis 是一个可以自定义SQL、存储过程和高级映射的持久层框架。MyBatis 摒除了大部分的JDBC代码、手工设置参数和结果集重获。MyBatis 只使用简单的XML 和注解来配置和映射基本数据类型、Map 接口和POJO 到数据库记录。相对Hibernate和Apache OJB等“一站式”ORM解决方案而言,Mybatis 是一种“半自动化”的ORM实现。感兴趣的朋友可
-
IN:只进不出,传值进来供过程内部用(默认类型,可省略写) -
OUT:只出不进,过程内用SELECT ... INTO或SET赋值,调用后通过用户变量(如@total)取结果 -
INOUT:既传入初始值,又允许过程修改后返回,本质是引用传递
典型陷阱:声明了 OUT total INT,却忘了在过程里用 SELECT COUNT(*) INTO total FROM ... 赋值——调用后 @total 仍是 NULL,且不会报错。
调用和查错:为什么 CALL proc_name() 报错找不到?
常见原因有三个:
- 没指定数据库上下文:
CALL不自动绑定当前库,如果过程建在shop_db,而你在test_db下执行,得写全名CALL shop_db.proc_name() - 权限不足:执行者没有
EXECUTE权限,需GRANT EXECUTE ON shop_db.proc_name TO 'user'@'%'; - 过程不存在或被删了:用
SHOW PROCEDURE STATUS LIKE 'proc_name';确认是否存在;注意大小写敏感性(Linux 系统下库名、过程名严格区分大小写)
真正难调试的是逻辑错误——比如 OUT 参数没赋值、IF 条件写反、事务没提交导致外部查不到变更。这些不会报语法错,但结果不符合预期,得靠 SELECT 中间变量或加日志表来定位。









