MySQL数据库——视图、存储过程、变量、函数

视图

1、定义

视图就是一条SELECT语句执行后返回的结果集。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。

2、特点

视图是对若干张基本表的引用,一张虚表,查询语句执行的结果,不存储具体的数据(基本表数据发生了改变,视图也会跟着改变)
视图一般不执行增删改操作,只用来查询。

3、优势

方便操作,特别是查询操作,减少复杂的SQL语句,增强可读性;
更加安全,数据库授权命令不能限定到特定行和特定列,但是通过合理创建视图,可以把权限限定到行列级别。

4、案例

现有三张表:用户(user)、课程(course)、用户课程中间表(user_course),可以通过外连接查询“小张”上的所有课的信息:

SELECT 
  `uc`.`id` AS `id`,
  `u`.`name` AS `username`,
  `c`.`name` AS `coursename` 
FROM
  `user` `u` 
  LEFT JOIN `user_course` `uc` 
    ON `u`.`id` = `uc`.`userid` 
  LEFT JOIN `course` `c` 
    ON `uc`.`courseid` = `c`.`id`
WHERE u.`name` = '小张' 

我们可以将这部分代码直接封装起来,成为一个视图,调用视图,只需要传入name,从而将结果输出:

-- 创建视图,名称必须vm开头
CREATE VIEW `vw_user_course` AS (
	SELECT
	`uc`.`id` AS `id`,
	`u`.`name` AS `username`,
	`c`.`name` AS `coursename`
	FROM
	`user` `u`
	LEFT JOIN `user_course` `uc` 
	ON `u`.`id` = `uc`.`userid`
	LEFT JOIN `course` `c` 
	ON `uc`.`courseid` = `c`.`id`
);

-- 调用
SELECT *
FROM vw_user_course
WHERE username = '小张';

-- 删除
DROP VIEW
IF EXISTS `view_user_course`;

存储过程

1、定义

存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

存储过程是可编程的函数,在数据库中创建并保存,可以由SQL语句和控制结构组成。当想要在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟,它允许控制数据的访问方式。

2、优势

(1).增强SQL语言的功能和灵活性.
存储过程可以用控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。

(2).标准组件式编程.
存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。

(3).较快的执行速度.
如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。

(4).减少网络流量.
针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织进存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大减少网络流量并降低了网络负载。

(5).作为一种安全机制来充分利用.
通过对执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。

3、基本格式语法

/*
MySQL默认以";"为分隔符,如果没有声明分割符,则编译器会把存储过程当成SQL语句进行处理
因此编译过程会报错,所以要事先用"DELIMITER //"声明当前段分隔符
让编译器把两个"//"之间的内容当做存储过程的代码,不会执行这些代码;
"DELIMITER ;"的意为把分隔符还原为;
PROCEDURE后面为函数名称,括号内为参数,IN为输入参数,OUT为输出参数,INOUT为输入输出参数
BEGIN和END之间为方法体
*/
DELIMITER //
  CREATE PROCEDURE myproc(OUT s int)
    BEGIN
      SELECT COUNT(*) INTO s FROM students;
    END
//
DELIMITER ;
4、案例

转账存储过程

通过id转账,实际生活中就是银行卡号
DELIMITER //
CREATE PROCEDURE transMoney(IN fromid INT, IN toid INT, IN m DECIMAL)
BEGIN
	UPDATE account SET money=money-m WHERE id=fromid;
	UPDATE account SET money=money+m WHERE id=toid;
END;
//
DELIMITER ;

#调用,只提供银行卡号和金额,所以安全性极高
CALL transMoney(1,2,1000);

使用存储添加学生

DELIMITER //
CREATE PROCEDURE addStudent(IN _id INT, IN `_name` VARCHAR(10), IN _age INT,_address VARCHAR(100))
BEGIN
	INSERT INTO student(id,NAME,age,address) VALUES(_id,_name,_age,_address);	
END;
//
DELIMITER ;

#调用
CALL addStudent(6,'Jack',20,'南京');

变量

1、局部变量

只在当前begin/end代码块中有效。

局部变量一般用在sql语句块中,比如存储过程的begin/end。其作用域仅限于该语句块,在该语句块执行完毕后,局部变量就消失了。declare语句专门用于定义局部变量,可以使用default来说明默认值。

-- 语法格式
DECLARE var_name [, var_name]... data_type [ DEFAULT value ];

-- 案例一
DELIMITER //
CREATE PROCEDURE addNum(IN a INT, IN b VARCHAR(10))
BEGIN
	DECLARE c INT DEFAULT 0;
	SET c=a+b; #赋值,必须要有SET
	SELECT c AS C;
END;
//
DELIMITER ;
#调用
CALL addNum(10,20);

2、用户变量

在客户端链接到数据库实例整个过程中用户变量都是有效的。

mysql中用户变量不用事前申明,在用的时候直接用“@变量名”使用就可以了。

