【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<Field> fields=new ArrayList<>();
            for(int i=0;i<rsmd.getColumnCount();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<String> 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

 

posted @   逆火狂飙  阅读(114)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2020-03-17 实验:模糊查询会使普通索引失效吗?
2020-03-17 位图索引对单表查询效率的影响(使用解释计划评估)
2020-03-17 查看加在一张表上的索引
2020-03-17 用解释计划评估创建索引后对单表查询效率的影响
2019-03-17 【Canvas与游戏】空战游戏1.18
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东
点击右上角即可分享
微信分享提示