如何从数据库中获取所有表名?

Posted

技术标签:

【中文标题】如何从数据库中获取所有表名?【英文标题】:How to get all table names from a database? 【发布时间】:2011-02-16 08:10:56 【问题描述】:

我想从数据库模式中检索所有表名,并且如果可能的话,获取所有以指定前缀开头的表。

我尝试使用 JDBC 的 connection.getMetaData().getTables(),但它根本不起作用。

Connection jdbcConnection = DriverManager.getConnection("", "", "");
DatabaseMetaData m = jdbcConnection.getMetaData();
ResultSet tables = m.getTables(jdbcConnection.getCatalog(), null, "TAB_%", null);
for (int i = 0; i < tables.getMetaData().getColumnCount(); i++) 
   System.out.println("table = " + tables.getMetaData().getTableName(i));

有人可以帮我解决这个问题吗?

【问题讨论】:

【参考方案1】:

您需要遍历调用 next() 的 ResultSet。

这是来自java2s.com的示例:

DatabaseMetaData md = conn.getMetaData();
ResultSet rs = md.getTables(null, null, "%", null);
while (rs.next()) 
  System.out.println(rs.getString(3));

3 列是TABLE_NAME(参见DatabaseMetaData::getTables 的文档)。

【讨论】:

如果这对您来说失败了(就像我一样),您需要确保数据库用户实际上可以在数据库中显示表。 显示所有数据库中的所有表。您可以将数据库名称作为第一个参数传递,以仅显示该数据库中的表。 对于 mysql,ResultSet rs = md.getTables(connection.getCatalog(), null, "%", new String [] "TABLE");只为您提供当前架构的表。 我们为什么要在这里给出 %?我们不应该使用“.*”之类的东西吗? @Pardhu:这不是正则表达式,% 在 SQL 中用作通配符。【参考方案2】:
 public void getDatabaseMetaData()
    
        try 

            DatabaseMetaData dbmd = conn.getMetaData();
            String[] types = "TABLE";
            ResultSet rs = dbmd.getTables(null, null, "%", types);
            while (rs.next()) 
                System.out.println(rs.getString("TABLE_NAME"));
            
         
            catch (SQLException e) 
            e.printStackTrace();
        
    

【讨论】:

显示所有数据库中的所有表。您可以将数据库名称作为第一个参数传递,以仅显示该数据库中的表。 从驱动mysql-connector-java 8.0.22开始metaData.getTables从所有数据库返回所有用户可见的表,忽略参数'schema'【参考方案3】:

在您的示例中,问题是在 DatabaseMetaData 的 getTables 函数中传递表名模式。

有些数据库支持大写标识符,有些支持小写标识符。例如 oracle 以大写形式获取表名,而 postgreSQL 以小写形式获取表名。

DatabaseMetaDeta 提供了判断数据库如何存储标识符的方法,可以混合大小写,大写,小写见:http://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#storesMixedCaseIdentifiers()

从下面的示例中,您可以获得所有表格和提供表格名称模式的视图,如果您只想要表格然后从 TYPES 数组中删除“VIEW”。

