3 视图 索引 存储过程与函数 |
3.1 视图 |
视图是建立在一个或者多个表上面通过子查询建立的投影 视图本身是不包含任何数据的,视图的数据全部来自基表 基表的数据更改则视图数据更改 视图的数据修改其实是在修改基表数据 视图可以进行多视图的连接查询 Create view view名 (各列别名)AS 查询语句 视图如果有别名,通过别名进行列的操作 Drop view view名
Show tables;
Show create view view名
Select * from information_schema.views
|
3.2 索引 |
主键索引 外键索引 全文索引 普通索引
1. create index idx_名 ON emp(empno,ename);
2. alter table emp add index(empno,ename);
3. create table emp(empno int,ename char(10),index(empno,ename));
查看索引 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下的任务计划)只能精确到每分钟执行一次。 2 事件的优缺点 优点 一些对数据定时性操作不再依赖外部程序,而直接使用数据库本身提供的功能。可以实现每秒钟执行一个任务,这在一些对实时性要求较高的环境下就非常实用了。 缺点 定时触发,不可以调用。 3 创建事件 一条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
|