过程式数据库对象.ppt
《过程式数据库对象.ppt》由会员分享,可在线阅读,更多相关《过程式数据库对象.ppt(58页珍藏版)》请在三一办公上搜索。
1、第7章 过程式数据库对象,7.1 存储过程,7.2 存储函数,7.3 触发器,7.4 事件,7.1 存储过程,使用存储过程的优点有:(1)存储过程在服务器端运行,执行速度快。(2)存储过程执行一次后,其执行规划就驻留在高速缓冲存储器,在以后的操作中,只需从高速缓冲存储器中调用已编译好的二进制代码执行,提高了系统性能。(3)确保数据库的安全。使用存储过程可以完成所有数据库操作,并可通过编程方式控制上述操作对数据库信息访问的权限。,7.1.1 创建存储过程,创建存储过程可以使用CREATE PROCEDURE语句。要在MySQL 5.1中创建存储过程,必须具有CREATE ROUTINE权限。要想
2、查看数据库中有哪些存储过程,可以使用SHOW PROCEDURE STATUS命令。要查看某个存储过程的具体信息,可使用SHOW CREATE PROCEDURE sp_name命令,其中sp_name是存储过程的名称。CREATE PROCEDURE的语法格式:CREATE PROCEDURE sp_name(proc_parameter,.)characteristic.routine_body其中,proc_parameter的参数如下:IN|OUT|INOUT param_name typecharacteristic特征如下:LANGUAGE SQL|NOT DETERMINISTI
3、C|CONTAINS SQL|NO SQL|READS SQL DATA|MODIFIES SQL DATA|SQL SECURITY DEFINER|INVOKER|COMMENT string说明:sp_name:存储过程的名称,默认在当前数据库中创建。需要在特定数据库中创建存储过程时,则要在名称前面加上数据库的名称,格式为:db_name.sp_name。值得注意的是,这个名称应当尽量避免取与MySQL的内置函数相同的名称,否则会发生错误。,7.1.1 创建存储过程,proc_parameter:存储过程的参数,param_name为参数名,type为参数的类型,当有多个参数的时候中间用
4、逗号隔开。存储过程可以有0个、1个或多个参数。MySQL存储过程支持三种类型的参数:输入参数、输出参数和输入/输出参数,关键字分别是IN、OUT和INOUT。输入参数使数据可以传递给一个存储过程。当需要返回一个答案或结果的时候,存储过程使用输出参数。输入/输出参数既可以充当输入参数也可以充当输出参数。存储过程也可以不加参数,但是名称后面的括号是不可省略的。注意:参数的名字不要等于列的名字,否则虽然不会返回出错消息,但是存储过程中的SQL语句会将参数名看做列名,从而引发不可预知的结果。characteristic:存储过程的某些特征设定,下面一一介绍。LANGUAGE SQL:表明编写这个存储过
5、程的语言为SQL语言,目前来讲,MySQL存储过程还不能用外部编程语言来编写,也就是说,这个选项可以不指定。将来将会对其扩展,最有可能第一个被支持的语言是PHP。DETERMINISTIC:设置为DETERMINISTIC表示存储过程对同样的输入参数产生相同的结果,设置为NOT DETERMINISTIC则表示会产生不确定的结果。默认为NOT DETERMINISTIC。CONTAINS SQL:表示存储过程不包含读或写数据的语句。NO SQL表示存储过程不包含SQL语句。READS SQL DATA表示存储过程包含读数据的语句,但不包含写数据的语句。MODIFIES SQL DATA表示存储
6、过程包含写数据的语句。如果这些特征没有明确给定,默认的是CONTAINS SQL。,7.1.1 创建存储过程,SQL SECURITY:SQL SECURITY特征可以用来指定存储过程使用创建该存储过程的用户(DEFINER)的许可来执行,还是使用调用者(INVOKER)的许可来执行。默认值是DEFINER。COMMENT string:对存储过程的描述,string为描述内容。这个信息可以用SHOW CREATE PROCEDURE语句来显示。routine_body:这是存储过程的主体部分,也叫做存储过程体。里面包含了在过程调用的时候必须执行的语句,这个部分总是以BEGIN开始,以END结
7、束。当然,当存储过程体中只有一个SQL语句时可以省略BEGIN-END标志。在开始创建存储过程之前,先介绍一个很实用的命令,即DELIMITER命令。在MySQL中,服务器处理语句的时候是以分号为结束标志的。但是在创建存储过程的时候,存储过程体中可能包含多个SQL语句,每个SQL语句都是以分号为结尾的,这时服务器处理程序的时候遇到第一个分号就会认为程序结束,这肯定是不行的。所以这里使用DELIMITER命令将MySQL语句的结束标志修改为其他符号。DELIMITER语法格式为:DELIMITER$说明:$是用户定义的结束符,通常这个符号可以是一些特殊的符号,如两个“#”,两个“¥”等。当使用D
8、ELIMITER命令时,应该避免使用反斜杠(“”)字符,因为那是MySQL的转义字符。,7.1.1 创建存储过程,【例7.1】将MySQL结束符修改为两个斜杠“/”符号。DELIMITER/说明:执行完这条命令后,程序结束的标志就换为双斜杠符号“/”了。用下列语句检验一下:SELECT 姓名 FROM XS WHERE 学号=081101/结果为:,要想恢复使用分号“;”作为结束符,运行下面命令即可:DELIMITER;【例7.2】下面是一个存储过程的简单例子,实现的功能是删除一个特定学生的信息。DELIMITER$CREATE PROCEDURE DELETE_STUDENT(IN XH C
9、HAR(6)BEGINDELETE FROM XS WHERE 学号=XH;END$DELIMITER;说明:当调用这个存储过程时,MySQL根据提供的参数XH的值,删除对应在XS表中的数据。调用存储过程的命令是CALL命令,后面会讲到。在关键字BEGIN和END之间指定了存储过程体,当然,BEGIN-END复合语句还可以嵌套使用,下面就来介绍存储过程体的内容。,7.1.2 存储过程体,1.局部变量在存储过程中可以声明局部变量,它们可以用来存储临时结果。要声明局部变量必须使用DECLARE语句。在声明局部变量的同时也可以对其赋一个初始值。DECLARE语法格式如下:DECLARE var_na
10、me,.type DEFAULT value说明:var_name为变量名;type为变量类型;DEFAULT子句给变量指定一个默认值,如果不指定默认为NULL的话。【例7.3】声明一个整型变量和两个字符变量。DECLARE num INT(4);DECLARE str1,str2 VARCHAR(6);说明:局部变量只能在BEGINEND语句块中声明。局部变量必须在存储过程的开头就声明,声明完后,可以在声明它的BEGINEND语句块中使用该变量,其他语句块中不可以使用它。前面已经学习过用户变量,在存储过程中也可以声明用户变量,不过千万不要将这两个混淆。局部变量和用户变量的区别在于:局部变量前
11、面没有使用符号,局部变量在其所在的BEGINEND语句块处理完后就消失了,而用户变量存在于整个会话当中。,7.1.2 存储过程体,2.使用SET语句赋值要给局部变量赋值可以使用SET语句,SET语句也是SQL本身的一部分。语法格式为:SET var_name=expr,var_name=expr.【例7.4】在存储过程中给局部变量赋值。SET num=1,str1=hello;说明:与声明用户变量时不同,这里的变量名前面没有符号。声明用户变量的方法已经介绍过,这里不再举例。注意,例中的这条语句无法单独执行,只能在存储过程和存储函数中使用。3.SELECT.INTO语句 使用这个SELECTIN
12、TO语法可以把选定的列值直接存储到变量中。因此,返回的结果只能有一行。语法格式为:SELECT col_name,.INTO var_name,.table_expr说明:col_name是列名,var_name是要赋值的变量名。table_expr是SELECT语句中的FROM子句及后面的部分,这里不再叙述。【例7.5】在存储过程体中将XS表中的学号为081101的学生姓名和专业名的值分别赋给变量name和project。SELECT 姓名,专业名 INTO name,project FROM XS;WHERE 学号=081101;,7.1.2 存储过程体,4.流程控制语句在MySQL中,常
13、见的过程式SQL语句可以用在一个存储过程体中。例如:IF语句、CASE语句、LOOP语句、WHILE语句、ITERATE语句和LEAVE语句。(1)IF语句IF-THEN-ELSE语句可根据不同的条件执行不同的操作。语法格式为:IF search_condition THEN statement_listELSEIF search_condition THEN statement_list.ELSE statement_listEND IF说明:search_condition是判断的条件,statement_list中包含一个或多个SQL语句。当search_condition的条件为真时,
14、就执行相应的SQL语句。IF语句不同于系统的内置函数IF()函数,IF()函数只能判断两种情况,所以请不要混淆。,7.1.2 存储过程体,【例7.6】创建XSCJ数据库的存储过程,判断两个输入的参数哪一个更大。DELIMITER$CREATE PROCEDURE XSCJ.COMPAR(IN K1 INTEGER,IN K2 INTEGER,OUT K3 CHAR(6)BEGINIF K1K2 THENSET K3=大于;ELSEIF K1=K2 THENSET K3=等于;ELSE SET K3=小于;END IF;END$DELIMITER;说明:存储过程中K1和K2是输入参数,K3是输出
15、参数。(2)CASE语句CASE语句在节介绍选择列的时候已经涉及。这里介绍CASE语句在存储过程中的用法,与之前略有不同。,7.1.2 存储过程体,语法格式为:CASE case_value WHEN when_value THEN statement_list WHEN when_value THEN statement_list.ELSE statement_listEND CASE或者:CASE WHEN search_condition THEN statement_list WHEN search_condition THEN statement_list.ELSE statemen
16、t_listEND CASE说明:一个CASE语句经常可以充当一个IF-THEN-ELSE语句。第一种格式中case_value是要被判断的值或表达式,接下来是一系列的WHEN-THEN块,每一块的when_value参数指定要与case_value比较的值,如果为真,就执行statement_list中的SQL语句。如果前面的每一个块都不匹配就会执行ELSE块指定的语句。CASE语句最后以END CASE结束。第二种格式中CASE关键字后面没有参数,在WHEN-THEN块中,search_condition指定了一个比较表达式,表达式为真时执行THEN后面的语句。与第一种格式相比,这种格式能
17、够实现更为复杂的条件判断,使用起来更方便。,7.1.2 存储过程体,【例7.7】创建一个存储过程,针对参数的不同,返回不同的结果。DELIMITER$CREATE PROCEDURE XSCJ.RESULT(IN str VARCHAR(4),OUT sex VARCHAR(4)BEGIN CASE strWHEN M THEN SET sex=男;WHEN F THEN SET sex=女;ELSE SET sex=无;END CASE;END$DELIMITER;【例7.8】用第二种格式的CASE语句创建以上存储过程。程序片段如下:CASE WHEN str=M THEN SET sex=
18、男;WHEN str=F THEN SET sex=女;ELSE SET sex=无;END CASE;,7.1.2 存储过程体,(3)循环语句MySQL支持3条用来创建循环的语句:WHILE、REPEAT和LOOP语句。在存储过程中可以定义0个、1个或多个循环语句。WHILE语句语法格式为:begin_label:WHILE search_condition DOstatement_listEND WHILE end_label说明:语句首先判断search_condition是否为真,不为真则执行statement_list中的语句,然后再次进行判断,为真则继续循环,不为真则结束循环。be
19、gin_label和end_label是WHILE语句的标注。除非begin_label存在,否则end_label不能被给出,并且如果两者都出现,它们的名字必须是相同的。【例7.9】创建一个带WHILE循环的存储过程。DELIMITER$CREATE PROCEDURE dowhile()BEGIN DECLARE v1 INT DEFAULT 5;WHILE v1 0 DO SET v1=v11;END WHILE;END$DELIMITER;,7.1.2 存储过程体,说明:当调用这个存储过程时,首先判断v1的值是否大于零,如果大于零则执行v11,否则结束循环。REPEAT语句格式如下:b
20、egin_label:REPEAT statement_listUNTIL search_conditionEND REPEAT end_label说明:REPEAT语句首先执行statement_list中的语句,然后判断search_condition是否为真,为真则停止循环,不为真则继续循环。REPEAT也可以被标注。【例7.10】用REPEAT语句创建一个如例7.9的存储过程。程序片段如下:REPEAT v1=v11;UNTIL v11;END REPEAT;说明:REPEAT语句和WHILE语句的区别在于:REPEAT语句先执行语句,后进行判断;而WHILE语句是先判断,条件为真时才
21、执行语句。,7.1.2 存储过程体,LOOP语句语法格式如下:begin_label:LOOP statement_listEND LOOP end_label说明:LOOP允许某特定语句或语句群的重复执行,实现一个简单的循环构造,statement_list是需要重复执行的语句。在循环内的语句一直重复至循环被退出,退出时通常伴随着一个LEAVE 语句。LEAVE语句经常和BEGIN.END或循环一起使用。结构如下:LEAVE labellabel是语句中标注的名字,这个名字是自定义的。加上LEAVE关键字就可以用来退出被标注的循环语句。【例7.11】创建一个带LOOP语句的存储过程。DELI
22、MITER$CREATE PROCEDURE doloop()BEGIN SET a=10;Label:LOOP SET a=a1;IF a0 THEN LEAVE Label;END IF;END LOOP Label;END$DELIMITER;,7.1.2 存储过程体,说明:语句中,首先定义了一个用户变量并赋值为10,接着进入LOOP循环,标注为Label,执行减1语句,然后判断用户变量a是否小于零,是则使用LEAVE语句跳出循环。我们调用此存储过程来查看最后结果。调用该存储过程使用如下命令:CALL doloop();接着,查看用户变量的值:SELECT a;结果为:,可以看到,用户变
23、量a的值已经变成1了。循环语句中还有一个ITERATE语句,它只可以出现在LOOP、REPEAT和WHILE语句内,意为“再次循环”。它的格式为:ITERATE label说明:该语句格式与LEAVE差不多,区别在于:LEAVE语句是离开一个循环,而ITERATE语句是重新开始一个循环。,7.1.2 存储过程体,在存储过程中处理SQL语句可能导致一条错误消息。例如,向一个表中插入新的行而主键值已经存在,这条INSERT语句会导致一个出错消息,并且MySQL立即停止对存储过程的处理。每一个错误消息都有一个唯一代码和一个SQLSTATE代码。例如,SQLSTATE 23000属于如下的出错代码:E
24、rror 1022,Cant write;duplicate key in tableError 1048,Column cannot be nullError 1052,Column is ambiguousError 1062,Duplicate entry for keyMySQL手册的“错误消息和代码”一章中列出了所有的出错消息及它们各自的代码。为了防止MySQL在一条错误消息产生时就停止处理,需要使用到DECLARE HANDLER语句。DECLARE HANDLER语句为错误代码声明了一个所谓的处理程序,它指明:对一条SQL语句的处理如果导致一条错误消息,将会发生什么。DECLAR
25、E HANDLER语法格式为:DECLARE handler_type HANDLER FOR condition_value,.sp_statement,7.1.2 存储过程体,其中,handler_type为:CONTINUE|EXIT|UNDOcondition_value为:SQLSTATE VALUE sqlstate_value|condition_name|SQLWARNING|NOT FOUND|SQLEXCEPTION|mysql_error_code说明:handler_type:处理程序的类型,主要有三种:CONTINUE、EXIT和UNDO。对CONTINUE处理程序,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程式 数据库 对象
链接地址:https://www.31ppt.com/p-6207986.html