十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

mysql8基础(七)自定义函数和存储过程

mysql8基础(七)自定义函数和存储过程 自定义函数语法格式如图第一行是函数名和参数第二行是返回值类型必须有返回值并且是唯一结果再之后是函数体。下面创建一个单条语句函数CREATEFUNCTIONriqi()RETURNSVARCHAR(10)RETURN(SELECTDATE_FORMAT(CURDATE(),%Y%m%d));调用函数SELECTriqi()如果创建函数失败报错youmightwant to use the less safe log_bin_trust_function_creators variable 执行以下语句信任函数创建者放宽对存储函数确定性、数据访问特征和相应权限的限制SETGLOBALlog_bin_trust_function_creators1;上面的函数里只有一条语句那么多条语句该怎么弄下例用declare声明一个变量result然后把语句的结果传给result再返回resultCREATE FUNCTION riqi1()RETURNS VARCHAR (10)DECLARE result VARCHAR(10);SELECT DATE_FORMAT(CURDATE(),‘%Y%m%d’) INTO result;RETURN result;结果自然报错。这时候要用到BEGIN … END复合语句这是官方文档的解释存储子程序可以使用BEGIN … END复合语句来包含多个语句。statement_list 代表一个或多个语句的列表。statement_list之内每个语句都必须用分号来结尾。那就加入复合语句CREATE FUNCTION riqi1 ()RETURNS VARCHAR (10)BEGINDECLARE result VARCHAR(10);SELECT DATE_FORMAT(CURDATE(),‘%Y%m%d’) INTO result;RETURN result;END;还是报错为什么虽然用复合语句包裹住了多条语句但是sql中默认分号结尾当执行到第一个分号的时候就判定结束进行了提交报错自然难免了。在这种情况下我们就应该改变结束符比如以为结束符定义结束符的关键字是demiliter如下例DELIMITER!CREATEFUNCTIONriqi1()RETURNSVARCHAR(10)BEGINDECLAREresultVARCHAR(10);SELECTDATE_FORMAT(CURDATE(),%Y%m%d)INTOresult;RETURNresult;END!DELIMITER 并不是SQL 语法而是 mysql 客户端命令作用是临时改变客户端识别一条语句结束的位置使 BEGIN…END 内部可以继续使用分号。调用函数别忘了恢复默认结束符DELIMITER;SELECTriqi1()mysql有如下流程控制语句if、case、loop、while、repeat。IF语法格式IF search_condition THEN statement_list[ELSEIF search_condition THEN statement_list] …[ELSE statement_list]END IF示例DELIMITER!CREATEFUNCTIONif_eg(aINT)RETURNSVARCHAR(10)BEGINDECLAREsVARCHAR(10);IFa90THENSETs优;ELSEIFa80THENSETs良;ELSEIFa70THENSETs中;ELSESETs差;ENDIF;RETURNs;END!调用结果case语法格式CASEcase_valueWHENwhen_valueTHENstatement_list[WHENwhen_valueTHENstatement_list]...[ELSEstatement_list]ENDCASE或者CASEWHENsearch_conditionTHENstatement_list[WHENsearch_conditionTHENstatement_list]...[ELSEstatement_list]ENDCASE示例DELIMITER!CREATEFUNCTIONcase_eg(aINT)RETURNSVARCHAR(10)BEGINDECLAREsVARCHAR(10);CASETRUNCATE(a/10,0)WHEN10THENSETs优;WHEN9THENSETs优;WHEN8THENSETs良;WHEN7THENSETs中;ELSESETs差;ENDCASE;RETURNs;END!或者DELIMITER!CREATEFUNCTIONcase_eg1(aINT)RETURNSVARCHAR(10)BEGINDECLAREsVARCHAR(10);CASEWHENa90THENSETs优;WHENa80THENSETs良;WHENa70THENSETs中;ELSESETs差;ENDCASE;RETURNs;END!loop语句格式[begin_label:]LOOPstatement_listENDLOOP[end_label]循环用leave退出。示例求a以内的累加和DELIMITER!CREATEFUNCTIONloop_eg(aINT)RETURNSINTBEGINDECLAREnINTDEFAULT0;DECLAREsINTDEFAULT0;t1:LOOPSETnn1;SETssn;IFnaTHENLEAVEt1;ENDIF;ENDLOOPt1;RETURNs;END!调用结果也可以用iterate在循环内部再次循环DELIMITER!CREATEFUNCTIONloop_eg1(aINT)RETURNSINTBEGINDECLAREnINTDEFAULT0;DECLAREsINTDEFAULT0;t1:LOOPSETnn1;SETssn;IFnaTHENITERATEt1;ENDIF;LEAVEt1;ENDLOOPt1;RETURNs;END!while循环语句格式[begin_label:]WHILEsearch_conditionDOstatement_listENDWHILE[end_label]示例DELIMITER!CREATEFUNCTIONwhile_eg(aINT)RETURNSINTBEGINDECLAREnINTDEFAULT0;DECLAREsINTDEFAULT0;WHILEnaDOSETnn1;SETssn;ENDWHILE;RETURNs;END!repeat循环语句格式[begin_label:]REPEATstatement_list UNTIL search_conditionENDREPEAT[end_label]示例DELIMITER!CREATEFUNCTIONrepeat_eg(aINT)RETURNSINTBEGINDECLAREnINTDEFAULT0;DECLAREsINTDEFAULT0;REPEATSETnn1;SETssn;UNTIL naENDREPEAT;RETURNs;END!存储过程示例CREATEPROCEDURErq()SELECTDATE_FORMAT(CURDATE(),%y年%m月%d日)存储过程不指定返回类型无return关键字用call调用CALLrq()调用结果以上是单条语句多条语句和定义函数一样也是使用BEGIN … END,存储过程有三种参数IN、OUT、INOUT也就是输入、输出、输入和输出。下例传入参数a进行累加求和,然后返回累加和b.。DELIMITER//CREATEPROCEDUREtest1(INaINT,OUTbINT)BEGINDECLAREcINTDEFAULT0;SETb0;WHILEcaDOSETcc1;SETbbc;ENDWHILE;END//调用DELIMITER;CALLtest1(10,b);SELECTb;b是接收参数用来接收返回值。结果在刚才存储过程里面增加交换两个数字的功能DELIMITER//CREATEPROCEDUREtest2(INaINT,OUTbINT,INOUTiINT,INOUTjINT)BEGINDECLAREcINTDEFAULT0;DECLAREtINTDEFAULT0;SETb0;SETti;SETij;SETjt;WHILEcaDOSETcc1;SETbbc;ENDWHILE;END//调用DELIMITER;SETc10,d20;CALLtest2(10,b,c,d);SELECTb,c,d;结果函数和存储过程有哪些区别1.功能定位与限制不同存储过程适合封装复杂的业务逻辑限制较少可通过动态SQL间接执行DDL操作函数作为SQL表达式的一部分设计上更注重“输入-输出”的纯粹性通常不应包含DDL操作。。2.返回值不同存储过程可以返回 0 个或多个值通过 OUT 参数或结果集不强制返回函数必须返回一个标量值如 INT、VARCHAR 等且只能返回一个值。3.参数不同存储过程有in、out、inout类型而函数只有类似IN的参数。4.语法结构不同存储过程不指定返回类型可以有RETURN但用于提前退出函数必须指定返回类型且必须包含有效的RETURN语句返回一个值。5.调用方式不同存储过程用call调用是独立的可以在外部调用。自定义函数用select调用是sql的一部分在sql语句中调用。查看自定义函数和存储过程SHOWFUNCTIONSTATUS;SHOWPROCEDURESTATUS;
返回列表