Есть ли возможность вывести название и (или) количество столбцов таблицы?
Надо получить из БД имена столбцов таблицы и (или) их количество, чтобы в Java распарсить ответ из БД и вернуть его в виде Hash таблицы, где ключи - названия столбцов, а значения - значения полей из запроса.
То есть, смысл в том, чтобы получив запросом названия столбцов, заполнить ими ключи таблицы, а потом сформировать отдельные запросы по именам столбцов и заполнить уже значения в таблице.
Например:
получаю список столбцов: id,name,age. Заношу их в HashMap в качестве ключей. Затем, делаю три отдельных селекта: select id from person where .... и заношу полученные значения в HashMap в качестве значений (извините за тафтологию).
Есть идеи? Или может я велосипед изобретаю?
Ответы (3 шт):
select column_name
from user_tab_columns
where table_name = 'TABLENAME'
Информацию о колонках таблицы: имя, тип данных, его длину и пр., можно получить не выполняя никаких явных запросов. Для этого есть интерфейс 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
Ваш подход потребует 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));
}
}
Кроме всего прочего, этот подход еще и не зависит от СУБД и будет работать на любой.