Basically I am trying to read multiple queries from excel sheet through jexel and I am adding the cell contents to Key and Value in hashmap. For example
A1=1 (Key) , A2 =2 ....
B1 = "SELECT * FROM ABCD;" (Value), B2 = "SELECT * FROM XYZ;"
Map<String, String> hashmap = new HashMap<String, String>();
for (int i=0;i<rowCount;i++) {
Cell rowObj1 =sheet.getCell(0, i);
Cell rowObj2 = sheet.getCell(1, i);
sql =rowObj2.getContents();
hashmap.put(rowObj1.getContents(), rowObj2.getContents());
}
Later I am getting the SQL(s) from the hashmap by iterating over rowCount on exel sheet.
Then I am adding all SQL(s) result sets to an array list
and finally I am iterating over array list size to get individual record set, at the same time get metadata for the record set.
However the problem here is I get
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:418)
at java.util.ArrayList.get(ArrayList.java:431)
at com.bmc.arsys.jdbc.core.ResultSetMetaData.getColumnCount(ResultSetMetaData.java:47)
on
int ColCount = metadata1.getColumnCount();
and here is the code snippet
ArrayList<ResultSet> arraylist = new ArrayList<ResultSet>();
int i;
String y;
for (i=1;i<=rowCount;i++){
y = Integer.toString(i);
sql =hashmap.get(y);
rs = st.executeQuery(sql);
arraylist.add(rs);
System.out.println(sql);
}
System.out.println("Array List Size "+arraylist.size());
for (int j=0;j<arraylist.size();j++){
ResultSet rs1= arraylist.get(j);
System.out.println("Record Set "+rs1);
ResultSetMetaData metadata1 = rs1.getMetaData();
System.out.println("Meta Data "+metadata1);
int ColCount = metadata1.getColumnCount();
System.out.println(ColCount);
int k;
for (k=1;k<ColCount;k++) {
System.out.println("Record_Set "+rs1);
while(rs1.next()) {
System.out.println(rs1.getString(k));
}
}
}
could someone please suggest where I am wrong.
Related
I have an hashmap with a key and value (Array of integers) HashMap<key, array> and I would like to retrieve data from a sql table with a column that matches the values in array stored in a hashmap
I can do this in two ways one getting all the data from table and iterating through hashmap and other being iterating through hashmap and applying the where clause in each iteration which makes n calls to database.
Is there an efficient way to do this other than the above ?
Use a PreparedStatement to set up a query having an IN condition in the WHERE clause. This snippet should give you the general idea:
values = new int[]{1,2,3,4,5};
String query =
"SELECT film_id, title\n"
+ "FROM film\n"
+ "WHERE film_Id IN (";
for (int i = 0; i < values.length; ++i) {
if (i > 0) {
query += ",";
}
query += "?";
}
query += ")";
try {
Connection conn = DriverManager.getConnection("db-url", "user", "pwd");
PreparedStatement stmt = conn.prepareStatement(query);
for (int i = 0; i < values.length; ++i)
stmt.setInt(i+1, values[i]);
ResultSet rs = stmt.executeQuery();
while (rs.next()){
// process results
}
} catch (Exception ex) {
ex.printStackTrace();
}
I'm currently scraping some scores from a HTML page and then inputting them into a SQL database.
The scores are being parsed using Jsoup into an ArrayList. From here I'm converting the ArrayList to a String to allow it to be parsed into a VARCHAR field in the db. Although I can't seem to work out how to edit the for loop I have to insert all the values at once.
Here is my current code:
Document doc = Jsoup.connect(URL).timeout(5000).get();
for (Element table : doc.select("table:first-of-type")) //selects first table
{
for (Element row : table.select("tr:gt(0)")) { //selects first table cell
Elements tds = row.select("td");//selects row
List1.add(tds.get(0).text());
List2.add(tds.get(1).text());
List3.add(tds.get(2).text());
}
}
PreparedStatement stmt = conn.prepareStatement("INSERT INTO Scores (Home, Score, Away) VALUES (?,?,?)");
String[] List1str = new String[List1.size()];
List1str = List1.toArray(List1str);
for (String s : List1str) {
stmt.setString(1, s);
stmt.setString(2, "test");
stmt.setString(3, "test");
stmt.executeUpdate();
}
for (int i = 0; i < dtm.getRowCount(); i++) {
for (int j = 0; j < dtm.getColumnCount(); j++) {
Object o = dtm.getValueAt(i, j);
System.out.println("object from table is : " + o);
pst.setString(j + 1, (String) o);
}
pst.executeUpdate();
pst.clearParameters();
}
This question already has answers here:
Retrieve column names from java.sql.ResultSet
(14 answers)
Closed 8 years ago.
Hello I'm trying to make an error when there is no matched student...
and it will display like this
No matching records found and I want the column name still the same but still not figuring it out... can some one tell me if this is right??
Heres my function for that... and I add comment there where I put the error... but i don't know how to get the columnname
public void SearchTableStudent() {
String tempSearchValue = searchStudent.getText().trim();
boolean empty = true;
sql = "SELECT student_id as 'Student ID',"
+ "concat(lastname, ' , ', firstname, ' ', middlename) as 'Name'"
+ "FROM user "
+ "WHERE CAST(student_id as CHAR) LIKE '%" + tempSearchValue + "%'";
try {
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
while(rs.next()) {
table.setModel(DbUtils.resultSetToTableModel(rs));
empty = false;
}
if(empty) {
String error = "";
table.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{"No matching records found",null}
},
new String [] {
/** I WANT TO PUT THE SAME COLUMN NAME ON MY DATABASE SELECTED BUT DON't Know
WHAT FUNCTION TO DO*/
}
));
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
}
I try like this but still gave me NULL!!!
this code is below of empty = false;
for(int i=0; i<table.getColumnCount(); i++) {
test[i] = table.getColumnName(i);
}
ResultSetMetaData metaData = resultSet.getMetaData();
int count = metaData.getColumnCount(); //number of column
String columnName[] = new String[count];
for (int i = 1; i <= count; i++)
{
columnName[i-1] = metaData.getColumnLabel(i);
System.out.println(columnName[i-1]);
}
Try this.
ResultSetMetaData meta = resultset.getMetaData();
Integer columncount = meta.getColumnCount();
int count = 1 ; // start counting from 1 always
String[] columnNames = new String[columncount];
while(count<=columncount){
columnNames [count-1] = meta.getColumnLabel(count);
count++;
}
Since here your expecting is to get the columns alias instead of column name, so you have to use ResultSetMetaData.getColumnLabel instead of ResultSetmetaData.getColumnName.
Get ResultSetMetaData using ResultSet#getMetaData():
ResultSetMetaData meta = rs.getMetaData();
And then to get column name of 1st column:
String col1Name = meta.getColumnLabel(1);
Similarly to get column name of 2nd column:
String col2Name = meta.getColumnLabel(2);
Get the metadata
ResultSetMetaData metaData = rs.getMetaData();
Then you can do:
String columnName = metaData.getColumnName(int index);
ResultSetMetaData doc
rs.getMetaData().getColumnName(int i);
and do not concat the query param!
How can I convert a ResultSet to an Integer array?
I really need an Integer array. No Lists or something like that.
ResultSet rs = sqlite.query("SELECT ores FROM testtable WHERE nicknames='"+"testname"+"';");
"ores" contains 8 integers separated by a space: 10 20 30 40 50 60 70 80
Edit:
"ores" is stored as VARCHAR
Bad code. I'd recommend a PreparedStatement:
PreparedStatement ps = connection.prepareStatement("SELECT ores FROM testtable WHERE nicknames= ?");
ps.setString(1, nickname);
ResultSet rs = ps.executeQuery();
List<Integer> values = new ArrayList<Integer>();
while (rs.next()) {
String ores = rs.getString("ores");
String [] tokens = ores.split("\\s+");
for (int i = 0; i < tokens.length; ++i) {
values.add(Integer.valueOf(tokens[i]));
}
}
The ResultSet is the result of yourr query, if you want to transform it to an ArrayList or a simple Integer array, you can iterate over the ResulstSet and add all the non-null Object to your ArrayList or array. This is a simple solution...
Vector<Integer> ores = new Vector<Integer>();
rs.beforeFirst();
while(rs.next()){ores.add(rs.getInt(1));}
Integer[] vals = ores.toArray(new Integer[0]);
Maybe something like:
rs.last();
rowcnt = myResultSet.getRow(); // get row no.
rs.beforeFirst();
int i = 0;
Integer[] options = new Integer[rowcnt];
while (rs.next()) {
options[i] = Integer.parseInt(rs.getString(i));
i++;
}
I'm using a ResultSet in Java, and am not sure how to properly close it. I'm considering using the ResultSet to construct a HashMap and then closing the ResultSet after that. Is this HashMap technique efficient, or are there more efficient ways of handling this situation? I need both keys and values, so using a HashMap seemed like a logical choice.
If using a HashMap is the most efficient method, how do I construct and use the HashMap in my code?
Here's what I've tried:
public HashMap resultSetToHashMap(ResultSet rs) throws SQLException {
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
HashMap row = new HashMap();
while (rs.next()) {
for (int i = 1; i <= columns; i++) {
row.put(md.getColumnName(i), rs.getObject(i));
}
}
return row;
}
Iterate over the ResultSet
Create a new Object for each row, to store the fields you need
Add this new object to ArrayList or Hashmap or whatever you fancy
Close the ResultSet, Statement and the DB connection
Done
EDIT: now that you have posted code, I have made a few changes to it.
public List resultSetToArrayList(ResultSet rs) throws SQLException{
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
ArrayList list = new ArrayList(50);
while (rs.next()){
HashMap row = new HashMap(columns);
for(int i=1; i<=columns; ++i){
row.put(md.getColumnName(i),rs.getObject(i));
}
list.add(row);
}
return list;
}
I just cleaned up RHT's answer to eliminate some warnings and thought I would share. Eclipse did most of the work:
public List<HashMap<String,Object>> convertResultSetToList(ResultSet rs) throws SQLException {
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
List<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();
while (rs.next()) {
HashMap<String,Object> row = new HashMap<String, Object>(columns);
for(int i=1; i<=columns; ++i) {
row.put(md.getColumnName(i),rs.getObject(i));
}
list.add(row);
}
return list;
}
RHT pretty much has it. Or you could use a RowSetDynaClass and let someone else do all the work :)
this is my alternative solution, instead of a List of Map, i'm using a Map of List.
Tested on tables of 5000 elements, on a remote db, times are around 350ms for eiter method.
private Map<String, List<Object>> resultSetToArrayList(ResultSet rs) throws SQLException {
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
Map<String, List<Object>> map = new HashMap<>(columns);
for (int i = 1; i <= columns; ++i) {
map.put(md.getColumnName(i), new ArrayList<>());
}
while (rs.next()) {
for (int i = 1; i <= columns; ++i) {
map.get(md.getColumnName(i)).add(rs.getObject(i));
}
}
return map;
}
A couple of things to enhance the other answers. First, you should never return a HashMap, which is a specific implementation. Return instead a plain old java.util.Map. But that's actually not right for this example, anyway. Your code only returns the last row of the ResultSet as a (Hash)Map. You instead want to return a List<Map<String,Object>>. Think about how you should modify your code to do that. (Or you could take Dave Newton's suggestion).
i improved the solutions of RHTs/Brad Ms and of Lestos answer.
i extended both solutions in leaving the state there, where it was found.
So i save the current ResultSet position and restore it after i created the maps.
The rs is the ResultSet, its a field variable and so in my solutions-snippets not visible.
I replaced the specific Map in Brad Ms solution to the gerneric Map.
public List<Map<String, Object>> resultAsListMap() throws SQLException
{
var md = rs.getMetaData();
var columns = md.getColumnCount();
var list = new ArrayList<Map<String, Object>>();
var currRowIndex = rs.getRow();
rs.beforeFirst();
while (rs.next())
{
HashMap<String, Object> row = new HashMap<String, Object>(columns);
for (int i = 1; i <= columns; ++i)
{
row.put(md.getColumnName(i), rs.getObject(i));
}
list.add(row);
}
rs.absolute(currRowIndex);
return list;
}
In Lestos solution, i optimized the code. In his code he have to lookup the Maps each iteration of that for-loop. I reduced that to only one array-acces each for-loop iteration. So the program must not seach each iteration step for that string-key.
public Map<String, List<Object>> resultAsMapList() throws SQLException
{
var md = rs.getMetaData();
var columns = md.getColumnCount();
var tmp = new ArrayList[columns];
var map = new HashMap<String, List<Object>>(columns);
var currRowIndex = rs.getRow();
rs.beforeFirst();
for (int i = 1; i <= columns; ++i)
{
tmp[i - 1] = new ArrayList<>();
map.put(md.getColumnName(i), tmp[i - 1]);
}
while (rs.next())
{
for (int i = 1; i <= columns; ++i)
{
tmp[i - 1].add(rs.getObject(i));
}
}
rs.absolute(currRowIndex);
return map;
}
Here is the code little modified that i got it from google -
List data_table = new ArrayList<>();
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(conn_url, user_id, password);
Statement stmt = con.createStatement();
System.out.println("query_string: "+query_string);
ResultSet rs = stmt.executeQuery(query_string);
ResultSetMetaData rsmd = rs.getMetaData();
int row_count = 0;
while (rs.next()) {
HashMap<String, String> data_map = new HashMap<>();
if (row_count == 240001) {
break;
}
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
data_map.put(rsmd.getColumnName(i), rs.getString(i));
}
data_table.add(data_map);
row_count = row_count + 1;
}
rs.close();
stmt.close();
con.close();
public static List<HashMap<Object, Object>> GetListOfDataFromResultSet(ResultSet rs) throws SQLException {
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount();
String[] columnName = new String[count];
List<HashMap<Object,Object>> lst=new ArrayList<>();
while(rs.next()) {
HashMap<Object,Object> map=new HashMap<>();
for (int i = 1; i <= count; i++){
columnName[i-1] = metaData.getColumnLabel(i);
map.put(columnName[i-1], rs.getObject(i));
}
lst.add(map);
}
return lst;
}