MySQL中不同类型参数存储过程示例

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: MySQL中不同类型参数存储过程示例

【1】前言变量


① 创建存储过程声明局部变量时不加 @(如DECLARE id int unsigned DEFAULT 20 (非用户变量));


② 但是无论从Mysql客户端下或者Navicat for MySQL ,使用用户变量参数(用户变量)要加 @ 符号如call proc1(@x);。


③ 调用存储过程使用call procedure(param);

navicat for mysql 工具下调用:

call proc1('tom');-- 只有一个in型参数,传值进入
call proc2('tom',@result);--result为out(inout)型参数
select @result;-- 查看返回结果
# 如果@result提前赋值,将会被清空后再传入存储过程内部。

④ 存储过程内部查看变量值(navicat 或dos下);

select @param(用户变量);

select param(局部变量);

用户变量作用域范围为全局,局部变量只在过程内容可用。

需要说明的是,在触发器或者函数中,不能使用select 形式查看变量值,会提示Not allowed to return a result set from a function[trigger]


⑤ 如果变量未提前赋值,那么默认值为null ,存储过程支持随时随地select查看变量值(这点函数和触发器不具备)。⑥ 如果存储过程中使用@类型变量,表明其使用用户变量,那么调用存储过程时需要为用户变量赋值,默认为null。如果用户变量作为out或者inout型参数,值将会发生改变。

存储过程中使用用户变量(不建议):

create procedure proc_test(out s int(11))
BEGIN 
  SELECT COUNT(*) INTO s FROM c_user; 
  set @c= s+1;
  IF @c >13 THEN
    select s,@c, @c+10;
  END if;
 END

更建议如下方式采用局部变量:

create procedure proc_test(out s int(11))
BEGIN 
  declare c int default 0;
  -- 在此统一声明需要用到的参数;
  SELECT COUNT(*) INTO s FROM c_user; 
  set c= s+1;
  IF c >13 THEN
    select s,c, c+10;
  END if;
 END

测试如下图:


⑧ 调用存储过程和函数方式不同

select function_name();-- 调用函数
call procedure_name();-- 调用存储过程

需要额外注意的是,在编写存储过程创建语句的时候,记得要修改MySQL语句控制符 ; 为其他,并在末尾进行恢复,实例如下。

DELIMITER  $
create procedure proc_test(out s int(11))
BEGIN 
  declare c int default 0;
  -- 在此统一声明需要用到的参数;
  SELECT COUNT(*) INTO s FROM c_user; 
  set c= s+1;
  IF c >13 THEN
    select s,c, c+10;
  END if;
 END
$
DELIMITER ;   

【2】不同情况实例

① 无参数

CREATE DEFINER=`root`@`localhost` PROCEDURE `indentity`()
BEGIN
  #Routine body goes here...
  SELECT COUNT(*)+1 as count FROM c_user;
END

result as follows :


② in 型参数

  • in型参数不会改变传入的变量值 ;
CREATE DEFINER=`root`@`localhost` PROCEDURE `IDENTITY`(in id INT)
BEGIN
select id; 
-- 这里将传进来的参数先进行了查询,前提是参数必须已经赋值(默认为null)
SELECT COUNT(*)+1 FROM c_user  INTO id ;
select id;
END
  • test code :
set @id = 0; -- -- 参数已经赋值(默认为null)
CALL IDENTITY(@id);
select @id;
  • result as follows :


如图所示,虽然存储过程中的 id值改变了。但并不影响变量 @id 的值。

如果在存储过程内部改变了@id值,如下:

set @id :=100;

那么,无论在存储过程内部还是外部查看该变量值,都将改变:

select @id;
-- 结果100。

③ in 型参数和变量的使用

  • 数据从外部传入内部使用(值传递),可以是数值也可以是变量
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc3`(in param1 INTEGER)
begin 
DECLARE id int unsigned DEFAULT 20;
--如果id不声明,下面使用的时候将提示未知系统变量。
IF param1=10 THEN
set id = param1;
ELSE
set id=id+1;
SELECT id;
end if;
end
  • test code :

【注意】:

sql创建的时候变量不加 @ ;但是无论从Mysql客户端下或者Navicat for MySQL ,使用的时候参数(变量)要加 @ 符号。

SET @param1 = 11;
call proc3(@param1);
select @param1;
  • result as follows :

如图所示,传入的参数 != 10,则id将在默认值下[20] +1=21 ;

④ out 型参数

  • 只允许过程内部使用(不用外部数据),给外部使用(引用传递:外部的数据会先被清空才会进入内部);
  • 只能是变量(navicat或dos下调用存储过程,如果mybatis中调用存储过程,赋值不起作用)。
  • out型参数会在存储过程结束后,将对应的局部变量值重新返回给传入的用户变量。
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc1`(OUT s int)
BEGIN 
  select s;-- 会先清空传入的变量值,此时显示为null
  SELECT COUNT(*) INTO s FROM c_user; 
  set s = s+1;
  select s;-- 将此值重新赋值给@id;
 END
  • result as follows :


  • test code:
set @id = 0;
CALL proc1(@id);
select @id;

如图所示,out 型参数会改变 传入的参数值( @id )。

即使在存储过程中重新给@id赋值,如下:

set @id := 100;

那么存储过程结束后,查看@id :

select @id;
--结果 : 14

⑤ 同时拥有 in 和 out 型参数

CREATE DEFINER=`root`@`localhost` PROCEDURE `get_user_count`(in sex_id INT,OUT user_count INT)
BEGIN
    IF sex_id = 0 THEN
    SELECT COUNT(*) FROM p_user WHERE p_user.sex="女" into user_count;
    ELSE
    SELECT COUNT(*) FROM p_user WHERE p_user.sex="男" INTO user_count;
    END IF;
END
  • result as follows :


⑥ inout 型参数

  • 只能是变量;
  • 传入内部时值保留只用;
  • 存储过程结束后将对应局部变量值重新返回给传入的用户变量;
CREATE DEFINER=`root`@`localhost` PROCEDURE `pinout`(INOUT `pinout` int)
BEGIN
  #Routine body goes here...
  IF pinout = 0 THEN
  SELECT COUNT(*) FROM c_user  into pinout;
  ELSE
  set pinout = pinout+1;
  END IF;
END
  • result as follows :

如图所示,inout 型参数会改变传入的参数(@pinoutt)值。


【Tips:】

当在DOS或者navicat下测试存储过程时,可直接传入参数进行测试:


  • 存储过程定义
PROCEDURE `proc_1`(IN `v_1` varchar(30),IN `v_2` bigint,OUT `o_result` int(4))
  • test
call proc_name('tom',1001,@result);
select @result; -- 查看out型参数最终值


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
3月前
|
存储 缓存 监控
MySQL服务器配置优化:my.cnf参数调优指南
本文深入解析了MySQL核心配置参数及性能优化技巧,涵盖内存结构、调优原则、存储引擎优化、查询性能优化等内容,通过实战案例帮助读者构建高性能MySQL服务器配置,解决常见的性能瓶颈问题。
|
10月前
|
存储 Java 关系型数据库
java调用mysql存储过程
在 Java 中调用 MySQL 存储过程主要借助 JDBC(Java Database Connectivity)。其核心原理是通过 JDBC 与 MySQL 建立连接,调用存储过程并处理结果。具体步骤包括:加载 JDBC 驱动、建立数据库连接、创建 CallableStatement 对象、设置存储过程参数并执行调用。此过程实现了 Java 程序与 MySQL 数据库的高效交互。
|
9月前
|
存储 SQL 关系型数据库
【YashanDB知识库】MySQL迁移至崖山char类型数据自动补空格问题
**简介**:在MySQL迁移到崖山环境时,若字段类型为char(2),而应用存储的数据仅为'0'或'1',查询时崖山会自动补空格。原因是mysql的sql_mode可能启用了PAD_CHAR_TO_FULL_LENGTH模式,导致保留CHAR类型尾随空格。解决方法是与应用确认数据需求,可将崖山环境中的char类型改为varchar类型以规避补空格问题,适用于所有版本。
|
9月前
|
关系型数据库 MySQL Java
【YashanDB知识库】崖山BIT类型对MYSQL兼容问题
【YashanDB知识库】崖山BIT类型对MYSQL兼容问题
|
9月前
|
自然语言处理 关系型数据库 MySQL
MySQL索引有哪些类型?
● 普通索引:最基本的索引,没有任何限制。 ● 唯一索引:索引列的值必须唯一,但可以有空值。可以创建组合索引,则列值的组合必须唯一。 ● 主键索引:是特殊的唯一索引,不可以有空值,且表中只存在一个该值。 ● 组合索引:多列值组成一个索引,用于组合搜索,效率高于索引合并。 ● 全文索引:对文本的内容进行分词,进行搜索。
|
9月前
|
存储 关系型数据库 MySQL
【YashanDB知识库】MySQL返回结果集的存储过程的改写方法
本文介绍了将MySQL存储过程改写至YashanDB的解决方案。由于MySQL存储过程可直接返回结果集,而YashanDB需通过返回SYS_REF_CURSOR的函数实现类似功能,因此需要对代码进行转换。示例中展示了如何将MySQL存储过程`proc1`改写为YashanDB函数,并调整JDBC应用代码以适配REF_CURSOR输出参数,从而正确获取查询结果。此方法确保了跨数据库场景下的兼容性与功能性。
|
11月前
|
机器学习/深度学习 关系型数据库 MySQL
mysql bit对gorm使用何种类型?
在GORM中使用MySQL的BIT类型时,通常使用 `bool`类型来处理BIT(1),使用 `[]byte`类型来处理BIT(N)(N > 1)。通过正确的类型映射和位操作,可以高效地处理位字段数据。确保在定义结构体字段时,明确指定字段类型,以便GORM能够正确地处理数据库交互。
282 18
|
10月前
|
存储 SQL 关系型数据库
【YashanDB 知识库】MySQL 迁移至崖山 char 类型数据自动补空格问题
问题分类】功能使用 【关键字】char,char(1) 【问题描述】MySQL 迁移至崖山环境,字段类型源端和目标端都为 char(2),但应用存储的数据为'0'、'1',此时崖山查询该表字段时会自动补充空格 【问题原因分析】mysql 有 sql_mode 控制,检查是否启用了 PAD_CHAR_TO_FULL_LENGTH SQL 模式。如果启用了这个模式,MySQL 才会保留 CHAR 类型字段的尾随空格,默认没有启动。 #查看sql_mode mysql> SHOW VARIABLES LIKE 'sql_mode'; 【解决/规避方法】与应用确认存储的数据,正确定义数据
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
496 6
|
SQL 存储 关系型数据库
MySQL进阶突击系列(01)一条简单SQL搞懂MySQL架构原理 | 含实用命令参数集
本文从MySQL的架构原理出发,详细介绍其SQL查询的全过程,涵盖客户端发起SQL查询、服务端SQL接口、解析器、优化器、存储引擎及日志数据等内容。同时提供了MySQL常用的管理命令参数集,帮助读者深入了解MySQL的技术细节和优化方法。

推荐镜像

更多