计算机二级MySQL——简单应用题(事件视图) 事件从MySQL 5.1起事件开始被支持。 它可以通过 MySQL 服务器中一个非常有特色的功能模块一一事件调度器 (Event Scheduler进行监视并判断其是否需要被调用。 事件调度器可以在指定的时刻执行某些特定的任务并以此可取代原先只能由操作系统的计划任务来执行的工作。这种需要在指定的时刻才被执行的某些特定任务就是事件这些特定任务通常是一些确定的 SQL 语句。目前MySQL 的事件调度器可以精确到每秒钟执行一个任务这对于一些对数据实时性要求较高的应用非常适合如股票、赔率和比分等。事件和触发器相似都是在某些事情发生的时候启动因此事件也可称为临时触发器temporal trigger。其中事件是基于特定时间周期触发来执行某些任务而触发器是基于某张表所产生的事件触发的它们的区别也在于此。在使用事件调度器功能之前必须确保 MySQL 中 EVENT_SCHEDULER 已被开启。这可通过执行如下 MySQL 命令语句来查看当前是否已开启事件调度器mysql SHOW VARIABLES LIKE EVENT_SCHEDULER:或者查看系统变量mysql SELECT EVENT_SCHEDULER;如若没有被开启可通过执行如下 MySQL 命令语句来开启该功能。mysqlSETCLOBAL EVENT_SCHEDULER1;//或mysqlSETCLOBAL EVENT_SCHEDULERTRUE再或者可以在 MySQL 的配置文件 my.ini 中加上EVENT_SCHEDULER1 或 SET GLOBAL EVENT SCHEDULERON 来开启。创建事件在MySQL 5.5中事件可以通过 CREATE EVENT 语句来创建其语法格式为CREATEEVENT[IFNOTEXISTS]event_nameONSCHEDULE schedule[ENABLE|DISABLE|DISABLEONSLAVE]DOevent_body其中schedule 的语法格式为ATtimestamp[INTERVALinterval]...|EVERY interva[STARTStimestamp[INTERVALinterval]...][ENDStimestamp[INTERVALinterval]...]interval 的语法格式为quantity|YEAR|QUARTER|MONTH|DAY|HOUR|MINUTE|WEEK|SECOND|YEAR_MONTH|DAY_HOUR|DAY_MINUTE|DAY_SECOND|HOUR_MINUTE|HOUR_SECOND|MINUTE_SECOND主要语法说明如下event name指定事件名前面可以添加关键字 IF NOT EXISTS 来修饰。schedule时间调度用于指定事件何时发生或者每隔多久发生一次分别对应下面两条子句①AT子句用于指定事件在某个时刻发生。其中timestamp 表示一个具体的时间点后面可以加上一个时间间隔表示在这个时间间隔后事件发生interval 表示这个时间间隔由一个数值和单位构成quantity 是间隔时间的数值。②EVERY子句用于表示事件在指定时间区间内每间隔多长时间发生一次。其中STARTS 子句用于指定开始时间ENDS 子句用于指定结束时间。event_bodyDo 子句中的 event_body 部分用于指定事件启动时所要求执行的代码。如果包含多条语句可以使用 BEGIN…END 复合结构。ENABLE | DISABLE | DISABLE ON SLAVE为可选项表示事件的一种属性。其中关键字 ENABLE 表示该事件是活动的活动意味着调度器检查事件动作是否必须调用关键字 DISABLE 表示该事件是关闭的关闭意味着事件的声明存储到目录中但是调度器不会检查它是否应该调用关键字 DISABLE ON SLAVE 表示事件在从机中是关闭的。如果不指定这三个选项中的任何一个则在一个事件创建之后它立即变为活动的。修改事件在MySQL 5.5中事件被创建之后可以通过使用 ALTER EVENT 语句来修改其定义和相关属性其语法格式为ALTEREVENT event_name T[ONSCHEDULE schedule][RENAMETOnew_event_name][ENABLE|DISABLE|DISABLEONSLAVE][DOevent_body]ALTER EVENT 语句与 CREATE EVENT 语句使用的语法相似。用户可以使用一条 ALTER EVENT 语句让一个事件关闭或再次让其活动。需要注意的是一个事件最后一次被调用后它是无法被修改的因为此时它已不存在了。删除事件在MySQL 5.5中可以使用 DROP EVENT 语句删除已创建的事件其语法格式为DROP EVENT [ IF EXISTS ] event_name例1DELIMITER$$CREATEEVENT ev_bookONSCHEDULE EVERY1DAYSTARTS2017-01-01 01:00:00DOBEGINUPDATEtb_bookingSETflag4WHEREpdateCURDATE()-1andflag1;END$$DELIMITER;空处①第二行EVENT②第二行DAY③第八行1flag 1④第九行$$例2DELIMITER$$//临时改变结束符结束符设置为$$CREATEEVENT ev_groupONSCHEDULE EVERY1MONTH//创建名为ev_group的事件时间调度为每月一次//CREATE EVENT [ IF NOT EXISTS ] event_name ON SCHEDULE scheduleSTARTS CURDATE()INTERVAL1MONTHDOBEGINSELECTsno,snameFROMtb_studentWHEREsnoNOTIN(SELECTsnoFROMtb_gs)INTOOUTFILEc:/tmp.txtFIELDSTERMINATEDBY,;//SELECT...INTO OUTFILE file_name TERMINATED BY stringEND$$//触发器体结束并用 $$ 表示整个定义结束DELIMITER;//恢复结束符为 ;空处①第二行SCHEDULE②第三行STARTS③第六行NOT IN④第六行snosno FROM tb_gs⑤第六行INTO导出备份语句 SELECT INTO…OUTFILE 的语法格式为SELECT * INTO OUTFILE file_name [ CHARACTER SET charset_name ] export_options | INTO DUMPFILE file_name例3DELIMITER$$//临时改变结束符结束符设置为$$CREATEEVENT ev_bakONSCHEDULE EVERY1DAY//创建名为ev_bak的事件时间调度为每日//CREATE EVENT [ IF NOT EXISTS ] event_name ON SCHEDULE scheduleDOBEGINSELECT*FROMtb_studentINTOOUTFILEbakfile.txtFIELDSTERMINATEDBY,;//指定字段值之间的符号为,END$$//触发器体结束并用 $$ 表示整个定义结束DELIMITER;//恢复结束符为 ;空处①第二行EVENT②第二行EVERY③第五行tb_student视图视图是从一张或多张表或者视图中导出的表它也包含一系列带有名称的数据列和若干条数据行。然而视图不同于数据库中真实存在的表其区别在于视图不是数据库中真实的表而是一 张虚拟表其结构和数据是建立在对数据库中真实表的查询基础上的。视图的内容是由存储在数据库中进行查询操作的 SQL 语句来定义的它的列数据与行数据均来自定义视图的查询所引用的真实表也称基础表、基表或源表或者是基于真实表的计算值并且这些数据是在引用视图时动态生成的。视图不是以数据集的形式存储在数据库中。它所对应的数据实际上是存储在视图所引用的真实表 基础表中。视图是用来查看存储在别处的数据的一种设施其自身并不存储数据。尽管视图与数据库中的表存在着本质上的不同但视图一经定义后可以如同使用表一样对视图进行查询以及受限的修改、删除和更新等操作。并且使用视图具有如下一些优点①集中分散数据。当用户所需的数据分散在数据库的多张表中时通过定义视图可以将这些数据集中在一起以方便用户对分散数据的集中查询与处理。②简化查询语句。定义视图可为用户屏蔽数据库的复杂性使其不必详细了解数据库中复杂的表结构和表连接因而能简化用户对数据库的查询语句。例如即便是底层数据库表发生了更改也不会影响上层用户对数据库的正常使用只需数据库编程人员重新定义视图的内容即可。这也正是使用外模式以及模式和外模式之间映射的目的。实际上视图的查询定义就是模式和外模式之间的映射关系。这样一来依据数据外模式编写的应用程序就不用修改从而保证了数据与程序的逻辑独立性。③重用 SQL 语句。视图提供的是一种对查询操作的封装它本身不包含数据其所呈现的数据是根据视图的定义从基础表中检索出来的若基础表中的数据被新增或更改视图所呈现的则是更新后的数据。因此通过定义视图编写完所需查询后可以方便地重用该视图而不了解它的具体查询细节。④保护数据安全。通过只授予用户使用视图的权限而不具体指定使用表的权限来保护基础数据的安全性。 因为通过视图用户只能查询和修改他们所能见到的数据数据库中的其他数据则既看不见也取不到。 数据库授权命令可以使每位用户对数据库的检索限制到特定的数据库对象上但不能授权到数据库的特定行上。 通过视图用户可以被限制在数据库的不同子集上。使用权可被限制在基表的行的子集上。⑤共享所需数据。 通过视图每位用户不必都定义和存储自己所需的数据可以共享数据库中的数据从而同样的数据只需存储一次。⑥更改数据格式。 通过视图可以重新格式化检索出的数据并组织输出到其他应用程序中去。创建视图在 MySQL 5.5 中可以使用 CREATE VIEW 语句来创建视图其语法格式为CREATE[ORREPLACE]VIEWview_name[(column_list)]ASSELECT_statement[WITH[CASCADED|LOCAL]CHECKOPTION]主要语法说明如下OR REPLACE可选项用于指定 OR REPLACE 子句。该语句用于替换数据库中已有的同名视图但需要在该视图上具有 DROP 权限。view_name指定视图的名称。该名称在数据库中必须是唯一的不能与其他表或视图同名。column_list这条可选子句可以为视图中的每个列指定明确的名称。其中列名的数目必须等于 SELECT 语句检索出的结果数据集的列数并且每个列名间用逗号分隔。如若省略 coIumn_list 子句则新建视图使用与基础表或源视图中相同的列名。SELECT_statement用于指定创建视图的 SELECT 语句。这条 SELECT 语句给出了视图的定义它可用于查询多张基础表或源视图。对于 SELECT 语句的指定存在以下一些限制①定义视图的用户除了要求被授于 CREATE VIEW 的权限外还必须被授予可以操作视图所涉及的基础表或其他视图的相关权限。②SELECT 语句不能包含 FROM 子句中的子查询。③SELECT语句不能引用系统变量或用户变量。④SELECT 语句不能引用预处理语句参数。⑤在 SELECT 语句中引用的表或视图必须存在。但是创建完视图后可以删除视图定义中所引用的基础表或源视图。若想检查视图定义是否存在这类问题可使用 CHECK TABLE 语句。⑥如若 SELECT 语句中所引用的不是当前数据库的基础表或源视图时需要在该表或视图前加上数据库的名称作为限定前缀。⑦在由 SELECT 语句构造的视图定义中允许使用 ORDER BY 子句。但是如果从特定视图进行了选择而该视图使用了自己的 ORDER BY 语句则视图定义中的 ORDER BY 子句将被忽略。⑧对于 SELECT 语句中的其他选项或子句若所创建的视图中也包含了这些选项则语句执行效果未定义。例如如果在视图定义中包含了 LIMIT 子句而 SELECT 语句也使用了自己的 LIMIT 子句那么 MySQL 对使用哪一条 LIMIT 语句未做定义。• WITH CHECK OPTION这条可选子句用于指定在可更新视图上所进行的修改都需要符合 select_statement 中所指定的限制条件这样可以确保数据修改后仍可以通过视图看到修改后的数据。当视图是根据另一个视图定义时WITH CHECK OPTION 给出两个参数即 CASCADED 和 LOCAL它们决定检查测试的范围。其中关键字 CASCADED 为选项默认值它会对所有视图进行检查而关键字 LOCAL 则使 CHECK OPTION 只对定义的视图进行检查。修改视图定义在 MySQL 5.5中可以使用 ALTER VIEW 语句来对已有视图的定义结构进行修改其语法格式为ALTERVIEWview_name[(columnlist)]ASSELECTstatement[WITH[CASCADED|LOCAL]CHECKOPTION]ALTER VIEW 语句的语法与 CREATE VIEW 类似但需要注意的是对于 ALTER VIEW 语句的使用需要用户具有针对视图的 CREATE VIEW 和 DROP 权限以及由 SELECT 语句选择的每一列上的某些权限。另外修改视图的定义也可以通过先使用 DROP VIEW 语句再使用 ALTER VIEW 语句的过程来实现还可以直接使用 CREATE OR REPLACE VIEW 语句来实现。若使用 CREATE OR REPLACE VIEW 语句则当要修改的视图不存在时该语句会创建一个新的视图而当要修改的视图存在时该语句会替换原有视图重新构造一个修改后的视图定义。删除视图在 MySQL 5.5中可以使用 DROP VIEW 语句来删除视图其语法格式为DROP VIEW [ IF EXISTS ]view_name [,view_name]...view_name指定要被删除的视图名。 使用 DROP VIEW 语句可以 一次删除多个视图但必须在每个视图上都拥有 DROP 权限。• IF EXISTS可选项用于防止因删除不存在的视图而出错。 若在 DROP VIEW 语句中没有给出该关键字则当指定的视图不存在时系统会发生错误。例1USEJY;//指定为当前数据库CREATEVIEWv_student//创建名为v_student的视图ASSELECT*FROMstudentWHEREstudent.stu_idIN(SELECTreading.stu_noFROMreading,bookWHEREreading.book_nobook.book_idANDbook.book_name高等数学);空处①第二行VIEW②第四行*③第六行IN④第六行book