My Database Table Schema is something like
DocumentID: Name1: Name2: Name3: Name4: Location1: Location2: Location3....:Organization1:..
Now I have 3 Hashset's available having the above values (i.e one for name, one for location and one for organization)
In each single iteration of loop these hashset are being populated with above values.
At the end of each iteration the data from these hashset's is removed and new one's are created.
Now my problem is at each iteration I have to populate the sql table row (just 1 row each iteration) from these hashset values.
What I am not able to understand is if I have hard coded strings than simply I can use something like:
String sql = "INSERT INTO Table " +
"VALUES ('100', 'Zara', 'Akli', '18','100', 'Zara', 'Ali', '18')";
However I need to iterate through each hashset and insert (something like above) the data of all 3 hashset's in a single row. I am confused of how to write such statement. Remember my table is initially completely empty so I cant't use the where clause (something like "insert into.....where documentID="23423")
Assuming you have created these Sets these way:
long DocumentId
names {"A", "B", "C"}
location {"1", "2", "3"}
and so on...
I think the easiest is to build dinamically the SQL to execute:
{
...
StringBuilder sb = new StringBuilder("insert into mytable (");
List<Object> params = new ArrayList<Object>();
addColumnAndValue(sb, "DocumentID", docIdYouHaveSomewhere, params);
int i = 0;
for (String name: names)
addColumnAndValue(sb, ",name" + i, name, params);
i = 0;
for (String location: locations)
addColumnAndValue(sb, ",location" + i, location, params);
// now close the thing
sb.append(") values (?");
for (i = 1; i<params.size(); i++)
sb.append(",?");
sb.append("=");
// and now sb.toString() will contain valid SQL and the param values for a PreparedStatement will be in params array-list:
PreparedStatement ps = conn.prepareStatement(sb.toString());
for (i=0; i<params.size(); i++)
ps.setObject(i+1, params.get(i));
ps.executeUpdate(); // voi là!
...
}
private void add addColumnAndValue(StringBuilder sb, String columnName, Object value, List<Object> params) {
sb.append(columnName);
params.add(value);
}
i guess you need to first do some work on your 3 "HashSet"s.
Since you said the data in 3 Sets will finally go to single row in database. so I suggest that convert your 3 hashset into a Map, or at least a List, with same order as the fields in your insert statement. so that later you could set those values by name or index as parameters to your PS.
and I have never seen an insert statement like "Insert into table values (....) where id=123" are u sure it will work?
Related
I want to insert list of string into Database so usual we will store string directly to database by either using prepared statement or batch statement like that but now I want to insert list of string into database so I have used prepared statement
List<String> Account_Number = Files.lines(Paths.get("D:\\PDFTOEXCEL\\Extractionfrompdf.txt"))
.filter(s -> s.contains(arra.get(7)))
.map(s -> s.split(":")[1].trim())
.collect(Collectors.toList());
System.out.println(Account_Number);
try {
Connection conn = PDFTOEXCEL.getConnection();
PreparedStatement stmt = conn.prepareStatement("insert into client_info values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
stmt.setString(1, Account_Number.get(1));
int k = stmt.executeUpdate();
I have about 31 columns in my database just for showing I have posted only one in this code all are in the list of string only
So now I am getting error in :
while (query_set.next()) {
row_counter = row_counter + 1;
**Account_Number = query_set.getString("Account_Number");**
Output:
Error:incompatible types: String cannot be converted to List
The bold one is the error statement
The problem is that Account_Number is of type List, and you try to assign a String to it. That is not possible: a String is not a List. Assuming you want to add this string to the list, you need to use Account_Number.add(...):
Account_Number.add(query_set.getString("Account_Number"));
Given you haven't provided a lot of context, it is hard to say if this is actually the right thing to do.
On a separate note, please try to follow common Java naming conventions. Variables and fields should start with a lowercase letter, and usually underscores are avoided, except in constants. So it should be accountNumber, not Account_Number. Following the conventions will make it easier for people to read your code.
I have a class in Java such like this
for (....) {
tarik_id.add(id);
}
which is tarik_id is a List<String> and I want to add the (id) to be written in tarik_id arrayList. And then....
hasil = db.getDetailResult(tarik_id);
getDetailResult is a class for selecting all the (id) that I have pulled out with tarik_id.
And hasil is two dimensional table (List.List.String..)
I think that tarik_id doesn't return a value in my second line above. I have tried to Log.i my id, and the LogCat returns true values of my id. My question is how can the tarik_id in .getDetailResult returns all of the array values?
make your code as the following:
// put the first id in first
StringBuilder stringBuilder = new StringBuilder(id.get(0));
// start the loop from the 2nd
for (i=1; i < idList.size(); i++)
{
stringBuilder.append(",").append(id.toString());
}
String ids = stringBuilder.toString()
hasil = db.getDetailResult(ids);
Change the code in getDetailResult() for the query to be something like
if(ids.equals("")){
return null;
}
String sql = "SELECT * FROM...... WHERE ID IN("+ids+").....";
I think this is much faster, all records in 1 hit and no need for a second loop.
I am trying to extract count(*) matching certain predicates. Every time I use createSQLQuery, I find myself having to write the code along the lines of,
// skipped code
Query q = session.createSQLQuery("select count(*) from A where id=1");
Scrollable results = q.scroll();
while ( results.next() )
{
Object[] row = Object[] results.get();
// Assign it
String str = row[0];
//set and persist
}
I have many such queries unioned over a single transaction. How do I get single result here? Am I missing something?
You can use this method instead:
Object[] row = (Object[]) query.uniqueResult();
If the query returns more than one result, this method will throw an exception
EDIT:
On top of that, you could use a ResultTransformer to convert the Object[] into an Integer. This would remove the need to get the result array and then extract it's first entry. See this example for more info
I have requirement to remove the duplicate values from result set based on some unique identifier.
I need to remove the duplicates from the result set.
while(resultSet.next())
{
int seqNo = resultSet.getInt("SEQUENCE_NO");
String tableName = resultSet.getString("TABLE_NAME");
String columnName = resultSet.getString("COLUMN_NAME");
String filter = resultSet.getString("FILTER");
}
from the above iteration, i m getting 2 rows from result set. There is same seq no,same table name, different columnname, same filter.
1 PRODUCTFEES CHARGETYPE PRODUCTID
1 PRODUCTFEES PRODUCTCODE PRODUCTID
My requirement is to remove the duplicate table name, duplicate seq no, duplicate filter.
I want to get output something below,
1 PRODUCTFEES CHARGETYPE PRODUCTCODE PRODUCTID
By the example you provide, it seems like you want to output all distinct values for each column indidivually (there are 4 columns in the table, but you output 5 values).
Being the question tagged java, an approach you could take would be using an implementation of Set for each of the columns, so that duplicates won't get through. Then output all the elements of each Set.
LinkedHashSet[] sets = new LinkedHashSet[]{
new LinkedHashSet(),
new LinkedHashSet(),
new LinkedHashSet(),
new LinkedHashSet() };
while(resultSet.next()) {
sets[0].add(resultSet.getInt("SEQUENCE_NO"));
sets[1].add(resultSet.getString("TABLE_NAME")););
sets[2].add(resultSet.getString("COLUMN_NAME"));
sets[3].add(resultSet.getString("FILTER"));
}
StringBuilder buf = new StringBuilder();
for (LinkedHashSet set : sets) {
// append to buf all elements of each set
}
But it might be simpler to address this from the very same SQL query and just make SELECT DISTINCT columnX for each of the columns and output the result without further manipulation. Or use an aggregation function that will concatenate all distinct values. The implementation will be highly dependent on the DBMS you're using (GROUP_CONCAT for MySQL, LISTAGG for Oracle, ...). This would be a similar question for Oracle: How to use Oracle's LISTAGG function with a unique filter?
Based on the different outputs I'd say, that you not just need to remove duplicates, but also reorder the data from the duplicates.
In that case you need to fill a new data-array (or similar structure) in the while(resultSet.next()), and after that loop over the newly arranged data-object and output accordingly.
In Meta-Lang this would be as follows:
while resultset.next()
if newdata-array has unique key
add column-name to found entry in newdata-array
else
create new entry in newdata-array with column-name
while newdata-array.next()
output seq, table-name
while entry.column-names.next()
output column-name
output product-id
I have 6 columns in a table. I have a select query which selects some records from the table. While iterating over the result set, im using the following logic to extract the values in the columns:
Statement select = conn.createStatement();
ResultSet result = select.executeQuery
("SELECT * FROM D724933.ECOCHECKS WHERE ECO = '"+localeco+"' AND CHK_TOOL = '"+checknames[i]+"'");
while(result.next()) { // process results one row at a time
String eco = result.getString(1);
mapp2.put("ECO", eco);
String chktool = result.getString(2);
mapp2.put("CHECK_TOOL", chktool);
String lastchktime = result.getString(3);
mapp2.put("LAST_CHECK_TIME", lastchktime);
String status = result.getString(4);
mapp2.put("STATUS", status);
String statcmts = result.getString(5);
mapp2.put("STATUS_COMMENTS", statcmts);
String details = result.getString(6);
mapp2.put("DETAILS_FILE", details);
}
I have 2 questions here:
1. Is there any better approach rather than using result.getString()???
2. Lets say, another column gets added to the table at a later point. Is there any way my code handles this new addition without making change to the code at that point of time
You can use ResultSetMetaData to determine the number and names of the columns in your ResultSet and deal with it this way. Note however that changing the number of columns in the database - affecting your code - and having the code still work may not always be a good idea.
Additionally, note that you're overwriting the values in your map on each iteration of the loop. You probably want to add those maps to some sort of List?
Finally, you need to make sure that your getString methods will not return null anywhere, otherwise putting it into a map will throw an exception.
Statement select = conn.createStatement();
ResultSet result = select.executeQuery("SELECT * FROM D724933.ECOCHECKS WHERE ECO = '"+localeco+"' AND CHK_TOOL = '"+checknames[i]+"'");
ResultSetMetaData rsmd = result.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
List data = new ArrayList<Map>();
Map mapp2;
while(result.next()) { // process results one row at a time
mapp2 = new HashMap<String, String>();
for(int i=1; i<=numberOfColumns; i++) {
mapp2.put(rsmd.getColumnName(i), rs.getString(i));
}
data.add(mapp2);
}
Each of the get family of methods on ResultSet has an overloaded variant that takes a column name as argument. You can use this instead to reduce reliance on ordering of columns.
ResultSet results = ...;
results.getString(1);
You could do this:
results.getString("name");
But the preferred way of handling this sort of problem is to impose an ordering of your own on the result set, by explicitly selecting the columns you want in the initial query.
If your table adds a new column, then obviously you have to change your code, because in your code you use hardcoded value, I mean getString(1).
Instead use ResultSetMetaData's getColumnCount and do some other logic to get that many column values dynamically.
Another thing for your first question, ResultSet contains getXXX() methods with two types of parameters, String column name and int column index. You used the index instead of column name which will perform little faster.
It is bad practice to use SELECT *, instead you should select only the columns you are interested in. The reason is exactly what you mentioned: What happens if your DB changes. you don't want to go trhough the whole code and find and edit all SELECT * statements.
You don't need to put the result into your own map because you can already do:
result.getString("DETAILS_FILE");
But there are already other answers explaining that.
It would be further helpful to use a constant instead of the string "DETAILS_FILE". You can use the constant in the SELECT and in the result.getString(). In case your DB changes you only need to introduce a new constant or change an existing one.