第一种用法:set @num=1; 或set @num:=1; 这里要使用set语句创建并初始化变量,直接使用@num变量
第二种用法:select @num:=1; 或 select @num:=字段名 from 表名 where …
注意上面两种赋值符号,使用set时可以用“=”或“:=”,但是使用select时必须用“:=赋值”

用户变量一般可以用来存储数据。

select @name:=password from user limit 0,1;

3、会话变量

服务器为每个连接的客户端维护一系列会话变量。在客户端连接数据库实例时,使用相应全局变量的当前值对客户端的会话变量进行初始化。设置会话变量不需要特殊权限,但客户端只能更改自己的会话变量,而不能更改其它客户端的会话变量。会话变量的作用域与用户变量一样,仅限于当前连接。当当前连接断开后,其设置的所有会话变量均失效。

#会话变量,查看编码
SHOW SESSION VARIABLES;
SHOW VARIABLES LIKE '%character%';
select @@var_name;
select @@session.var_name;
show session variables like "%var%";

4、全局变量

全局变量影响服务器整体操作。当服务器启动时,它将所有全局变量初始化为默认值。这些默认值可以在选项文件中或在命令行中指定的选项进行更改。要想更改全局变量,必须具有SUPER权限。

-- 查看所有的全局变量 
show global variables;
-- 要想查看一个全局变量,有如下两种方式:
select @@global.var_name;
show global variables like%var%;

函数

存储过程和函数区别: 存储过程没有返回值,使用输出参数返回数据,可以有多个,函数有返回值,只能返回一个。

MySQL 有很多内置的函数

1、字符串函数

mysql中处理字符串时,默认第一个字符下标为1,即参数position必须大于等于1

CHARSET(str) //返回字串字符集
CONCAT (string2 [,... ]) //连接字串
INSTR (string ,substring ) //返回substring首次在string中出现的位置,不存在返回0
LCASE (string2 ) //转换成小写
LEFT (string2 ,length ) //从string2中的左边起取length个字符
LENGTH (string ) //string长度,字节的长度
LOAD_FILE (file_name ) //从文件读取内容
LOCATE (substring , string [,start_position ] ) 同INSTR,但可指定开始位置
LPAD (string ,length ,pad ) //重复用pad加在string开头,直到字串长度为length
LTRIM (string ) //去除前端空格
REPEAT (string2 ,count ) //重复count次
REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替换search_str
RPAD (string ,length ,pad) //在str后用pad补充,直到长度为length
RTRIM (string ) //去除后端空格
STRCMP (string1 ,string2) //逐字符比较两字串大小,
SUBSTRING (str , position [,length ]) //从str的position开始,取length个字符,
TRIM([[BOTH|LEADING|TRAILING] [padding] FROM]string2) //去除指定位置的指定字符
UCASE (string2 ) //转换成大写
RIGHT(string2,length) //取string2最后length个字符
SPACE(count) //生成count个空格
--注:mysql中处理字符串时,默认第一个字符下标为1,即参数position必须大于等于1

2、数学类函数

ABS (number2 ) //绝对值
BIN (decimal_number) //十进制转二进制
CEILING (number2 ) //向上取整
CONV(number2,from_base,to_base) //进制转换
FLOOR (number2 ) //向下取整
FORMAT (number,decimal_places ) //保留小数位数
HEX (DecimalNumber) //转十六进制
POWER (number ,power ) //求指数
RAND([seed]) //随机数
ROUND (number [,decimals ]) //四舍五入,decimals为小数位数] 注:返回类型并非均为整数

3、日期时间类

ADDTIME (date2 ,time_interval) //将time_interval天加到date2  秒
ADDDATE('2019-04-15',2); #2天
CURRENT_DATE ( ) //当前日期
CURRENT_TIME ( ) //当前时间
CURRENT_TIMESTAMP ( ) //当前时间戳
DATE (datetime ) //返回datetime的日期部分
DATE_ADD (date2 , INTERVAL d_value d_type ) //在date2中加上日期或时间
DATE_FORMAT (datetime ,FormatCodes ) //使用formatcodes格式显示datetime
DATE_SUB (date2 , INTERVAL d_value d_type ) //在date2上减去一个时间
DATEDIFF (date1 ,date2 ) //两个日期差
DAY (date ) //返回日期的天
DAYNAME (date ) //英文星期
DAYOFWEEK (date ) //星期(1-7) ,1为星期天
DAYOFYEAR (date ) //一年中的第几天
EXTRACT (interval_name FROM date ) //从date中提取日期的指定部分
MAKEDATE (year ,day ) //给出年及年中的第几天,生成日期串
MAKETIME (hour ,minute ,second ) //生成时间串
MONTHNAME (date ) //英文月份名
NOW ( ) //当前时间
SEC_TO_TIME (seconds ) //秒数转成时间
STR_TO_DATE (string ,format ) //字串转成时间,以format格式显示
TIMEDIFF (datetime1 ,datetime2 ) //两个时间差
TIME_TO_SEC(time) //时间转秒数
WEEK (date_time [,start_of_week ]) //第几周
YEAR (datetime ) //年份
DAYOFMONTH(datetime) //月的第几天
HOUR(datetime) //小时
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值