mySQL__storage课堂笔记和练习

#存储过程和函数
/*
存储过程和函数类似于Java中的方法
好处:
1、提高代码重用性
2、简化操作
*/
#存储过程
/*
含义:一组编译好的SQL语句的集合,理解成批处理语句
1、提高代码的重用性
2、简化操作
3、减少了编译次数
4、减少了和数据库服务器连接次数,提高了效率
*/

#一、创建
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN 
	存储过程体(一组合法的SQL语句)
END

注意:
1、参数列表包含3个部分
参数模式 参数名 参数类型
举例:
IN stuname VARCHAR(20)

参数模式:
IN:修饰的参数可以作为入口,也就是说该参数需要调用方传入值
OUT:修饰的参数可以作为出口,也就是说该参数可以作为返回值
INOUT:修饰的参数可以作为出口/入口,既可以传入值又可以返回值


2、如果存储过程体仅仅只有1句话,BEGIN END可以省略

3、存储过程体中的每条SQL语句的结尾要求必须加分号,
存储过程的结尾可以使用DELIMITER重新设置
语法:
DELIMITER 结束标记
案例:
DELIMITER $

#二、调用
CALL 存储过程名(实参列表);

#1、空白列表
#案例:插入到admin表中5条记录
SELECT * FROM admin;
#设置结束标志
DELIMITER $

#定义
CREATE PROCEDURE myp1()
BEGIN
	INSERT INTO admin(username,`password`)
	VALUES('john1','0000'),('lily','0000'),('rose','0000'),('jack','0000'),('tom','0000');
END $
#如果SQLyog中运行不了,就粘贴到cmd打开girls数据库,再运行

#调用
CALL myp1()$#之后结束符号都不是;了,都换成$
SELECT * FROM admin$
#如果SQLyog中运行不了,就粘贴到cmd打开girls数据库,再运行




#2、创建带in模式参数的存储过程
#案例1:创建存储过程实现,根据女神名查询对应的男神信息
#IN 可以省略,但是不建议
#定义
CREATE PROCEDURE myp2(IN beautyName VARCHAR(20))
BEGIN
	SELECT bo.*
	FROM boys bo
	RIGHT JOIN beauty b ON bo.id = b.boyfriend_id
	WHERE b.name=beautyName;
END$
#调用
CALL myp2('宋茜')$
#如果出现报错: Incorrect string value: '\xC1\xF8\xD1\xD2' for column 'beautyName' at row 8
#说明是字符集的问题,这时要重新设置一下字符集
SET NAMES gbk$
CALL myp2('宋茜')$#不报错了




#案例2:创建存储过程实现,用户登陆是否成功
#定义
CREATE PROCEDURE myp5(IN username VARCHAR(20),IN PASSWORD VARCHAR(20))
BEGIN
	#声明变量,存放存储结果
	DECLARE result INT DEFAULT 0;#声明并初始化
	#赋值
	SELECT COUNT(*) INTO result
	FROM admin
	WHERE admin.`username`=username
	AND admin.`password`=PASSWORD;
	#使用
	
	SELECT IF(result>0,'成功','失败');
END$
#调用
CALL myp5('张飞','8888')$


#3、创建带out模式的存储过程
#案例1:根据女神名,返回对应的男神名
CREATE PROCEDURE myp6(IN beautyName VARCHAR(20),OUT boyname VARCHAR(20))
BEGIN
	SELECT bo.boyName INTO boyName
	FROM boys bo
	INNER JOIN beauty b ON b.boyfriend_id=bo.id
	WHERE b.name=beautyName;
END$

#调用
#第二个参数就是一个变量,不需要有值,用于接收返回值
SET @bName$#定义一个用户变量,甚至可以不定义,直接用@bName
CALL myp6('宋茜',@bName)$
SELECT @bName$#这就是男神名


