- 视图的操作
- 存储过程与存储函数
- 触发器的操作
- (最末尾有测试数据库表和数据代码)
一、视图的操作
1.1视图可以用来做什么?
简单的说视图就是一个查询,它在业务中只需要最简单的查询语句就可以获取到业务需要的数据。
select * from view_selectproduct;
可以这么简单的查询数据记录,是通过将SQL查询语句封装在视图中,比如我们来看看如何创建视图:
create view view_selectproduct
as
select id,name
from t_product;
1.2为什么使用视图?
前面说过了在业务开发中不需要每次都去写复杂的查询语句,只要使用最简单的查询语句查询视图就可以实现(便捷)。除了方便开发,还有一些数据表中除了必要的业务需要的数据,还有一些敏感数据并不需要查询出来,比如查看用户信息并不需要将用户的密码查询出来(数据安全)。还可以为不同的业务定制不同的查询视图(灵活)。
1.3视图的一些概念:
- 视图是基于数据表的虚拟表,它并不用于存储数据,是表的抽象和在逻辑意义上建立的新关系。
- 视图的列可以来自于不同的表。(根据封装的SQL查询语句产生)
- 视图的建立与删除不影响基本表。
- 对视图内容的更新(添加、删除、修改)之影响视图的查询结果,并不影响数据表的结构。
1.4查看、修改、删除视图的操作:
//查看视图定义信息 show create view view_name; //查看视图设计信息(describe | desc) desc view_name; //修改视图:CREATE OR REPLACE VIEW ... AS ...; create or replace view view_name as select...; //修改视图:ALTER VIEW ... AS ...; alter view view_name as select...; //删除视图 drop view view_name [,view_name]...;
1.5视图除了查询数据记录还能做些什么?
视图也可以用来进行数据添加、删除,且直接影响基本表。但是当视图来自多个基础表时,不允许添加和删除数据。虽然视图可以添加和删除数据,但是不建议这么做。
//通过视图写入数据记录 INSERT INTO view_name (field1,field2,...fieldn) VALUES(data1,data2,...datan); //通过视图删除数据记录 DELECT FROM view_name WHERE condition
1.6可以通过视图来创建常量视图:
//∏ CREATE VIEW pi AS SELECT 3.1415926;
二、存储过程与存储函数
1.存储过程可以用来做什么?
在很多的实际业务中,一个请求需要多条SQL语句来完成,这时候就需要用到存储过程,也就是说存储过程是用来处理多条SQL语句的请求。例如为了完成商品订单处理,需要考虑以下情况:
(a)在生成订单前,首先需要查看商品库中是否有相应的商品(是否还有库存)。
(b)如果商品库中存在相应的商品,接着需要预定商品以防该商品卖给他人,并且修改库存物品数量以反映正确的库存量。
(c)如果商品库存中不存在相应的商品,则需要向供货商订货。
在以上示例中,它肯定不是单条SQL语句能实现的,这时候就需要使用存储过程来实现一次处理多条SQL语句的操作。
2.存储过程的语法:
CREATE PROCEDURE procedure_name([procedure_parameter[,...]])
[characteristic...] routine_body
- procedure_name:存储过程的名称。
- procedure_parameter:存储过程的参数,每个参数的语法形式 [IN|OUT|INOUT] parameter_name type ,参数三部分分别表示:输入输出类型、参数名、参数类型。IN表示输入类型;OUT表示输出类型;INOUT表示输入/输出类型。
- characteristic:存储过程的特性。
- routine_body:存储过程的SQL语句代码。
存储过程的特性(characteristic)参数取值解析,以及默认取值:
LANGUAGE SQL//指定存储过程routine_body部分为SQL语句,默认特性。(看到有些资料中说将来可能支持其他语言来实现存储过程的数据操作) | [NOT] DETERMINISTIC//表示存储过程的执行结果是否确定,意思是输入相同的参数执行结果是否一致,默认DETERMINISTIC表示存储过程执行结果一致。那NOT DETERMINISTIC也就是执行结果不一致,这个特性简单的来讲可以在结果一致时缓存执行结果,不需要每次调用存储过程都操作数据库,从而达到提升性能的目的 | {CONTAINS SQL|NO SQL|READS SQL DATA|MODIFIES SQL DATA}//表示使用SQL语句的限制,默认值为CONTAINS SQL,表示包含SQL语句但不包含读或写的语句。NO SQL表示不包含SQL语句;READS SQL DATA表示包含读数据的语句;MODIFIES SQL DATA表示包含写数据的语句。看到这个解析是不是很恐慌,别怕这个特性目前只提交给服务,并不约束实际的实际的数据操作,所以说这个特性实际上不会被作用,至少目前是不会作用。 | SQL SECURITY {DEFINER|INVOKER}//设置谁有权限来执行,默认值为DEFINER,表示只有自己才能够执行。INVOKER表示调用者可以执行。 | COMMENT 'string'//表示注释语句,用来描述存储过程的字符串。
看到上面的语法和特性解析,是不是感觉存储过程就弄明白了,理论上这么说没错,但是别飘!比如在SQL语句中使用分号(;)表示SQL语句的结束符,我们知道每写一句SQL语句就需要使用分号间隔,但是一个存储过程中需要包含多个SQL语句,那用什么来间隔表示一个独立的存储过程语句呢?
//在存储过程语句开始前将接受符号修改成“$$”,在存储过程语句结束再修改成分号(;) DELIMITER $$ ...存储过程语句 DELIMITER ;
除了结束符号的问题,还有参数写在括号内后面紧接着写特性,写完特性就写SQL语句?理论上还是不错,但是真的是这样吗?要是这样存储过程在服务内岂不是还需要进行一个复杂的语法分析?这种损耗性能的行为怎么可能出现在数据库程序中,在存储过程中将SQL语句使用BEGIN ... END包裹起来,这就好比一对标签告诉服务这是SQL语句。来看看下面这个简单的示例:
#创建存储过程 delimiter $$ create procedure proce_employee_sal(in comparison float) comment '查询所有雇员工资' begin select sal from t_employee where sal>comparison; end$$ delimiter ; #执行存储过程 call proce_employee_sal(1800);
3.存储函数
存储函数与存储过程基本类似,都是用来处理一组SQL语句的数据操作,但两者的用途在适应场景上有些区别,通常查询一组数据使用存储过程(一组数据存储函数无法返回,最后返回的是空),查询单个数据使用存储函数(这里使用返回数据比查询应该更合理一点),为什么有这样的区别这里不深入解析,这涉及的内容不是一两句讲的清楚的,主要是我现在也将不明白。。。皮一下,淡定,但可以肯定的是这么区分用途归根到底还是性能问题。用途上有一些差异,就必然会在语法结构上体现出来,下面来看看存储函数的语法:
CREATE FUNCTION function_name([function_parameter[,...]])
[characteristic...] routine_body
从简洁的语法上来看存储函数与存储过程基本没有区别,但是存储函数的参数function_parameter有一些区别:
//存储函数参数的语法 parameter_name type
与存储过程对比存储函数不需要标注参数的输入输出,只需要写参数名称和类型,这是因为存储函数使用return来返回(输出)数据。虽然没有参数类型,但是需要在特性内写返回值的数据类型(RETURNS type)。然后就是执行回调函数使用的关键字不是call,而是select。看下面这个简单的示例:
#创建存储函数 delimiter $$ drop function if exists func_employee_sal; create function func_employee_sal() returns float comment '查询雇员工资' begin return (select sal from t_employee where ename="SMITH"); end $$ delimiter ; #执行存储函数 select func_employee_sal();
4.关于存储过程和函数的表达式
在一开始就说过存储过程是用来处理多条SQL语句的,在存储过程和存储函数内处理复杂的数据操作,还需要操作变量、操作游标、流程控制、临时表、操作条件。
4.1操作变量
#声明变量:var_name--变量名称、type--变量的类型、DEFAULT-默认值,如果没有该语句默认为null DECLARE var_name[,...] type [DEFAULT value] #手动赋值赋值变量:参数expr表示变量赋值的表达式 SET var_name=expr[,...] #通过查询数据赋给变量:在SELECT查询语句中使用INTO实现变量赋值 SELECT field INTO var_name [,...] ....
操作变量示例:
delimiter $$ drop procedure if exists procedure_cs; CREATE PROCEDURE procedure_cs() begin declare employee_sal float default 1000; declare num int ; select sal into employee_sal from t_employee where empno=7369; set num = 100; select employee_sal,num; end $$ delimiter ; call procedure_cs();