作为一个后端的新手,在之前的一个项目开发中,遇到了一个比较头疼的问题,因为是管理系统,据客户要求基本上每个列表都需要有导入导出功能,其中导出并不需要头疼,只要将数据按照顺序写入EXCEL中即可,可是在写导入的时候确实遇到了一个头疼的问题,因为是用户自己导入EXCEL,你永远不知道里面会出现什么数据,若是导入比较多,中间有数据无法插入导致报错就会导致后续所有数据都导入失败,在此之前的一个项目因为导入字段较少,在导入的时候一一判断,原本拿到项目也打算这么写,可是实战下来发现这个方法在数据比较多的时候一一判断很不实际,映像最深刻的是用户的导入,EXCEL读取到的字段一共有45个字段,去除不用担心无法插入的和主键还有大约40个左右,若按照以往老方法写判断可以想象判断函数会有多长。
思前想后之后决定写一个函数进行简单的varchar(**) 和 常用的date decimal类型的字段和不可为空的字段进行判断,按照原本的想法这个功能不可能这么久没有懒(大)人(神)解决过,而且Symfony功能一如以往的强大,应该有人解决过此类问题,可惜百度不可靠,Google自己英文水平不够,之后只能自己想办法解决。
第一方案是从获取数据字典的方法里找到的一个SQL语句
$sql = "SHOW COLUMNS FROM = ?";
$res_columns = $conn->fetchAll($sql, array($table_name));
[
此SQL 可以获取table_name 表中字段名Field 类型Type(PS:varchar(255)) 是否可为空 Null 原本也是这么解决利用循环判断是否可以插入,但是写到最后发现在报错的语句方面比较难处理,无法获得字段备注这个确实比较麻烦,之后再次百度找到这样一句SQL
$sql = "SELECT COLUMN_NAME, DATA_TYPE AS `数据类型`, CHARACTER_MAXIMUM_LENGTH AS `字符长度`, NUMERIC_PRECISION AS `数字长度`, NUMERIC_SCALE AS `小数位数`, IS_NULLABLE AS `是否允许非空`, CASE WHEN EXTRA = "auto_increment" THEN 1 ELSE 0 END AS `是否自增`, COLUMN_DEFAULT AS `默认值`, COLUMN_COMMENT AS `备注` FROM information_schema.COLUMNS WHERE TABLE_NAME = ?";
$res_columns = $conn->fetchAll($sql, array($table_name));
这个SQL正好也解决了之前varchar需要处理出里面定义的长度的问题,最终写出的方法为
/**
* 判断字符串是否可以插入数据库
*
* @param $data
* @param $table_name
* @param array $field_name 自定义字段备注 array("name"=>"姓名")
* @return array
*/
public function sqlJudgeChar($data,$table_name,$field_name = array())
{
$conn = $this->get("database_connection");
$sql = "SELECT COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH AS LENGTH,NUMERIC_PRECISION,COLUMN_COMMENT,IS_NULLABLE FROM information_schema.COLUMNS WHERE TABLE_NAME = ?";
$res_columns = $conn->fetchAll($sql, array($table_name));
if (!empty($res_columns)){
foreach ($res_columns as $key=>$value){
foreach ($data as $k=>$v){
if ($k == $value["COLUMN_NAME"]){
if (isset($field_name[$k])){
$value["COLUMN_COMMENT"] = $field_name[$k];
}
if ($value["IS_NULLABLE"] === "NO" && empty($v)){ //判断是否输入完全
return array("errorCode"=>1, "message"=>"请输入" . $value["COLUMN_COMMENT"]);
}
if (strpos($value["DATA_TYPE"], "varchar") !== false){ //判断varchar
if ($this->getLength($v) > $value["LENGTH"] ){
return array("errorCode"=>1, "message"=>$value["COLUMN_COMMENT"] . "输入过长");
}
}elseif (strpos($value["DATA_TYPE"], "date") !== false){ //判断date
if (!strtotime($v)){
return array("errorCode"=>1, "message"=>$value["COLUMN_COMMENT"] . "输入不是日期格式,请检查输入是否正确");
}
}elseif (strpos($value["DATA_TYPE"], "decimal") !== false){ //判断decimal
if (!is_numeric($v) || $v < 0){ return array("errorCode"=>1, "message"=>$value["COLUMN_COMMENT"] . "必须大于零且只能为数字");
}
if ($this->getLength($v) > $value["NUMERIC_PRECISION"]){
return array("errorCode"=>1, "message"=>$value["COLUMN_COMMENT"] . "输入过大");
}
}
}
}
}
}else{
return array("errorCode"=>1, "message"=>"表名错误");
}
}
若是数据库备注字段有误可以通过$field_name进行自定义,当然也只需将需要自定义的字段名在$field_name中的对应即可,此方法还没有完善,对于提示语句也比较死板,对于一些特殊情况也无法进行判断,也希望哪位找到已经成熟的方法可以告知一下笔者。万分感谢
http://m.bbyears.com/jiaocheng/111307.html
推荐访问: