【jdbc/metadata】利用表的元数据创建一个同构新表


【需求】

提供一个源表名和目的表名,要求目的表的字段全照源表构建,创建时遇到同名表则将其删除。

【源表】

create table emp_from_10(
    id number(12),
    f1 nvarchar2(10),
    f2 nvarchar2(10),
    f3 nvarchar2(10),
    f4 nvarchar2(10),
    f5 nvarchar2(10),
    f6 nvarchar2(10),
    f7 nvarchar2(10),
    f8 nvarchar2(10),
    f9 nvarchar2(10)
);

【代码】

package com.hy.lab;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;


class Field{
    String name;
    String type;
    int length;
}
public class SameTableCreator {
    //-- 以下为连接Oracle数据库的四大参数
    private static final String DRIVER = "oracle.jdbc.driver.OracleDriver";
    private static final String URL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
    private static final String USER = "luna";
    private static final String PSWD = "1234";

    /**
     * 完全按源表的字段,建一个新表出来
     * @param destTableName
     * @param srcTableName
     * @return
     */
    public void makeSameTable(String destTableName,String srcTableName){

        Connection conn = null;
        PreparedStatement pstmt = null;

        try{
            String sql=String.format("select * from %s where 1=2",srcTableName);

            Class.forName(DRIVER);
            conn = DriverManager.getConnection(URL, USER, PSWD);
            pstmt = conn.prepareStatement(sql);
            // 核心语句,取得查询的元数据
            ResultSetMetaData rsmd=pstmt.executeQuery().getMetaData();

            // 获得源表字段信息
            List fields=new ArrayList<>();
            for(int i=0;i){
                int index=i+1;
                String columnName=rsmd.getColumnName(index);
                String columnType=rsmd.getColumnTypeName(index);
                int columnLength=rsmd.getColumnDisplaySize(index);

                Field field=new Field();
                field.name=columnName;
                field.type=columnType;
                field.length=columnLength;
                fields.add(field);

                //String msg=String.format("columnName=%s,columnType=%s,columnLength=%d",columnName,columnType,columnLength);
                //System.out.println(msg);
            }

            if(isTableExist(destTableName,conn)){
                String dropSql=String.format("drop table %s",destTableName);
                pstmt.executeQuery(dropSql);
                System.out.println("droped");
            }

            // 组合创建语句
            StringBuilder sb=new StringBuilder();
            sb.append(String.format("create table %s(",destTableName));
            List ls=new ArrayList<>();
            for(Field field:fields){
                ls.add(String.format("   %s %s(%d)",field.name, field.type, field.length));
            }
            String columnBundle=String.join(",",ls);
            sb.append(columnBundle);
            sb.append(")");

            String createSql=sb.toString();
            System.out.println(createSql);

            // 建表
            pstmt.executeQuery(createSql);
            System.out.println("created");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                pstmt.close();
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 看表是否存在 注意函数中将表名大写的处置
     * @param tablename
     * @param conn
     * @return
     * @throws Exception
     */
    private boolean isTableExist(String tablename,Connection conn) throws Exception{
        DatabaseMetaData meta= conn.getMetaData();

        ResultSet set=meta.getTables(null,null,tablename.toUpperCase(),null);
        if(set.next()){
            return true;
        }

        return false;
    }

    public static void main(String[] args){
        SameTableCreator creator=new SameTableCreator();
        creator.makeSameTable("emp_from_10_317","emp_from_10");
    }
}

输出:

droped
create table emp_from_10_317(   ID NUMBER(13),   F1 NVARCHAR2(10),   F2 NVARCHAR2(10),   F3 NVARCHAR2(10),   F4 NVARCHAR2(10),   F5 NVARCHAR2(10),   F6 NVARCHAR2(10),   F7 NVARCHAR2(10),   F8 NVARCHAR2(10),   F9 NVARCHAR2(10))
created

虽然id字段比源表的id字段多了一位,但无伤大雅,客户可以接受。

【DESC建成表】

SQL> desc emp_from_10_317;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER(13)
 F1                                                 NVARCHAR2(10)
 F2                                                 NVARCHAR2(10)
 F3                                                 NVARCHAR2(10)
 F4                                                 NVARCHAR2(10)
 F5                                                 NVARCHAR2(10)
 F6                                                 NVARCHAR2(10)
 F7                                                 NVARCHAR2(10)
 F8                                                 NVARCHAR2(10)
 F9                                                 NVARCHAR2(10)

END

相关