excel转sql:

excel下载:https://moozik.cn/code/xls2sql.xlsm

暂不支持字符编码、索引、引擎、某些特殊初期值。

做这个东西完全是为了方便更新表结构文档。

设计为vba脚本,在excel中按照以下格式设计数据表,点击按钮即可生成建表sql语句。

 

No. 伦理名 物理名 主键 非空 类型 长度 初期值 备考

以下为注意事项。

[使用方法]
1、左侧填写表名和列名相关数据,点击按钮,下方出现建表语句
2、“初期值”为空等同默认为NULL,与“非空”互斥
3、“初期值”为auto意为自增选项
4、“初期值”的两个双引号意为空字符串
5、并未进行严格check,请按照规范填写
6、“伦理名”为空即认为此行为空
7、枚举类型需要在“长度”中填写带单引号的数据

sql转excel:

工具地址:http://moozik.cn/code/sql2xls.php

因为sql转excel比较复杂,所以就使用php和正则来实现解析。同样忽略了编码和索引。

本身的建表语句是从navicate的表属性中查看到的,就以此为标准来匹配,比较严格的地方为,会使用 explode(",\n", ...) 来分割各项,所以不符合此项格式皆不能正常使用,或许以后会改进,但是目前够我使用了。

php部分代码:

if(!empty($_POST['sql_in'])){
    $res = sql_analysis($_POST['sql_in']);
    echo json_encode($res);
    exit;
}
//return array
function sql_analysis($sql_text){
    $table = array(
        'table_name'=>'',
        'flag'=>'0',
        'message'=>'',
        'column'=>array(
        )
    );

    preg_match_all("/CREATE TABLE `([a-z0-9_]+)`/",$sql_text,$res);
    if(empty($res[1][0])){
        $table['message'] = '获取表名失败';
        return $table;
    }else{
        $table['table_name']=$res[1][0];
    }
    preg_match_all("/\(.*\)/s",$sql_text,$res);
    if(empty($res[0][0])){
        $table['message'] = '获取表中项目失败';
        return $table;
    }else{
        $column_string = explode(",\n",rtrim(ltrim($res[0][0],'('),')'));
    }
    $t_1_reg = "/^(tinyint|smallint|mediumint|int|bigint|bit|char|varchar|year|binary|varbinary)\((\d+)\)/";
    $t_2_reg = "/^(double|decimal)\(([\d ]+,[\d ]+)\)/";
    $t_3_reg = "/^(enum|set)\(('.*?')\)/";
    $t_4_reg = "/^(float|date|time|timestamp|datetime|tinyblob|blob|mediumblob|longblob|tinytext|text|mediumtext|longtext|point|linestring|polygon|geometry|multipoint|multilinestring|multipolygon|geometrycollection)/";
    $defualt_reg = "/^DEFAULT ('.*?'|NULL)|^(AUTO_INCREMENT)/";
    
    $col_list = array();
    foreach($column_string as $key=>$item){
        $colarr = array(
                'name_cn'=>'',//中文名
                'name'=>'',//列名
                'primary'=>'',//是否为主键
                'notnull'=>'',//null
                'data_type'=>'',//数据类型
                'data_type_len'=>'',//数据长度以及小数位以及枚举数据
                'defualt'=>'',//初期值
                'comment'=>'',//备注
        );

        //忽略编码设置
        $column = trim(preg_replace("/CHARACTER SET \w+|COLLATE \w+/",'',$item));

        //忽略索引
        if(preg_match("/^KEY/",$column)){
            continue;
        }

        //判断主键
        preg_match_all("/^PRIMARY KEY \((.*?)\)$/",$column,$res);
        if(!empty($res[1][0])){
            //过滤“`”和“ ”
            $res = explode(',',preg_replace("/[ `]+/",'',$res[1][0]));
            foreach($col_list as $col_name=>$tmp_arr){
                if(in_array($col_name,$res)){
                    $col_list[$col_name]['primary'] = '○';
                }else{
                    $col_list[$col_name]['primary'] = '';
                }
            }
            break;
        }

        //匹配列名
        preg_match_all("/^`([a-z0-9_]+)`/",$column,$res);
        if(empty($res[1][0])){
            $table['message'] = '获取列名失败'.$item;
            return $table;
        }else{
            $colarr['name'] = $res[1][0];
        }
        $column = trim(preg_replace("/^`[a-z0-9_]+`/","",$column));

        //解析类型
        preg_match_all($t_1_reg,$column,$res);
        $column = trim(preg_replace($t_1_reg,'',$column));
        if(empty($res[0][0])){
            preg_match_all($t_2_reg,$column,$res);
            $column = trim(preg_replace($t_2_reg,'',$column));
        }
        if(empty($res[0][0])){
            preg_match_all($t_3_reg,$column,$res);
            $column = trim(preg_replace($t_3_reg,'',$column));
        }
        if(empty($res[0][0])){
            preg_match_all($t_4_reg,$column,$res);
            $column = trim(preg_replace($t_4_reg,'',$column));
        }
        $colarr['data_type'] = $res[1][0];
        if(!empty($res[2][0])){
            $colarr['data_type_len'] = $res[2][0];
        }else{
            $colarr['data_type_len'] = '';
        }

        //不为NULL
        if(preg_match("/^NOT NULL/",$column)){
            $colarr['notnull'] = '○';
            $column = trim(preg_replace("/^NOT NULL/",'',$column));
        }else{
            $colarr['notnull'] = '';
        }
        
        //初期值
        // 1、如果“不为null”为○,那么此项不能为null或空
        // 2、区别空字符和未设置
        preg_match_all($defualt_reg,$column,$res);
        if(
            count($res[0]) != 0
            and
            ($res[1][0]=="NULL" or empty($res[1][0]))  and empty($res[2][0]) and $colarr['notnull']=='○'
        ){
            $table['message'] = "'{$colarr['name']}'的“不为NULL”与“初期值”冲突";
            return $table;
        }
        if(count($res[0]) == 0){
            $colarr['defualt'] = '';
        }else if($res[1][0]=='NULL'){
            $colarr['defualt'] = 'NULL';
        }else if($res[1][0]=="''"){
            $colarr['defualt'] = '""';
        }else if($res[2][0]=="AUTO_INCREMENT"){
            $colarr['defualt'] = 'AUTO';
        }else{
            $colarr['defualt'] = str_replace("'",'',$res[1][0]);
        }
        $column = trim(preg_replace($defualt_reg,'',$column));

        //备注
        if(empty($column)){
            $colarr['comment'] = '';
            $colarr['name_cn'] = $colarr['name'];
        }else{
            preg_match_all("/^COMMENT '(.*?)'/",$column,$res);
            if(isset($res[1][0])){
                $tmp = explode("--",$res[1][0],2);
                //如果存在--,那么前半部分为名称,后半部分为备注
                if(count($tmp)==2){
                    $colarr['comment'] = $tmp[1];
                }else{
                    $colarr['comment'] = $tmp[0];
                }
                //如果小于9个utf-8字符,那么设置为中文名称
                if(mb_strlen($tmp[0],'utf-8')<9){
                    $colarr['name_cn'] = $tmp[0];
                }else{
                    $colarr['name_cn'] = $colarr['name'];
                }
            }else{
                $colarr['name_cn'] = $colarr['name'];
            }
        }
        $col_list[$colarr['name']] = $colarr;
    }
    $table['flag'] = '1';
    $table['column'] = $col_list;
    return $table;
}

 

最后修改:2021 年 01 月 12 日
如果觉得我的文章对你有用,请随意赞赏