mysql存储过程.doc_第1页
mysql存储过程.doc_第2页
mysql存储过程.doc_第3页
mysql存储过程.doc_第4页
mysql存储过程.doc_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

MySQL存储过程1.存储过程简介我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(StoredProcedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。一个存储过程是一个可编程的函数,它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式。存储过程通常有以下优点:(1).存储过程增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。(2).存储过程允许标准组件是编程。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。(3).存储过程能实现较快的执行速度。如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。(4).存储过程能过减少网络流量。针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织程存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。(5).存储过程可被作为一种安全机制来充分利用。系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。2.关于MySQL的存储过程存储过程是数据库存储的一个重要的功能,但是MySQL在5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣。好在MySQL5.0终于开始已经支持存储过程,这样即可以大大提高数据库的处理速度,同时也可以提高数据库编程的灵活性。3.MySQL存储过程的创建(1).格式MySQL存储过程创建的格式:CREATE PROCEDURE过程名(过程参数,.)procedure特性.过程体这里先举个例子:mysqlDELIMITER/mysqlCREATEPROCEDUREproc1(OUTsint)-BEGIN-SELECTCOUNT(*)INTOsFROMuser;-END-/mysqlDELIMITER;注:(1)这里需要注意的是DELIMITER/和DELIMITER;两句,DELIMITER是分割符的意思,因为MySQL默认以;为分隔符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字申明当前段分隔符,这样MySQL才会将;当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。(2)存储过程根据需要可能会有输入、输出、输入输出参数,这里有一个输出参数s,类型是int型,如果有多个参数用,分割开。(3)过程体的开始与结束使用BEGIN与END进行标识。这样,我们的一个MySQL存储过程就完成了,是不是很容易呢?看不懂也没关系,接下来,我们详细的讲解。(2).声明分割符delimiter分隔符delimiter/其实,关于声明分割符,上面的注解已经写得很清楚,不需要多说,只是稍微要注意一点的是:如果是用MySQL的Administrator管理工具时,可以直接创建,不再需要声明。(3).参数MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT,形式如:CREATEPROCEDURE(IN|OUT|INOUT参数名数据类形.)CREATEPROCEDURE(in)输入参数参数值由外向procedure内传即外面给个值,里面获得,但仅单向传递值,即内部改变传不到外部。CREATEPROCEDURE(out)输出参数外部定的参数值不能传到内部,但内部参数可传单外部。IN输入参数:表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值OUT输出参数:该值可在存储过程内部被改变,并可返回INOUT输入输出参数:调用时指定,并且可被改变和返回.IN参数例子创建:mysqlDELIMITER/mysqlCREATEPROCEDUREdemo_in_parameter(INp_inint)-BEGIN-SELECTp_in;/*查询输入参数*/-SETp_in=2;/*修改*/-SELECTp_in;/*查看修改后的值*/-END;-/mysqlDELIMITER;执行结果:mysqlSETp_in=1;mysqlCALLdemo_in_parameter(p_in);+-+|p_in|+-+|1|+-+-+|p_in|+-+|2|+-+mysqlSELECTp_in;+-+|p_in|+-+|1|+-+以上可以看出,p_in虽然在存储过程中被修改,但并不影响p_id的值.OUT参数例子创建:mysqlDELIMITER/mysqlCREATEPROCEDUREdemo_out_parameter(OUTp_outint)-BEGIN-SELECTp_out;/*查看输出参数*/-SETp_out=2;/*修改参数值*/-SELECTp_out;/*看看有否变化*/-END;-/mysqlDELIMITER;执行结果:mysqlSETp_out=1;mysqlCALLsp_demo_out_parameter(p_out);+-+|p_out|+-+|NULL|+-+/*未被定义,返回NULL*/+-+|p_out|+-+|2|+-+mysqlSELECTp_out;+-+|p_out|+-+|2|+-+.INOUT参数例子创建:mysqlDELIMITER/mysqlCREATEPROCEDUREdemo_inout_parameter(INOUTp_inoutint)-BEGIN-SELECTp_inout;-SETp_inout=2;-SELECTp_inout;-END;-/mysqlDELIMITER;执行结果:mysqlSETp_inout=1;mysqlCALLdemo_inout_parameter(p_inout);+-+|p_inout|+-+|1|+-+-+|p_inout|+-+|2|+-+mysqlSELECTp_inout;+-+|p_inout|+-+|2|+-+(4).变量.变量定义DECLAREvariable_name,variable_name.datatypeDEFAULTvalue;其中,datatype为MySQL的数据类型,如:int,float,date,varchar(length)例如:unsigned无符号整型的每一种都有无符号(unsigned)和有符号(signed)两种类型(float和double总是带符号的),在默认情况下声明的整型变量都是有符号的类型(char有点特别),如果需声明无符号类型的话就需要在类型前加上unsigned。无符号版本和有符号版本的区别就是无符号类型能保存2倍于有符号类型的数据,比如16位系统中一个int能存储的数据的范围为-3276832767,而unsigned能存储的数据范围则是065535。由于在计算机中,整数是以补码形式存放的。根据最高位的不同,如果是1,有符号数的话就是负数;如果是无符号数,则都解释为正数。同时在相同位数的情况下,所能表达的整数范围变大。另外,unsigned若省略后一个关键字,大多数编译器都会认为是unsignedint。在sql语句中的意义sql语句中,创建一个数据表时ceatetableuseruser_idintunsigned.当中的unsigned表示,数据项user_id恒为正整数。declare变量名称变量的数据类型约束条件;DECLAREl_intintunsigneddefault4000000;DECLAREl_numericnumber(8,2)DEFAULT9.95;DECLAREl_datedateDEFAULT1999-12-31;DECLAREl_datetimedatetimeDEFAULT1999-12-3123:59:59;5.DECLAREl_varcharvarchar(255)DEFAULTThiswillnotbepadded;.变量赋值SET变量名=表达式值,variable_name=expression.selectcol_name,.intovar_name,.fromtable条件实例:动态查询f_name,f_price给ruitname,和fruitprice赋值selectf_name,f_priceintofruitname,fruitpricefromfruitswheref_id=a1;.注释单行注释-多行注释/*/MySQL存储过程可使用两种风格的注释双模杠:-该风格一般用于单行注释c风格:/*注释内容*/一般用于多行注释流程控制使用1:if语句例10.14】IF语句的示例,代码如下:if()功能代码;else功能代码;条件语句:If语句:if(条件) then执行M end ifIf-then-else语句:If(条件) then执行MElse执行NEnd ifCase语句:case变量when1 then执行1when2 then执行2(类似于java中switch变量case1:执行1;case2:执行2)循环语句:Loop语句:标签:loop循环体判断语句thenleave标签Repeat语句:标签repeat循环体until判断语句endrepeat标签while条件 do 循环体;endwhile;IF val IS NULLTHEN SELECT valisNULL;ELSE SELECT valisnotNULL;END IF;.if-then-else语句mysqlDELIMITER/mysqlCREATEPROCEDUREproc2(INparameterint)-begin-declare(声明)varint;-setvar=parameter+1;-ifvar=0then-insertintotvalues(17);-endif;-ifparameter=0then-updatetsets1=s1+1;-else-updatetsets1=s1+2;-endif;-end;-/mysqlDELIMITER;【例10.15】使用CASE流程控制语句判断val值等于1、等于2,或者两者都不等,语句如下:delimiter/createprocedureprocase()begindeclarevalint;setval=1;casevalwhen1thenselectvalis1;when2thenselectvalis2;endcase;end/case变量when条件1then功能1;when条件2then功能2;endcase;CASEvalWHEN1THENSELECTvalis1;WHEN2THENSELECTvalis2;ELSESELECTvalisnot1or2;ENDCASE;mysqlDELIMITER/mysqlCREATEPROCEDUREproc3(inparameterint)-begin-declarevarint;-setvar=parameter+1;-casevar-when0then-insertintotvalues(17);-when1then-insertintotvalues(18);-else-insertintotvalues(19);-endcase;-end;-/mysqlDELIMITER;【例10.16】使用CASE流程控制语句判断val是否为空、小于0、大于0或者等于0,或者两者都不等,语句如下:CASEWHENvalISNULLTHENSELECTvalisNULL;WHENval0THENSELECTvalisgreaterthan0;ELSESELECTvalis0;ENDCASE;loop循环【例10.17】使用LOOP语句的进行循环操作,id值小于等于10之前,将重复执行循环过程,代码如下:DECLAREidINTDEFAULT0;add_loop:LOOPSETid=id+1;IFid10THENLEAVEadd_loop;ENDIF;ENDLOOPadd_loop;leave语句用来退出任何被标注的流程控制构造,leave语句的基本格式如下:leavelabeliterate语句将执行顺序转到语句开头处语法格式iteratelabeliterate只可以出现在loop,repeatwhile语句中iterate的意思是再次循环环label参数表示循环的标志。iterate语句必须跟在循环标志前面。mysqlDELIMITER/mysqlCREATEPROCEDUREproc6()-begin-declarevint;-setv=0;-LOOP_LABLE:loop-insertintotvalues(v);-setv=v+1;-ifv=5then-leaveLOOP_LABLE;-endif;-endloop;-end;-/mysqlDELIMITER;【例10.18】ITERATE语句示例,代码如下:CREATEPROCEDUREdoiterate()BEGINDECLAREp1INTDEFAULT0;my_loop:LOOPSETp1=p1+1;IFp120THENLEAVEmy_loop;ENDIF;SELECTp1isbetween10and20;ENDLOOPmy_loop;ENDmysqlDELIMITER/mysqlCREATEPROCEDUREproc10()-begin-declarevint;-setv=0;-LOOP_LABLE:loop-ifv=3then-setv=v+1;-ITERATELOOP_LABLE;-endif;-insertintotvalues(v);-setv=v+1;-ifv=5then-leaveLOOP_LABLE;-endif;-endloop;-end;-/mysqlDELIMITER;repeat语句创建一个带条件判断的循环过程,每次语句执行完毕之后,会对条件表达式进行判断,如果表达式为真,则循环环结束,否则重复执行循环中语句。repeat语法的基本格式如下:repeat_label:repeatstatement_listutilexpr_conditionendrepeatrepeat:label【例10.19】REPEAT语句示例,id值小于等于10之前,将重复执行循环过程,代码如下:repeat。功能代码,循环体until条件endrepeat;DECLAREidINTDEFAULT0;REPEATSETid=id+1;UNTILid=10ENDREPEAT;mysqlDELIMITER/mysqlCREATEPROCEDUREproc5()-begin-declarevint;-setv=0;-repeat-insertintotvalues(v);-setv=v+1;-untilv=5-endrepeat;-end;-/mysqlDELIMITER;【例10.20】WHILE语句示例,id值小于等于10之前,将重复执行循环过程,代码如下:while条件do循环体;endwhile;delimiter/createprocedureprocwhile()DECLAREiINTDEFAULT0;WHILEiDELIMITER/mysqlCREATEPROCEDUREproc4()-begin-declarevarint;-setvar=0;-whilevarinsertintotvalues(var);-setvar=var+1;-endwhile;-end;-/mysqlDELIMITER光标的使用查询语句可能返回多条记录,如果数据量非常大,需要在存储过程和存储函数中使用光标来逐条读取查询结果集中的记录。应用程序可以根据需要滚动或浏览其中的数据,本节将介绍如何声明,打开,使用关闭光标。声明光标:Declare cursor_name CURSORFOR select_statement例10.10】声明名称为cursor_fruit的光标,代码如下:DECLARE cursor_fruit CURSORFOR(粗略的) SELECTf_name,f_price FROM fruits;打开光标:Open cursor_name;【例10.11】打开名称为cursor_fruit的光标,代码如下:OPENcursor_fruit;使用光标:FETCH光标名称intovar_name,var_price;语法格式fetchcursor_nameintovar_name,var_price【例10.12】使用名称为cursor_fruit的光标。将查询出来的数据存入fruit_name和fruit_price这两个变量中,代码如下:FETCHcursor_fruitINTOfruit_name,fruit_price;关闭光标【例10.13】关闭名称为cursor_fruit的光标,代码如下:CLOSEcursor_fruit;定义条件和处理程序特定条件需要特定处理。这些条件可以联系到错误,以及子程序中一般流程控制。定义条件事先定义程序执行过程中遇到的问题,处理程序定义了在遇到这些问题是应当采取的处理方式,别且保证存储过程或函数在遇到警告或者错误时能继续执行。这样可以增强存储程序处理问题的能力,避免程序异常停止工作。定义条件Declare condition_nameconditionforcondition_typecondition_type:sqlstatevaluesqlstate_value|mysql_error_codesqlstate_value和mysql_error_code都可以表示MySQL的错误,sqlstate_value为长度为5的字符串类型的错误代码,mysql_error_code为类型错误代码:例如error1142(42000)中,sqlstate_value的值是:42000,my_error_code的值是1142【例10.7】定义ERROR1148(42000)错误,名称为command_not_allowed。可以用两种不同的方法来定义,代码如下:/方法一:使用sqlstate_valueDECLAREcommand_not_allowedCONDITIONFORSQLSTATE42000;/方法二:使用mysql_error_codeDECLAREcommand_not_allowedCONDITIONFOR1148【例10.8】定义处理程序的几种方式,代码如下:/方法一:捕获sqlstate_valueDECLARECONTINUEHANDLERFORSQLSTATE42S02SETinfo=NO_SUCH_TABLE;/方法二:捕获mysql_error_codeDECLARECONTINUEHANDLERFOR1146SETinfo=NO_SUCH_TABLE;/方法三:先定义条件,然后调用DECLAREno_such_tableCONDITIONFOR1146;DECLARECONTINUEHANDLERFORNO_SUCH_TABLESETinfo=NO_SUCH_TABLE;/方法四:使用SQLWARNINGDECLAREEXITHANDLERFORSQLWARNINGSETinfo=ERROR;/方法五:使用NOTFOUNDDECLAREEXITHANDLERFORNOTFOUNDSETinfo=NO_SUCH_TABLE;/方法六:使用SQLEXCEPTIONDECLAREEXITHANDLERFORSQLEXCEPTIONSETinfo=ERROR;【例10.9】定义条件和处理程序,具体执行的过程如下:CREATETABLEtest.t(s1int,primarykey(s1);DELIMITER/CREATEPROCEDUREhandlerdemo()BEGINDECLARECONTINUEHANDLERFORSQLSTATE23000SETx2=1;SETx=1;INSERTINTOtest.tVALUES(1);SETx=2;INSERTINTOtest.tVALUES(1);SETx=3;END;/DELIMITER;CALLhandlerdemo();/*调用存储过程*/SELECTx;/*查看调用过程结果*/存储函数:创建存储函数使用createfunction(存储函数参数列表)returns返回的数据类型return(selects_namefromsupplierswheres_call=48075);调用此存储函数select存储函数名称();delimiter/createfunctioncount()returnschar(50)return(selectcount(*)fromfruitswheres_id=103);/调用存储函数selectcount();MySQL存储过程的调用用call和你过程名以及一个括号,括号里面根据需要,加入参数,参数包括输入参数、输出参数、输入输出参数。具体的调用方法可以参看上面的例子。callproccedure_name(param);5.MySQL存储过程的查询我们像知道一个数据库下面有那些表,我们一般采用showtables;进行查看。那么我们要查看某个数据库下面的存储过程,是否也可以采用呢?答案是,我们可以查看某个数据库下面的存储过程,但是另一种方式。我们可以用Show procedure status;模糊查询某个数据库的存储过程Show procedure status likep%;进行查询。如果我们想知道,某个存储过程的详细,那我们又该怎么做呢?是不是也可以像操作表一样用describe表名进行查看呢?答案是:我们可以查看存储过程的详细,但是需要用另一种方法:SHOWCREATEPROCEDURE数据库.存储过程名;例如:查

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论