Есть ли возможность вывести название и (или) количество столбцов таблицы?

Надо получить из БД имена столбцов таблицы и (или) их количество, чтобы в Java распарсить ответ из БД и вернуть его в виде Hash таблицы, где ключи - названия столбцов, а значения - значения полей из запроса.

То есть, смысл в том, чтобы получив запросом названия столбцов, заполнить ими ключи таблицы, а потом сформировать отдельные запросы по именам столбцов и заполнить уже значения в таблице.

Например:
получаю список столбцов: id,name,age. Заношу их в HashMap в качестве ключей. Затем, делаю три отдельных селекта: select id from person where .... и заношу полученные значения в HashMap в качестве значений (извините за тафтологию).

Есть идеи? Или может я велосипед изобретаю?


Ответы (3 шт):

Автор решения: Akina
select column_name 
from user_tab_columns 
where table_name = 'TABLENAME'
→ Ссылка
Автор решения: 0xdb

Информацию о колонках таблицы: имя, тип данных, его длину и пр., можно получить не выполняя никаких явных запросов. Для этого есть интерфейс DatabaseMetaData.

Например для таблицы:

create table persons (id int, name varchar2 (32), age int)

Такой код:

create or replace and compile java source named TestMetaData as
import java.sql.*;
public class TestMetaData {
    public static void getColumns (String tabname) {
        try {
            Connection conn = DriverManager.getConnection ("jdbc:default:connection");
            DatabaseMetaData md = conn.getMetaData();
            ResultSet rs = md.getColumns (null, null, tabname, null);
            int rows = 0;
            while (rs.next()) {
                System.out.println (
                    rs.getString ("COLUMN_NAME")+" "+
                    rs.getString ("TYPE_NAME")+"("+rs.getInt ("COLUMN_SIZE")+")");
                rows++;
            }
            System.out.println ("total cols: "+rows);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
/
create or replace procedure getcols (rows varchar2)
as language java name 'TestMetaData.getColumns (java.lang.String)';
/

Выведет следующий результат:

exec getcols (upper ('persons'))

ID   NUMBER(38)  
NAME   VARCHAR2(32)  
AGE   NUMBER(38)  
total cols: 3
→ Ссылка
Автор решения: Roman Konoval

Ваш подход потребует N+1 запрос, если у вас в таблице N колонок. Правильный подход это делать один запрос и из его метаданных доставать информацию и про столбцы и собственно сами данные:

import java.sql.*;


...
Map<String, Object> row = new HashMap<>();

PreparedStatement ps = connection.prepareStatement("select * from TABLENAME");  
ResultSet rs = ps.executeQuery();  
ResultSetMetaData metadata = rs.getMetaData();

rs.next(); // переходим к первой строке результата

for(int i = 0; i < metadata.getColumnCount(); ++i) {
  String columnName = metadata.getColumnName(i + 1); 
  switch(metadata.getColumnType()) {
  case Types.INTEGER:
     map.put(columnName, rs.getInt(i + 1));
     break; 
  case Types.VARCHAR:
     map.put(columnName, rs.getString(i + 1));
     break; 
  // и другие типы если нужно
  default:
     map.put(columnName, rs.getObject(i + 1));
  }
}  

Кроме всего прочего, этот подход еще и не зависит от СУБД и будет работать на любой.

→ Ссылка