3 视图 索引 存储过程与函数 |
3.1 视图 |
视图是建立在一个或者多个表上面通过子查询建立的投影 视图本身是不包含任何数据的,视图的数据全部来自基表 基表的数据更改则视图数据更改 视图的数据修改其实是在修改基表数据 视图可以进行多视图的连接查询
Create view view名 (各列别名)AS 查询语句 视图如果有别名,通过别名进行列的操作
Drop view view名
Show tables; Show create view view名 Select * from information_schema.views
|
3.2 索引 |
主键索引 外键索引 全文索引 普通索引
查看索引 show index from 表名 删除索引 drop index index名 on 表名 全文检索 搜索引擎为MyISAM 支持频率在50%以下的单词检索,不区分大小写 CREATE TABLE `tt1` ( `id` int(11) DEFAULT NULL, `title` text, `content` text, FULLTEXT KEY `title` (`title`,`content`) ) ENGINE=MyISAM DEFAULT CHARSET=gbk
select * from tt1 where match(title,content) against ('mysql');
|
3.3 存储过程与函数 |
存储函数与存储过程的区别: 存储函数不能拥有输出参数;必须添加return; 存储函数可直接调用,且不需使用call语句,而存储过程的调用必须使用call语句; 存储函数中必须包含一条return语句,而这条特殊的SQL语句不允许包含于存储过程。
存储过程 mysql> delimiter // mysql> CREATE PROCEDURE simpleproc (OUT param1 INT) -> BEGIN -> SELECT COUNT(*) INTO param1 FROM t; -> END -> // Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ; mysql> CALL simpleproc(@a); Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @a; +------+ | @a | +------+ | 3 | +------+ 1 row in set (0.00 sec)
函数 mysql> delimiter // mysql> CREATE FUNCTION hello (s CHAR(20) charset utf8) RETURN S CHAR(50) -> RETURN CONCAT('Hello, ',s,'!'); -> // Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> SELECT hello('world'); -- 字符串要加单引号 +----------------+ | hello('world') | +----------------+ | Hello, world! | +----------------+ 1 row in set (0.00 sec)
示例:建立存储函数:根据给定的cust_id返回客户所在的州名(缩写),若库中无给定的cust_id,则返回“不存在该客户”。
->delimiter // ->create function fn_search(c_id int) ->returns varchar(50) -- 定义返回的数据类型,与函数部分中的数据类型需统一,如函数中的“不存在该客户”为6个字符,如果这里设置为char(5),则无法输出该结果 ->deterministic – 表示对于相同的输入值,返回值也相同 ->begin ->declare state char(2); -- 声明一个变量state,作为输出的州变量 ->select cust_state from customers where cust_id=c_id into state; ->if state is null then ->return(select ’不存在该客户’); --注意这里return不用加s ->else ->return(select state); ->end if; ->end; ->// -- 执行存储函数 ->select fn_search(10001);
显示 mysql> SHOW procedure status; mysql> SHOW function status;
mysql> SHOW CREATE FUNCTION test.hello\G mysql> SHOW FUNCTION STATUS LIKE 'hello'\G 练习: 查找对应姓名雇员的奖金,如果奖金高于500,就显示‘表现优秀‘,否则继续努力’ delimiter // CREATE PROCEDURE pr5(IN NAME CHAR(20) charset gbk ) BEGIN SELECT SAL,IF(SAL>50,'表现不错','继续努力') 评语,ENAME FROM emp WHERE ENAME=NAME; END// delimiter ; CALL pr5('jack');
delimiter // CREATE FUNCTION f7(NAME CHAR(20) charset gbk) RETURNS char(50) charset gbk BEGIN DECLARE result char(50) charset gbk; DECLARE s DOUBLE; SELECT emp.SAL INTO s FROM emp WHERE ename=name; IF s>500 THEN SET result=CONCAT(name,' 表现不错 ,奖金',s); ELSE SET result=CONCAT(name,' 继续努力 ,奖金',s); END IF; RETURN result; END// delimiter ; SELECT f7('jack'); |
3.4 触发器 |
触发器:MySQL响应insert、delete、update语句时自动执行的一条MySQL语句,创建触发器时需要给出的4条信息:唯一的触发器名、触发器相关的表、触发器应该响应的活动(insert 、delete、update)、触发器何时执行(处理前或处理后)。 1 insert触发器:当对表插入数据时起作用,只能用after 建立insert触发器 SHOW CREATE TRIGGER tr2; DROP TRIGGER tr2; CREATE TRIGGER tr2 AFTER INSERT ON emp FOR EACH ROW BEGIN INSERT INTO emp_log VALUES (null,NOW(),'insert'); END 执行insert触发器 INSERT INTO emp VALUES('0012','张三','销售','00002','2015-09-09',9000,700,'03'); 2 delete触发器:当对表删除数据时起作用,只能用after 同时返回奖金高于500的人数 建立 delete触发器 CREATE TRIGGER tr3 AFTER DELETE ON emp FOR EACH ROW BEGIN INSERT INTO emp_log VALUES (null,NOW(),'delete'); call pro(); END 执行delete触发器 delete from emp where ename=’jack’; 3 update触发器:当对表修改数据时起作用,同时含有new和old两个虚拟表。结合New可访问更新行的记录;结合old可访问更新前行的记录,可用after,也可用before
练习: 建立一个update触发器, 如果更新后的comm大于2000,则2000作为comm create trigger tr_u BEFORE update on emp for each row begin if new.comm>2000 then set new.comm=2000; end if; insert into emp_log values(now(),'update'); end
UPDATE emp set comm=comm*2 WHERE comm>500;
SELECT * from emp; 4 删除触发器:drop trigger trg_name; 5 查看触发器:show triggers; |
3.5 事件 |
1 事件简介 事件(event)是MySQL在相应的时刻调用的过程式数据库对象。一个事件可调用一次,也可周期性的启动,它由一个特定的线程来管理的,也就是所谓的“事件调度器”。 事件和触发器类似,都是在某些事情发生的时候启动。当数据库上启动一条语句的时候,触发器就启动了,而事件是根据调度事件来启动的。由于他们彼此相似,所以事件也称为临时性触发器。 事件取代了原先只能由操作系统的计划任务来执行的工作,而且MySQL的事件调度器可以精确到每秒钟执行一个任务,而操作系统的计划任务(如:Linux下的CRON或Windows下的任务计划)只能精确到每分钟执行一次。
优点 一些对数据定时性操作不再依赖外部程序,而直接使用数据库本身提供的功能。可以实现每秒钟执行一个任务,这在一些对实时性要求较高的环境下就非常实用了。 缺点 定时触发,不可以调用。
一条create event语句创建一个事件。每个事件由两个主要部分组成,第一部分是事件调度(event schedule),表示事件何时启动以及按什么频率启动,第二部分是事件动作(event action ),这是事件启动时执行的代码,事件的动作包含一条SQL语句,它可能是一个简单地insert或者update语句,也可以使一个存储过程或者benin...end语句块,这两种情况允许我们执行多条SQL。不支持DDL语句 一个事件可以是活动(打开)的或停止(关闭)的,活动意味着事件调度器检查事件动作是否必须调用,停止意味着事件的声明存储在目录中,但调度器不会检查它是否应该调用。在一个事件创建之后,它立即变为活动的,一个活动的事件可以执行一次或者多次。
当一个使用 ON COMPLETION NOT PRESERVE 属性定义的事件最后一次执行后,事件直接就不存在了,不能修改。
.查看:show variables like ’event_scheduler’; .开启:set global event_scheduler=1;
CREATE EVENT EVENT_NAME ON SCHEDULE schedule DO event_body; 其中schedule的语法格式为 AT timestamp [+INTERVAL interval]…|every interval -- 指定事件执行的时间,可以为某时刻点即timestamp,或某时刻点开始的interval时间后,或者为每隔interval时间执行一次 [starts timestamp [+INTERVAL interval]] -- 设置事件开始执行的时间 [ends timestamp [+INTERVAL interval]] -- 设置事件终止执行的时间
-- 建立一个事件,用于每分钟向elog表中插入一条数据“now()、’event’”,该事件从5分钟后开始并于20分钟后结束 ->delimiter // -> CREATE EVENT `NewEvent` ON SCHEDULE EVERY 1 MINUTE STARTS CURRENT_TIMESTAMP ENDS CURRENT_TIMESTAMP + INTERVAL 20 MINUTE ON COMPLETION NOT PRESERVE ENABLE DO insert into elog values(now(),'event');; ->// (2)修改事件,用于修改时间的状态:alter event event_name {enable|disable}; (3)删除事件:drop event event_name; (4)查看事件:show events
5分钟后将emp_log 这张表 复制到 emp_log_old 并且将emp_log_old备份到D盘
grant file on *.* to root@localhost;在命令行中进行 CREATE EVENT `NewEvent` ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 5 MINUTE ON COMPLETION PRESERVE ENABLE DO Insert into emp_log_old SELECT * FROM emp_log; select * from emp_log_old into outfile 'd:\2.txt';; |
补充:流程控制语句IF, CASE, LOOP, WHILE, ITERATE, LEAVE |
1. 查询每个学生学号、 学生姓名、 课程名称、 成绩 (成绩大于60时的显示及格,小于60时的显示不及格) Select stu.SID, stu.SName, `subject`.SubName, select_subject.Grade < 60 AS '不及格', select_subject.Grade > 60 AS '及格' from stu,select_subject,`subject` WHERE stu.SID = select_subject.StuID and select_subject.SubID= `subject`.SubID;
IF Select stu.SID, stu.SName, `subject`.SubName,if( select_subject.Grade < 60,'不及格','及格') AS '成绩' from stu,select_subject,`subject` WHERE stu.SID = select_subject.StuID and select_subject.SubID= `subject`.SubID;
CASE Select stu.SID, stu.SName, `subject`.SubName, case select_subject.Grade < 60 WHEN 1 THEN'不及格' WHEN 0 THEN '及格' else '成绩为空'END AS '成绩' from stu,select_subject,`subject` WHERE stu.SID = select_subject.StuID and select_subject.SubID= `subject`.SubID;
ELT Select stu.SID, stu.SName, `subject`.SubName, ELT((select_subject.Grade < 60)+1,'及格','不及格') '成绩' from stu,select_subject,`subject` WHERE stu.SID = select_subject.StuID and select_subject.SubID= `subject`.SubID
LOOP, ITERATE CREATE PROCEDURE doiterate(p1 INT) BEGIN label1: LOOP SET p1 = p1 + 1; IF p1 < 10 THEN ITERATE label1; ELSE END IF; LEAVE label1; END LOOP label1; SET @x = p1; END
REPEAT mysql> CREATE PROCEDURE dorepeat(p1 INT) -> BEGIN -> SET @x = 0; -> REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT; -> END -> // mysql> CALL dorepeat(1000)// mysql> SELECT @x//
WHILE CREATE PROCEDURE dowhile() BEGIN DECLARE v1 INT DEFAULT 5; WHILE v1 > 0 DO ... SET v1 = v1 - 1; END WHILE; END |
数据库(视图、索引、存储过程与函数)
最新推荐文章于 2025-06-30 20:06:04 发布