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

关联博文:

存储过程中的控制语句
PLSQL存储过程
MySQL中不同类型参数存储过程示例
MyBatis调用存储过程

【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型参数最终值
<think>嗯,用户需要关于数据库和商业数据分析面试题。首先,我得确认这两个领域的关键知识点。数据库方面,常见的问题包括SQL查询、事务、索引、范式、ACID特性,以及优化技巧。商业数据分析可能涉及数据分析方法、工具使用(如SQL、Python、Excel)、统计知识、业务指标的理解,还有案例分析的题目。 用户提到的引用[1]提到了数据分析在业务场景中的应用,比如评估营销效果和定价策略,这可能意味着他们希望面试题不仅考察技术能力,还有实际业务应用能力。引用[2]提到了事务的一致性,这属于数据库中的ACID特性,所以数据库部分需要涵盖事务相关的问题。 接下来,我需要确保问题覆盖基础到进阶的内容,适合不同层次的面试者。比如,数据库部分可以包括基本的SQL查询,事务的ACID,索引的作用,范式理论,以及优化策略。而商业数据分析可能需要包括指标定义、AB测试、数据清洗、可视化工具、统计方法等。 另外,用户提到的示例中,快速排序相关问题包括性能分析、优化方法和应用场景。这提示我应该为每个主要知识点生成相关问题,帮助用户深入理解。例如,在数据库事务部分,可以问如何保证一致性,或者事务隔离级别的问题。在数据分析部分,可以涉及如何设计AB测试,或者如何处理缺失数据。 还要注意问题是否实用,能否反映实际工作场景。比如,商业数据分析可能会问如何评估营销活动效果,这直接关联到引用[1]的内容。同时,结合数据库的问题,比如优化慢查询,可以引用到索引的使用和查询优化技巧。 最后,需要检查问题是否全面,有没有遗漏重要的考点。例如,数据库部分是否覆盖了主流的数据库类型(如关系型和非关系型),商业数据分析是否包括常用的工具和模型。此外,是否有一些综合性的问题,比如结合数据库和数据分析的实际案例题,这样能更好地评估面试者的综合能力。</think>### 数据库与商业数据分析面试题整理 --- #### **一、数据库核心问题** 1. **SQL基础与优化** - 写一个SQL查询:统计订单表中每个用户的最近一次订单金额,并按金额降序排列[^2]。 - 什么是覆盖索引?如何通过覆盖索引优化查询性能? - 解释数据库范式的区别(如第一范式、第三范式)及其对设计的影响。 2. **事务与锁机制** - 事务的ACID特性中,如何通过锁机制实现“隔离性”?举例说明脏读和不可重复读的区别。 - 如果事务执行过程中发生死锁,数据库通常会如何处理? 3. **性能调优** - 如何分析并优化一个执行缓慢的SQL查询? - 分库分表的适用场景及实现方案有哪些? --- #### **二、商业数据分析核心问题** 1. **数据分析方法** - 如何设计一个AB测试来评估新功能对用户留存率的影响?需要控制哪些变量? - 解释“同期群分析”(Cohort Analysis)的定义和应用场景[^1]。 2. **业务指标与可视化** - 定义“用户流失率”并设计一个SQL查询来计算它。 - 如何通过数据可视化工具(如Tableau)解释销售数据的季节性波动? 3. **数据清洗与统计** - 如何处理数据集中的缺失值?列举三种常用方法并说明其优缺点。 - 假设检验中p值的意义是什么?如何用p值判断营销活动的显著性效果? --- #### **三、综合应用题** 1. **场景题** - 某电商平台发现某类商品的退货率突然上升,请描述你的分析思路和所需数据。 - 设计一个数据分析方案,帮助公司决定是否应扩展某个区域的市场。 2. **SQL与业务结合** - 给定用户行为表(包含用户ID、行为类型、时间戳),写一个SQL查询找出连续三天登录的用户。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值