视图(View)是一种虚拟存在的表。视图并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表, 并且是在使用视图时动态生成的。视图就是一条SELECT语句执行后返回的结果集。所以在创建视图时,主要的工作就落在创建这条SQL查询语句上。
视图相对于普通的表的优势主要有
简单:使用视图的用户完全不需要关心后面对应的表的结构、关联条件和筛选条件,对用户来说已经是过滤 好的复合条件的结果集。
安全:使用视图的用户只能访问他们被允许查询的结果集,对表的权限管理并不能限制到某个行某个列,但 是通过视图就可以简单的实现。
数据独立:一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响;源表 修改列名,则可以通过修改视图来解决,不会造成对访问者的影响。
创建视图的语法为:
CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
修改视图的语法为:
ALTER [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
创建city_country_view视图 , 执行如下SQL:
create or replace view city_country_view
as
select t.*,c.country_name from country c , city t where c.country_id = t.country_id;
查询视图:跟查询数据操作一样
select * from city_country_view
查看视图
SHOW TABLES
//显示表信息,同时显示视图的信息
SHOW TABLE STATUS
删除视图
DROP VIEW [IF EXISTS] view_name [, view_name] ...[RESTRICT | CASCADE]
DROP VIEW city_country_view;
存储过程和函数是事先经过编译并存储在数据库中的一段 SQL 语句的集合,调用存储过程和函数可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。
存储过程和函数的区别在于函数必须有返回值,而存储过程没有。
函数 : 是一个有返回值的过程 ;过程 : 是一个没有返回值的函数 ;
CREATE PROCEDURE procedure_name ([proc_parameter[,...]])
begin
-- SQL语句
end ;
示例 :
delimiter $
create procedure pro_test1()
begin
select 'Hello Mysql' ;
end$
delimiter ;
//delimiter
//该关键字用来声明SQL语句的分隔符 , 告诉 MySQL 解释器,该段命令是否已经结束了,mysql是否可以执行。
//默认情况下,delimiter是分号;。在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会//执行该命令。
call procedure_name();
-- 查询db_name数据库中的所有的存储过程
select name from mysql.proc where db='db_name';
-- 查询存储过程的状态信息
show procedure status;
-- 查询某个存储过程的定义
show create procedure test.pro_test1 \G;
DROP PROCEDURE [IF EXISTS] sp_name;
存储过程是可以编程的,意味着可以使用变量,表达式,控制结构 , 来完成比较复杂的功能。
变量 DECLARE:定义一个局部变量,该变量的作用范围只能在 BEGIN…END 块中
赋值 SET:直接赋值使用 SET,可以赋常量或者赋表达式。例 SET var_name = 'MYSQL'
赋值 select ... into:例 declare countnum int; select count(*) into countnum from city;
判断 if
传递参数:IN - 输入 ,OUT-输出 ,INOUT: 既可以作为输入参数,也可以作为输出参数
case结构
while循环
repeat结构:有条件的循环控制语句, 当满足条件时退出循环 。while 是满足条件才执行,repeat 是满足条件就退出循环。
loop语句:LOOP 实现简单的循环,退出循环的条件需要使用其他的语句定义,通常可以使用 LEAVE 语句实现
leave语句:用来从标注的流程构造中退出,通常和 BEGIN ... END 或者循环一起使用
游标/光标:游标是用来存储查询结果集的数据类型 , 在存储过程和函数中可以使用光标对结果集进行循环的处理。光标的使用 包括光标的声明、OPEN、FETCH 和 CLOSE
CREATE FUNCTION function_name([param type ... ])
RETURNS type
BEGIN
...
END;
定义一个存储过程, 请求满足条件的总记录数
delimiter $
create function count_city(countryId int)
returns int
begin
declare cnum int ;
select count(*) into cnum from city where country_id = countryId;
return cnum;
end$
delimiter ;
调用
select count_city(1);
触发器是与表有关的数据库对象,指在 insert/update/delete 之前或之后,触发并执行触发器中定义的SQL语句集合。触发器可以协助应用在数据库端确保数据的完整性 ,日志记录 , 数据校验等操作。使用别名 OLD 和 NEW 来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只支持行级触发,不支持语句级触发
语法结构
create trigger trigger_name
before/after insert/update/delete
on tbl_name
[ for each row ] -- 行级触发器
begin
trigger_stmt ;
end;
需求:通过触发器记录 emp 表的数据变更日志 , 包含增加, 修改 , 删除 ;
创建 insert 型触发器,完成插入数据时的日志记录 :
DELIMITER $
create trigger emp_logs_insert_trigger
after insert
on emp
for each row
begin
insert into emp_logs (id,operation,operate_time,operate_id,operate_params)
values(null,'insert',now(),new.id,concat('插入后(id:',new.id,', name:',new.name,',
age:',new.age,', salary:',new.salary,')'));
end $
DELIMITER ;
//如果没有指定 schema_name,默认为当前数据库
drop trigger [schema_name.]trigger_name
show triggers;