视图
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) //小时