数据库(视图、索引、存储过程与函数)

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

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值