MySQL中IN为默认类型无需声明,OUT必须显式写出且须在IN之后;PostgreSQL用INOUT替代,需显式赋值;SQL Server的OUTPUT参数定义和调用均需标记,且NULL分支易致结果为空。

MySQL里IN和OUT参数怎么写才不报错
MySQL存储过程中,IN是默认类型,不用显式声明;但OUT必须明确写出,漏掉就会报ERROR 1064语法错误。声明顺序也重要:所有IN参数必须在OUT之前,否则解析失败。
常见错误现象:CREATE PROCEDURE p1(a INT, b OUT INT)... 直接报错——OUT不能出现在IN后面;正确写法是(a IN INT, b OUT INT),或者更稳妥地全写清楚:(a IN INT, b OUT INT, c INOUT INT)。
-
IN参数可直接当变量用,比如WHERE id = a -
OUT参数只能被赋值,不能参与计算或作为查询条件(如SELECT ... INTO b) - 调用时,
OUT参数必须传变量名(如@result),不能传字面量(CALL p1(5, 10)会报错)
PostgreSQL中INOUT比MySQL更常用,但语义不同
PostgreSQL没有独立的IN和OUT关键字,统一用INOUT,且参数默认就是INOUT——这容易让人误以为“传进去就能改回来”,其实不是:只有显式赋值给该参数名,调用方才能拿到新值。
使用场景:适合封装简单转换逻辑,比如把字符串转大写并返回长度:CREATE FUNCTION upper_and_len(INOUT s TEXT) AS $$ BEGIN s := UPPER(s); RETURN; END; $$ LANGUAGE plpgsql;。注意这里RETURN不是返回值,而是结束函数;真正返回靠的是s被重新赋值。
- PostgreSQL中
INOUT参数在函数体里必须显式赋值,否则调用后仍是NULL - 不能像MySQL那样用
SELECT ... INTO来填充OUT变量;PG里得用SELECT ... INTO variable或直接:= - 兼容性影响:从MySQL迁移到PG时,原
OUT逻辑要重写为INOUT+ 显式赋值,否则结果为空
SQL Server的@param必须带OUTPUT标记,且调用时也要加
SQL Server里参数全是@开头,IN不用标,OUT必须写OUTPUT两次:定义时一次,EXEC调用时再写一次。漏掉任意一个,参数就收不到值,还不会报错——这是最危险的坑。
示例:CREATE PROC p2 @x INT, @y INT OUTPUT AS BEGIN SET @y = @x * 2 END;调用必须写EXEC p2 5, @out OUTPUT。如果写成EXEC p2 5, @out(少OUTPUT),@out保持原值不变,调试时极难发现。
- SQL Server不支持
INOUT,只有IN和OUTPUT两种 -
OUTPUT参数不能是表达式,比如EXEC p2 5, (@a + @b) OUTPUT非法 - 性能上无差异,但参数多时建议用表值参数替代大量
OUTPUT,避免网络往返开销
跨数据库移植时最容易忽略的返回时机问题
MySQL的OUT参数在END前赋值即可;PostgreSQL的INOUT必须在RETURN前完成赋值;SQL Server的OUTPUT只要在RETURN前任意位置设值都行——但如果你在IF分支里只给部分路径赋值,其他路径没覆盖,结果就是NULL,而错误日志里完全没提示。
比如SQL Server里写:IF @x > 0 SET @y = 10 ELSE SELECT @y = 20,看着没问题,但如果@x是NULL,@y就还是NULL。这种空值传播很难追踪,尤其当OUTPUT参数又被下游当IN传给另一个存储过程时。
- 所有数据库都要求
OUT/OUTPUT/INOUT参数在过程退出前有确定值,不能依赖默认初始化 - MySQL和PG允许在
DECLARE里给OUT变量设初值,SQL Server不行 - 测试时别只测主路径,
NULL输入、边界条件、异常分支都要覆盖到










