在MySQL的官方说明文档中有这么一段话:

An IN parameter passes a value into a procedure. The procedure might modify the value, but the modification is not visible to the caller when the procedure returns. An OUT parameter passes a value from the procedure back to the caller. Its initial value is NULL within the procedure, and its value is visible to the caller when the procedure returns. An INOUT parameter is initialized by the caller, can be modified by the procedure, and any change made by the procedure is visible to the caller when the procedure returns.

一个IN参数传送一个值的过程。该过程可能会修改该值,但过程返回时调用程序看不到修改。一个OUT参数传送从过程返回给调用者的值。它的初始值 NULL在过程中,当过程返回时,调用者可以看到它的值。一个 INOUT参数是由呼叫者初始化,可以由程序进行修改,并且由所述方法制备的任何变化是可见的呼叫者时,过程返回。

这段话理解起来可能有些困难,下面通过一个简单的实例就可了解这三个参数类型的区别

进入mysql,新建一个过程,变量p1,p2,p3类型分别为IN、INOUT和OUT:

delimiter //
drop procedure myproc//
create procedure myproc(in p1 int,inout p2 int,out p3 int)
begin
select p1,p2,p3;
set p1=10;
set p2=20;
set p3=30;
end
//

cmd运行结果如下

init_process_group参数详解 in process out_存储过程


过程建立完毕,这里使用用//作为分隔符表示代码块结束,过程中打印并设置p1,p2,p3值,接下来调用过程

call myproc(@p1,@p2,@p3)//

init_process_group参数详解 in process out_数据_02


由于首次调用,p1,p2,p3的值均为空,接下来再次调用:

init_process_group参数详解 in process out_MySQL存储过程_03


发现过程中p2的值储存为20,p1,p3均为空值,接着在外部查看p1,p2,p3的值:

select @p1,@p2,@p3//

init_process_group参数详解 in process out_存储过程_04


外部p1的值仍为空,p3的值显示为30,接下来外部修改三个值:

set @p1=70//
set @p2=80//
set @p3=90//

init_process_group参数详解 in process out_存储过程_05


修改后再次查看,发现值已改变:

init_process_group参数详解 in process out_MySQL存储过程_06


但是当我们调用过程时,发现过程内部的值如下:

init_process_group参数详解 in process out_数据_07


p1,和p2的值被外部改变,p3的值还是空,再次调用过程:

init_process_group参数详解 in process out_存储过程_08


查看外部值:

init_process_group参数详解 in process out_存储过程_09


再次调用后p1的值未发生改变,也就是说外部值可以改变内部值,过程中对p1的赋值仅为初始化;p2的值变回20,内部值可以改变外部值;p3内部仍是空值,过程中对p3的值仅外部可见,内部始终为空。

总结如下:

IN 类型修饰的参数在存储过程中修改该参数的值不能被返回,在外部修也可改参数内部的值,仅需要将数据传入存储过程,并不需要返回计算后的该值。只能当做传入参数。

INOUT 类型修饰的参数在调用时可被改变和返回数据可以传入存储过程或经过调用计算后,再传出返回值,传出后的值仍为过程中的初始值,可当做传入转出参数。

OUT类型修饰的参数表示该值可在存储过程内部被改变,并可返回内部不接受外部传入的数据,仅能内部改变值的内容,返回计算之后的值,只能当做转出参数。