本身是一个虚拟表,它的数据来自于表,通过执行时动态生成,占用较小,只保存了sql逻辑,不保存查询结果。临时表
场景:多个地方用到同样的查询结果;该查询结果使用的sql语句较复杂
create view 视图名
as
查询语句;
create or replace view 视图名
as
查询语句;
alter view 视图名
as
查询语句
drop view 视图1,视图2,...;
desc 视图名;
show create view 视图名;
CREATE VIEW my_v1
AS
SELECT studentname,majorname
FROM student s
INNER JOIN major m
ON s.majorid=m.majorid
WHERE s.majorid=1;
注意:视图一般用于查询的,而不是更新的,所以具备以下特点的视图都不允许更新
变量由系统提供的,不用自定义
全局变量:服务器层面上的,必须拥有super权限才能为系统变量赋值,作用域为整个服务器,也就是针对于所有连接(会话)有效
查看所有全局变量
SHOW GLOBAL VARIABLES;
查看满足条件的部分系统变量
SHOW GLOBAL VARIABLES LIKE '%char%';
查看指定的系统变量的值
SELECT @@global.autocommit;
为某个系统变量赋值
SET @@global.autocommit=0;
SET GLOBAL autocommit=0;
会话变量:服务器为每一个连接的客户端都提供了系统变量,作用域为当前的连接(会话)
查看所有会话变量
SHOW SESSION VARIABLES;
查看满足条件的部分会话变量
SHOW SESSION VARIABLES LIKE '%char%';
查看指定的会话变量的值
SELECT @@autocommit;
SELECT @@session.tx_isolation;
为某个会话变量赋值
SET @@session.tx_isolation='read-uncommitted';
SET SESSION tx_isolation='read-committed';
如果没有显式声明 global 还是 session,则默认是 session
用户变量
①声明并赋值:
set @变量名=值;或
set @变量名:=值;或
select @变量名:=值;
②更新值
方式一:
set @变量名=值;或
set @变量名:=值;或
select @变量名:=值;
方式二:
select xx into @变量名 from 表;
③使用
select @变量名;
局部变量:
①声明
declare 变量名 类型 【default 值】;
②赋值或更新
方式一:
set 变量名=值;或
set 变量名:=值;或
select @变量名:=值;
方式二:
select xx into 变量名 from 表;
③使用
select 变量名;
作用域 | 定义位置 | 语法 | |
---|---|---|---|
用户变量 | 当前会话 | 会话的任何地方 | 加@符号,不用指定类型 |
局部变量 | 定义它的BEGIN END中 | BEGIN END的第一句话 | 一般不用加@,需要指定类型 |
数据库存储过程:就是一组SQL语句集,功能强大,可以实现一些比较复杂的逻辑功能,类似于JAVA语言中的方法。
存储过程跟触发器有点类似,都是一组SQL集,但是存储过程是主动调用的,且功能比触发器更加强大,触发器是某件事触发后自动调用;
创建:
create procedure 存储过程名(参数模式 参数名 参数类型)
begin
存储过程体
end
注意:
结束标记
使用 delimiter 指定新的结束标记
delimiter $
调用:
call 存储过程名(实参列表)
举例:
调用in模式的参数:call sp1(‘值’);
调用out模式的参数:set @name; call sp1(@name);select @name;
调用inout模式的参数:set @name=值; call sp1(@name); select @name;
查看
show create procedure 存储过程名;
删除
drop procedure 存储过程名;
下面创建一个名为num_from_employee的存储过程.
CREATE PROCEDURE num_from_employee (IN emp_id INT, OUT count_num INT )
READS SQL DATA
BEGIN
SELECT COUNT(*) INTO count_num
FROM employee
WHERE d_id=emp_id ;
END
#调用
SET @cnum ; # 不定义直接用也可以
CALL num_from_employee(123,@cnum);
存储过程名称为 num_from_employee
;输入变量为emp_id
;输出变量为count_num
。SELECT语句从employee
表查询d_id
值等于emp_id
的记录,并用COUNT(*)
计算d_id
值相同的记录的条数,最后将计算结果存入count_num
中。
创建
create function 函数名(参数名 参数类型) returns 返回类型
begin
函数体
end
注意:函数体中肯定需要有return语句
#案例1:根据员工名,返回它的工资;有参有返回
CREATE FUNCTION myf2(empName VARCHAR(20)) RETURNS DOUBLE
BEGIN
SET @sal=0;#定义用户变量
SELECT salary INTO @sal #赋值
FROM employees
WHERE last_name = empName;
RETURN @sal;
END $
SELECT myf2('k_ing') $
调用
select 函数名(实参列表);
查看
show create function 函数名;
删除
drop function 函数名;
关键字 | 调用语法 | 返回值 | 应用场景 | |
---|---|---|---|---|
函数 | FUNCTION | SELECT 函数() | 只能是一个 | 一般用于查询结果为一个值并返回时 |
存储过程 | PROCEDURE | CALL 存储过程() | 可以有0个或多个 | 一般用于更新 |
顺序结构:程序从上往下依次执行
分支结构:程序按条件进行选择执行,从两条或多条路径中选择一条执行
循环结构:程序满足一定条件下,重复执行一组语句
if 函数
if(条件,值1,值2)
case 结构
语法1:
case 表达式或字段
when 值1 then 语句1;
when 值2 then 语句2;
..
else 语句n;
end [case];
语法2:
case
when 条件1 then 语句1;
when 条件2 then 语句2;
..
else 语句n;
end [case];
if 结构
if 条件1 then 语句1;
elseif 条件2 then 语句2;
...
else 语句n;
end if;
while
名称可以不写,写了就成对使用,记得冒号
【名称:】while 循环条件 do
循环体
end while 【名称】;
loop
注意死循环
【名称:】loop
循环体
end loop 【名称】;
repeat
【名称:】repeat
循环体
until 结束条件
end repeat 【名称】;
比较
位置:只能放在begin end中
特点:都能实现循环结构
对比:
循环控制语句
/*一、已知表stringcontent
其中字段:
id 自增长
content varchar(20)
向该表插入指定个数的,随机的字符串
*/
DROP TABLE IF EXISTS stringcontent;
CREATE TABLE stringcontent(
id INT PRIMARY KEY AUTO_INCREMENT,
content VARCHAR(20)
);
DELIMITER $
CREATE PROCEDURE test_randstr_insert(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE str VARCHAR(26) DEFAULT 'abcdefghijklmnopqrstuvwxyz';
DECLARE startIndex INT;#代表初始索引
DECLARE len INT;#代表截取的字符长度
WHILE i<=insertcount DO
SET startIndex=FLOOR(RAND()*26+1);#代表初始索引,随机范围1-26
SET len=FLOOR(RAND()*(20-startIndex+1)+1);#代表截取长度,随机范围1-(20-startIndex+1)
INSERT INTO stringcontent(content) VALUES(SUBSTR(str,startIndex,len));
SET i=i+1;
END WHILE;
END $
CALL test_randstr_insert(10)$
触发器(TRIGGER)是由事件来触发某个操作。这些事件包括INSERT语句、UPDATE语句和DELETE语句。当数据库系统执行这些事件时,会激活促发其执行相应的操作。参考
CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件
ON 表名 FOR EACH ROW
BEGIN
执行语句列表
END
触发事件:
当在users中插入一条数据,就会在logs中生成一条日志信息。
DELIMITER $
CREATE TRIGGER user_log AFTER INSERT ON users FOR EACH ROW
BEGIN
DECLARE s1 VARCHAR(40)character set utf8;
DECLARE s2 VARCHAR(20) character set utf8;#后面发现中文字符编码出现乱码,这里设置字符集
SET s2 = " is created";
SET s1 = CONCAT(NEW.name,s2); #函数CONCAT可以将字符串连接
INSERT INTO logs(log) values(s1);
END $
DELIMITER ;
mysql5.1.6 增加了一个事件调度器(Event Scheduler),可以做定时任务(定时删除记录,定时数据统计),取代之前系统的计划任务。mysql事件调度器可以精确到每秒执行一个任务。参考
事件调度器与触发器的区别:事件调度器是基于特定时间周期来触发执行某些任务,触发器是基于某个表产生的事件来触发。
查看是否开启
show variables like 'event_scheduler';
开启事件调度器
set global event_scheduler = on;
当mysql重启后,会自动关闭。如果需要一直开启,需要在my.ini
中配置如下:event_scheduler = on
创建事件语法
CREATE EVENT [IF NOT EXISTS ] event_name
ON SCHEDULE schedule
[ ON COMPLETION [ NOT ] PRESERVE ]
[ ENABLE | DISABLE ]
[ COMMENT '注释' ]
DO SQL语句;
schedule : AT TIMESTAMP [+ INTERVAL interval ] | EVERY interval [ STARTS TIMESTAMP ] [ ENDS TIMESTAMP ]
interval : quantity { YEAR | QUARTER | MONTH | DAY |
HOUR | MINUTE | WEEK | SECOND |
YEAR_MONTH | DAY_HOUR | DAY_MINUTE | DAY_SECOND |
HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND }
关闭事件
ALTER EVENT event_name DISABLE;
开启事件
ALTER EVENT event_name ENABLE;
删除事件
DROP EVENT [IF EXISTS ] event_name;
查看所有事件
SHOW EVENTS;
查看定期任务
SELECT event_name,event_definition,interval_value,interval_field,status
FROM information_schema.EVENTS;
定时规则
示例
事件类型有两种,一种是间隔触发,一种是特定时间触发
DROP EVENT IF EXISTS event_test;
CREATE EVENT event_test
ON SCHEDULE EVERY 1 SECOND STARTS '2017-08-22 11:57:00' ENDS '2017-08-22 12:00:00'
ON COMPLETION PRESERVE
ENABLE
COMMENT '每隔一秒向test表插入记录'
DO INSERT INTO test VALUES(NULL, now());
DROP EVENT IF EXISTS event_test2;
CREATE EVENT event_test2
ON SCHEDULE AT '2017-08-22 12:01:00'
ON COMPLETION PRESERVE
ENABLE
COMMENT '指定时间向test表插入记录'
DO INSERT INTO test VALUES(999999, now());
on schedule every 1 week //每周执行1次
on schedule at current_timestamp()+interval 5 day //5天后执行
on schedule at '2019-01-01 00:00:00' //在2019年1月1日,0点整执行
on schedule every 1 day starts current_timestamp()+interval 5 day ends current_timestamp()+interval 1 month //5天后开始每天都执行执行到下个月底
on schedule every 1 day ends current_timestamp()+interval 5 day //从现在起每天执行,执行5天
alter database mydb character set 'utf-8;
alter table mytbl convert to character set 'utf-8';