#案例2:根据女神名,返回对应的男神名和男神的魅力值
CREATE PROCEDURE myp7(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20),OUT userCP INT)
BEGIN
	SELECT bo.boyName,bo.userCP INTO boyName,userCP
	FROM boys bo
	INNER JOIN beauty b ON b.boyfriend_id=bo.id
	WHERE b.name=beautyName;
END$

#调用
CALL myp7('宋茜',@bName,@usercp)$
SELECT @bName,@usercp$



#4、创建带有inout模式参数的存储过程
#案例1:传入a和b两个值,最终a和b都翻倍并返回
CREATE PROCEDURE myp8(INOUT a INT, INOUT b INT)
BEGIN
	SET a=a*2;
	SET b=b*2;
END$
#调用
#注意:不可以直接往存储过程中传常数,如果传常数,返回的值将没有位置放
#因此在调用之前,必须要先定义两个有值的变量
SET @m=10$
SET @n=20$
CALL myp8(@m,@n)$
SELECT @m,@n$






#三、存储过程的删除
/*
语法:drop procedure 存储过程名称
说明:每次只能删除一个【在SQLyog中就可以运行】
*/

DROP PROCEDURE test_prop3;



#四、查看存储过程信息
SHOW CREATE PROCEDURE myp2;
#desc myp2是错误写法


#【练习】
#练习1:创建存储过程,实现传入用户名和密码,插入到admin表中
CREATE PROCEDURE test_pro1(IN username VARCHAR(20),IN loginPwd VARCHAR(20))
BEGIN
	INSERT admin(admin.username,PASSWORD)
	VALUES(userName,loginPwd);
END;$#这里也可以加个分号
CALL test_pro1('admin','0000')$

SELECT * FROM admin$


#练习2:创建存储过程实现传入女神编号,返回女神名称和女神电话
CREATE PROCEDURE test_pro2(IN id INT, OUT `name` VARCHAR(20) , OUT phone VARCHAR(20))
BEGIN
	SELECT b.name,b.phone INTO `name`,phone
	FROM beauty b
	WHERE b.id=id;
END$

CALL test_pro2(7,@n,@p)$
SELECT @n,@p$

#练习3:创建存储过程或函数实现传入两个女神生日,返回大小
CREATE PROCEDURE test_pro3(IN birth1 DATETIME, IN birth2 DATETIME,OUT result INT)
BEGIN
	SELECT DATEDIFF(birth1,birth2) INTO result;
END$
CALL test_pro3('1998-1-1',NOW(),@result)$

SELECT @result$

#练习4:创建存储过程或函数实现传入一个日期,格式化成xx年xx月xx日并返回
CREATE PROCEDURE test_pro4(IN mydate DATETIME,OUT strDate VARCHAR(50))
BEGIN
	SELECT DATE_FORMAT(mydate,'%y年%m月%d日') INTO strDate;
	#DATE_FORMAT将日期转换为字符串并且返回一个字符串
END$

CALL test_pro4(NOW(),@str)$
SELECT @str$


#练习5:创建存储过程或函数实现传入女神名称,返回:女神 and 男神   格式的字符串
CREATE PROCEDURE test_pro5(IN beautyName VARCHAR(20),OUT str VARCHAR(50))
BEGIN
	SELECT CONCAT(beautyName,'  and  ',IFNULL(boyName,'null')) INTO str
	FROM boys bo
	RIGHT JOIN beauty b ON b.boyfriend_id=bo.id
	WHERE b.name=beautyName;
END$

CALL test_pro5('宋茜',@str)$
SELECT @str$



#练习6:创建存储过程函数,根据传入的条目数和起始索引,查询beauty表的记录
CREATE PROCEDURE test_pro6(IN startIndex  INT, IN size INT)
BEGIN
	SELECT * FROM beauty LIMIT startIndex,size;
END$

CALL test_pro6(1,2)$#索引和id无关

猜你喜欢

转载自www.cnblogs.com/deer-cen/p/12791783.html