【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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需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