最新消息:文章中包含代码时,请遵守代码高亮规范!

Symfony下关于数据库数据插入的判断【原创】

PHP Pota 1438浏览 1评论

作为一个后端的新手,在之前的一个项目开发中,遇到了一个比较头疼的问题,因为是管理系统,据客户要求基本上每个列表都需要有导入导出功能,其中导出并不需要头疼,只要将数据按照顺序写入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://blog.it985.com/18333.html


pay_weixin
pay_weixin
微信打赏
pay_weixin
支付宝打赏
感谢您对作者Pota的打赏,我们会更加努力!    如果您想成为作者,请点我

您必须 登录 才能发表评论!

网友最新评论 (1)

  1. Jay
    😳 学习了
    Jay2016-09-30 17:50