public class DBUtility 
    private static final String[] TYPES = "TABLE", "VIEW";
    public static void getTableMetadata(Connection jdbcConnection, String tableNamePattern, String schema, String catalog, boolean isQuoted) throws HibernateException 
            try 
                DatabaseMetaData meta = jdbcConnection.getMetaData();
                ResultSet rs = null;
                try 
                    if ( (isQuoted && meta.storesMixedCaseQuotedIdentifiers())) 
                        rs = meta.getTables(catalog, schema, tableNamePattern, TYPES);
                     else if ( (isQuoted && meta.storesUpperCaseQuotedIdentifiers())
                        || (!isQuoted && meta.storesUpperCaseIdentifiers() )) 
                        rs = meta.getTables(
                                StringHelper.toUpperCase(catalog),
                                StringHelper.toUpperCase(schema),
                                StringHelper.toUpperCase(tableNamePattern),
                                TYPES
                            );
                    
                    else if ( (isQuoted && meta.storesLowerCaseQuotedIdentifiers())
                            || (!isQuoted && meta.storesLowerCaseIdentifiers() )) 
                        rs = meta.getTables( 
                                StringHelper.toLowerCase( catalog ),
                                StringHelper.toLowerCase(schema), 
                                StringHelper.toLowerCase(tableNamePattern), 
                                TYPES 
                            );
                    
                    else 
                        rs = meta.getTables(catalog, schema, tableNamePattern, TYPES);
                    

                    while ( rs.next() ) 
                        String tableName = rs.getString("TABLE_NAME");
                        System.out.println("table = " + tableName);
                    



                
                finally 
                    if (rs!=null) rs.close();
                
            
            catch (SQLException sqlException) 
                // TODO 
                sqlException.printStackTrace();
            

    

    public static void main(String[] args) 
        Connection jdbcConnection;
        try 
            jdbcConnection = DriverManager.getConnection("", "", "");
            getTableMetadata(jdbcConnection, "tbl%", null, null, false);
         catch (SQLException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
    

【讨论】:

【参考方案4】:

如果您想使用高级 API,它隐藏了数据库架构元数据周围的大量 JDBC 复杂性,请查看这篇文章:http://www.devx.com/Java/Article/32443/1954

【讨论】:

【参考方案5】:
public static ArrayList<String> getTablesList(Connection conn)
            throws SQLException 

        ArrayList<String> listofTable = new ArrayList<String>();

        DatabaseMetaData md = conn.getMetaData();

        ResultSet rs = md.getTables(null, null, "%", null);

        while (rs.next()) 
            if (rs.getString(4).equalsIgnoreCase("TABLE")) 
                listofTable.add(rs.getString(3));
            
        
        return listofTable;
    

【讨论】:

【参考方案6】:

在较新版本的 MySQL 连接器中,如果未通过目录,也会列出默认表

        DatabaseMetaData dbMeta = con.getMetaData();
        //con.getCatalog() returns database name
        ResultSet rs = dbMeta.getTables(con.getCatalog(), "", null, new String[]"TABLE");
        ArrayList<String> tables = new ArrayList<String>();
        while(rs.next())
            String tableName = rs.getString("TABLE_NAME");
            tables.add(tableName);
        
        return tables;

【讨论】:

【参考方案7】:
DatabaseMetaData md = conn.getMetaData();
String[] types = "TABLE";
ResultSet rs = md.getTables("Your_DB_Name", null, "%", types);
while (rs.next()) 
    System.out.println(rs.getString("TABLE_NAME"));

【讨论】:

【参考方案8】:
@Transactional
@RequestMapping(value =  "/getDatabaseTables" , method = RequestMethod.GET)
public @ResponseBody String getDatabaseTables() throws Exception 

    Connection con = ((SessionImpl) sessionFactory.getCurrentSession()).connection();
    DatabaseMetaData md = con.getMetaData();
    ResultSet rs = md.getTables(null, null, "%", null);
    HashMap<String,List<String>> databaseTables = new HashMap<String,List<String>>();
    List<String> tables = new ArrayList<String>();
    String db = "";
    while (rs.next()) 
        tables.add(rs.getString(3));
        db = rs.getString(1);
    
    List<String> database = new ArrayList<String>();
    database.add(db);
    databaseTables.put("database", database);
    Collections.reverse(tables);
    databaseTables.put("tables", tables);
    return new ObjectMapper().writeValueAsString(databaseTables);


@Transactional
@RequestMapping(value =  "/getTableDetails" , method = RequestMethod.GET)
public @ResponseBody String getTableDetails(@RequestParam(value="tablename")String tablename) throws Exception 
    System.out.println("...tablename......"+tablename);
    Connection con = ((SessionImpl) sessionFactory.getCurrentSession()).connection();       
     Statement st = con.createStatement();
     String sql = "select * from "+tablename;
     ResultSet rs = st.executeQuery(sql);
     ResultSetMetaData metaData = rs.getMetaData();
     int rowCount = metaData.getColumnCount();    
     List<HashMap<String,String>> databaseColumns = new ArrayList<HashMap<String,String>>();
     HashMap<String,String> columnDetails = new HashMap<String,String>();
     for (int i = 0; i < rowCount; i++) 
         columnDetails = new HashMap<String,String>();
         Method method = com.mysql.jdbc.ResultSetMetaData.class.getDeclaredMethod("getField", int.class);
         method.setAccessible(true);
         com.mysql.jdbc.Field field = (com.mysql.jdbc.Field) method.invoke(metaData, i+1);
         columnDetails.put("columnName", field.getName());//metaData.getColumnName(i + 1));
         columnDetails.put("columnType", metaData.getColumnTypeName(i + 1));
         columnDetails.put("columnSize", field.getLength()+"");//metaData.getColumnDisplaySize(i + 1)+"");
         columnDetails.put("columnColl", field.getCollation());
         columnDetails.put("columnNull", ((metaData.isNullable(i + 1)==0)?"NO":"YES"));
         if (field.isPrimaryKey()) 
             columnDetails.put("columnKEY", "PRI");
          else if(field.isMultipleKey()) 
             columnDetails.put("columnKEY", "MUL");
          else if(field.isUniqueKey()) 
             columnDetails.put("columnKEY", "UNI");
          else 
             columnDetails.put("columnKEY", "");
         
         columnDetails.put("columnAINC", (field.isAutoIncrement()?"AUTO_INC":""));
         databaseColumns.add(columnDetails);
     
    HashMap<String,List<HashMap<String,String>>> tableColumns = new HashMap<String,List<HashMap<String,String>>>();
    Collections.reverse(databaseColumns);
    tableColumns.put("columns", databaseColumns);
    return new ObjectMapper().writeValueAsString(tableColumns);

【讨论】:

以上是关于如何从数据库中获取所有表名?的主要内容,如果未能解决你的问题,请参考以下文章

JDBC - 从 OpenOffice 数据库中获取所有表名

使用c#获取数据库中的所有表名

如何获取android sqlite数据库中的所有表名?

如何从特定数据库中检索具有行数的表名?

如何从 SQL 查询中获取表名?

如何从雪花中的数据库模式中检索所有表名