mysql存数组的实例代码和方法
在很多的情况下,在编写存储过程中往往会用到数组,但是mysql中存储过程传入参数并没有可以直接传入数组的方法。在这种情况下我们只能退而求之或者说换个方式以字符串形式传入参数,然后在过程体中把字符串再转成数组?不过很遗憾告诉你,mysql并没有直接提供把字符串转数组的函数。现在你是不是有种想打人的感觉呢?不过,不用慌,此路不通,咱走另外的路,总有解决方法的。我们可以把传入的字符串截取成多个字符然后传入到临时表中,然后使用游标或者直接关联表过滤数据。这样就可以达到后面预期的效果了。
下面我们以一个例子来具体实践一下:
1、创建数据库,用于实例:
CREATEDATABASEhuafeng_db; usehuafeng_db; DROPTABLEIFEXISTS`huafeng_db`.`t_scores`; DROPTABLEIFEXISTS`huafeng_db`.`t_students`; DROPTABLEIFEXISTS`huafeng_db`.`t_class`; CREATETABLE`huafeng_db`.`t_class`(`class_id`int(11)NOTNULL,`class_name`varchar(32)CHARACTERSETutf8DEFAULTNULL, PRIMARYKEY(`class_id`) )ENGINE=InnoDBDEFAULTCHARSET=utf8; INSERTINTO`huafeng_db`.`t_class`(`class_id`,`class_name`)VALUES('1','一年级'); INSERTINTO`huafeng_db`.`t_class`(`class_id`,`class_name`)VALUES('2','二年级'); INSERTINTO`huafeng_db`.`t_class`(`class_id`,`class_name`)VALUES('3','三年级'); INSERTINTO`huafeng_db`.`t_class`(`class_id`,`class_name`)VALUES('4','四年级'); INSERTINTO`huafeng_db`.`t_class`(`class_id`,`class_name`)VALUES('5','五年级'); INSERTINTO`huafeng_db`.`t_class`(`class_id`,`class_name`)VALUES('6','六年级'); CREATETABLE`t_students`(`student_id`int(11)NOTNULLAUTO_INCREMENT,`student_name`varchar(32)NOTNULL,`sex`int(1)DEFAULTNULL,`seq_no`int(11)DEFAULTNULL,`class_id`int(11)NOTNULL, PRIMARYKEY(`student_id`), KEY`class_id`(`class_id`), CONSTRAINT`t_students_ibfk_1`FOREIGNKEY(`class_id`)REFERENCES`t_class`(`class_id`) )ENGINE=InnoDBDEFAULTCHARSET=utf8; INSERTINTO`huafeng_db`.`t_students`(`student_name`,`sex`,`seq_no`,`class_id`)VALUES('小红',0,1,'1'); INSERTINTO`huafeng_db`.`t_students`(`student_name`,`sex`,`seq_no`,`class_id`)VALUES('小青',0,2,'2'); INSERTINTO`huafeng_db`.`t_students`(`student_name`,`sex`,`seq_no`,`class_id`)VALUES('小明',1,3,'3'); INSERTINTO`huafeng_db`.`t_students`(`student_name`,`sex`,`seq_no`,`class_id`)VALUES('小兰',0,4,'4'); INSERTINTO`huafeng_db`.`t_students`(`student_name`,`sex`,`seq_no`,`class_id`)VALUES('小米',1,5,'5'); INSERTINTO`huafeng_db`.`t_students`(`student_name`,`sex`,`seq_no`,`class_id`)VALUES('小白',1,6,'6'); CREATETABLE`huafeng_db`.`t_scores`(`score_id`int(11)NOTNULLAUTO_INCREMENT,`course_name`varchar(64)DEFAULTNULL,`score`double(3,2)DEFAULTNULL,`student_id`int(11)DEFAULTNULL, PRIMARYKEY(`score_id`), KEY`student_id`(`student_id`), CONSTRAINT`t_scores_ibfk_1`FOREIGNKEY(`student_id`)REFERENCES`t_students`(`student_id`) )ENGINE=InnoDBAUTO_INCREMENT=3DEFAULTCHARSET=utf8; INSERTINTO`t_scores`(`score_id`,`course_name`,`score`,`student_id`)VALUES('1','语文','90','1'); INSERTINTO`t_scores`(`score_id`,`course_name`,`score`,`student_id`)VALUES('2','数学','97','1'); INSERTINTO`t_scores`(`score_id`,`course_name`,`score`,`student_id`)VALUES('3','英语','95','1'); INSERTINTO`t_scores`(`score_id`,`course_name`,`score`,`student_id`)VALUES('4','语文','92','2'); INSERTINTO`t_scores`(`score_id`,`course_name`,`score`,`student_id`)VALUES('5','数学','100','2'); INSERTINTO`t_scores`(`score_id`,`course_name`,`score`,`student_id`)VALUES('6','英语','98','2');
2、需求:根据学生编号批量删除学生信息
DROPPROCEDUREIFEXISTS`p_del_studentInfo_bySeqNo`; DELIMITER$$ CREATEPROCEDUREp_del_studentInfo_bySeqNo(INarrayStrVARCHAR(1000),INsSplitVARCHAR(10)) SQLSECURITYINVOKER#允许其他用户运行BEGINDECLAREe_codeINTDEFAULT0;#初始化报错码为0 DECLAREresultVARCHAR(256)CHARACTERsetutf8;#初始化返回结果,解决中文乱码问题 DECLAREarrLengthINTDEFAULT0;/*定义数组长度*/ DECLAREarrStringVARCHAR(1000);/*定义初始数组字符*/ DECLAREsStrVARCHAR(1000);/*定义初始字符*/ DECLARECONTINUEHANDLERFORSQLEXCEPTIONSETe_code=1;#遇到错误后继续执行;(需要返回执行结果时用这个) STARTTRANSACTION;#启动事务 SETarrLength=LENGTH(arrayStr)-LENGTH(REPLACE(arrayStr,sSplit,''));/*获得数组长度*/ SETarrString=arrayStr; DROPTEMPORARYTABLEIFEXISTSlist_tmp; createtemporarytablelist_tmp(idVARCHAR(32));/*定义临时表*/ WHILEarrLength>0DO setsStr=substr(arrString,1,instr(arrString,sSplit)-1);--得到分隔符前面的字符串 setarrString=substr(arrString,length(sStr)+length(sSplit)+1);--得到分隔符后面的字符串 setarrLength=arrLength-1; set@str=trim(sStr); insertintolist_tmp(id)values(@str); ENDWHILE;IFrow_count()=0THEN SETe_code=1; SETresult='请输入正确的参数'; ENDIF; set@count=(SELECTcount(1)FROMt_studentss,list_tmptWHEREs.seq_no=t.id);IF@count>0THEN DELETEFROMt_scoresWHEREstudent_idin(SELECTs.student_idFROMt_studentss,list_tmptWHEREs.seq_no=t.id); DELETEFROMt_studentsWHEREstudent_idin(SELECTt.idFROMlist_tmpt);ELSE SETe_code=1; SETresult='该学生不存在!'; ENDIF;IFe_code=1THEN ROLLBACK;#回滚 ELSE COMMIT; SETresult='该学生已被删除成功'; ENDIF; SELECTresult; DROPTEMPORARYTABLEIFEXISTSlist_tmp; END$$ DELIMITER;
说明:在创建存储过程的时候,传入了两个参数,第一个代表要传入的数组字符串形式,第二个参数为以什么分割字符串。
声明初始化变量
DECLAREarrLengthINTDEFAULT0;/*定义数组长度*/ DECLAREarrStringVARCHAR(1000);/*定义初始数组字符*/ DECLAREsStrVARCHAR(1000);/*定义初始字符*/
获取传入参数数组长度
SETarrLength=LENGTH(arrayStr)-LENGTH(REPLACE(arrayStr,sSplit,''));/*获得数组长度*/ SETarrString=arrayStr;/*赋值*/
创建临时表
DROPTEMPORARYTABLEIFEXISTSlist_tmp; createtemporarytablelist_tmp(idVARCHAR(32));/*定义临时表*/
截取数组字符串并依次存入到临时表中供后面业务使用
WHILEarrLength>0DO setsStr=substr(arrString,1,instr(arrString,sSplit)-1);--得到分隔符前面的字符串 setarrString=substr(arrString,length(sStr)+length(sSplit)+1);--得到分隔符后面的字符串 setarrLength=arrLength-1; set@str=trim(sStr); insertintolist_tmp(id)values(@str); ENDWHILE;
注:存储过程结束时一定要记得删除临时表
不是非常复杂的业务没有必要用到存储过程的,本文不是引导大家一定要使用存储过程,只是让大家知道有这么一回事!