I have an arraylist of strings
ArrayList myList = new ArrayList();
myList = [url1,url2,url3];
I need to insert these urls in 3 different rows in the database.This is how I am doing it.
while(myList.size()!=0)
{
//get individual values in the array list
int idx=0;
String url= myList.get(idx++).toString() ;
String insert="INSERT into test (url) values (?)";
prepstmt = conn.prepareStatement(insert);
prepstmt .setString(r++, url);
prepstmt.executeUpdate();
}
This goes to infinite loop.
Can someone please help me correct my code? Insert part of code is fine. But I am failing to get the individual urls.
Thanks!
Try this:
String insert = "INSERT into test (url) values (?)";
for (String url : myList) {
prepstmt = conn.prepareStatement(insert);
prepstmt.setString(1, url);
prepstmt.executeUpdate();
}
#niculare give the best way you need to change your code.
but if you don't want to to use for-loop you need to change your if-statement like this:
int idx=0;
while(idx < myList.size())
{
String url= myList.get(idx).toString() ;
String insert="INSERT into test (url) values (?)";
prepstmt = conn.prepareStatement(insert);
prepstmt .setString(r++, myURL);
idx++;
}
or if you not need this list any more use remove method:
while(myList.size()!=0)
{
//get individual values in the array list
int idx=0;
String url= myList.remove(idx++).toString() ;
String insert="INSERT into test (url) values (?)";
prepstmt = conn.prepareStatement(insert);
prepstmt .setString(r++, myURL);
}
you can use listIterator:
ListIterator<String> iter = myList.listIterator();
while(iter.hasNext()){
String url = (String) iter.next();
String insert="INSERT into test (url) values (?)";
prepstmt = conn.prepareStatement(insert);
prepstmt .setString(r++, myURL);
}
but I repeat once more: the best way is to use for-loop.
And one more advice. create you list like this:
List<String> myList = new ArrayList<String>();
UPDATE
this is one of my examples:
public class test2 {
public static void main(String ... args) {
ArrayList<String> myList = new ArrayList<String>();
myList.add("123");
myList.add("245");
myList.add("678");
ListIterator<String> iter = myList.listIterator();
while(iter.hasNext()){
String url = (String) iter.next();
System.out.println(url);
}
}
Posting full stack trace:
[3/30/13 2:35:00:241 GMT-06:00] 00000251 SystemOut O
com.ibm.dw.register.PubHandler handleMessage(String promoter,
String topic, String message) com.ibm.db2.jcc.am.eo: The value of a
host variable in the EXECUTE or OPEN statement is out of range for its
corresponding use.. SQLCODE=-302, SQLSTATE=22001, DRIVER=3.57.110
Related
Hi I'm using preparedStatement in Java to execute query in DB.
The table:
When it comes to update, delete and insert it's all fine, however when it comes to select( ex. I've done "SELECT ?,?,?,?,? from person" and set strings afterwards) and the following result is returned:
I'm assuming that because it's the strings that are replacing ? so it did not come out as expected:(please correct me if it's wrong)
Expected sql: "SELECT no,name,tel,birthday,address FROM person"
Actual sql: "SELECT \"no\",\"name\",\"birthday\",\"address\" FROM person"
I've tested the second one in in Navicat:
I'd like to understand that why executing this query statement would return a result like this?
If it would help here's Java code:
// Data Assist Object
public class DAO {
static String jdbcurl;
static String username;
static String password;
static{
try {
Class.forName("com.mysql.jdbc.Driver");
ResourceBundle rb = ResourceBundle.getBundle("db");
jdbcurl = rb.getString("jdbcurl");
username = rb.getString("username");
password = rb.getString("password");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
// for insert, delete and update
public int modify(String sql, String[] args){
int x=0;
try(Connection con = DriverManager.getConnection( jdbcurl,username ,password);
PreparedStatement ps = con.prepareStatement(sql);){
for (int i = 0; i < args.length; i++) {
ps.setString(i+1, args[i]);
}
x =ps.executeUpdate();
System.out.println(x);
}catch(SQLException e){
e.printStackTrace();
}
return x;
}
// for select
public List<Map<String,String>> query(String sql, String[] params){
List<Map<String,String>> resList = new ArrayList<>();
try(Connection con = DriverManager.getConnection( jdbcurl,username ,password);
PreparedStatement ps = con.prepareStatement(sql);){
for (int i = 0; i < params.length; i++) {
ps.setString(i+1, params[i]);
}
try(ResultSet res =ps.executeQuery();){
ResultSetMetaData mdata = res.getMetaData();
int num = mdata.getColumnCount();
while(res.next()){
HashMap<String,String> data = new HashMap<>();
for (int i = 1; i <= num; i++) {
String result = res.getString(i);
String columnName = mdata.getColumnName(i);
data.put(columnName,result);
}
resList.add(data);
}
}
}catch(Exception e){
e.printStackTrace();
}
return resList;
}
public static void main(String[] args) throws SQLException {
DAO dao = new DAO();
String sql = "insert into person(name,tel,birthday,address) values(?,?,?,?)";
sql = "select ?,?,?,?,? from person";
List<Map<String,String>> res = dao.query(sql, new String[]{"no","name","tel","birthday","address"});
for(Map m:res){
System.out.print("no: "+m.get("no")+",");
System.out.print("name: "+m.get("name")+",");
System.out.print("tel: "+m.get("tel")+",");
System.out.print("birthday: "+m.get("birthday")+",");
System.out.println("address: "+m.get("address"));
}
}
}
Thanks for any help.
SQL basically works on a show me these columns where this criteria is true basis.
In the statement:
"SELECT \"no\",\"name\",\"birthday\",\"address\" FROM person"
You're getting
SELECT "no", "name", "birthday", "address" FROM person
when it actually hits the database. The "" operator creates a string in SQL. In plain English, that means that you're telling the database to return that specified set of strings for each row in person where the criteria you listed is met.
Since you didn't list a where clause, all rows are true by default so you get one row of strings for every single row in the person table. The first query is the same thing, but instead of directly passing the strings, you're adding them in as bind variables.
If you actually want to see the values in the table, write the query without the "'s
SELECT no, name, birthday, address FROM person
Unless otherwise specified, bind functions generally pass the value as a string. Which is why the query behaved the way it did. I don't recommend using bind variables in the select clause. That's a strange practice.
Edit:
As Adrian pointed out in the comments, " denotes columns in SQL. My apologies for not catching that. I assume that you meant to use the ' operator which actually denotes strings.
If not, something else is going on here entirely.
For the select you use the question marks in the WHERE clause, not where you list the fields you need as output.
Replace
sql = "select ?,?,?,?,? from person";
with
sql = "select no,name,tel,birthday,address from person";
For this particular query there is no binding to do. It will retrieve all the records from the table.
I am trying to find regular expression and if there are some duplicates, keep the unique ones and put the rest in a trash table.
but I get this Erro which I do not know what it is!
Here is my code:
public class RegexRemoverMain {
public static void main(String[] args) throws SQLException, ClassNotFoundException{
//Connection Parameters and Connect to Postgres Database
String data = "jdbc:postgresql://localhost:5432/postgres";
Class.forName("org.postgresql.Driver");
Connection conn = null;
//Connect to DB
conn = DriverManager.getConnection(
data, "username", "password");
//statements to get distinct owners
Statement ownerSt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
//statement to get Image Ids of a user
Statement ownersImagesIdsSt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String insertSQL;
//an arraylist to store unique titles+tags reported by user
ArrayList<List<String>> result = new ArrayList<List<String>>();
//list for storing those Ids of a users which are filtered
List<String> filteredIds = new ArrayList<String>();
//list for storing those Ids of a users which are kept
List<String> ids = new ArrayList<String>();
//get the list of all the users
ResultSet distinctOwner = ownerSt.executeQuery("select distinct owner from \"flickrData_bulkUploadedFree\"");
distinctOwner.last();
distinctOwner.beforeFirst();
int count=0;
//RegularExpression Pattern
String theRegex= "((DSC)?(dsc)?(img)?(IMG)?(\\s?)(\\_?)((\\-?))[0-9]{1,9})";
Pattern checkRegex = Pattern.compile(theRegex);
//loop is going through all user's Images and check whether their the titles is one of the patterns if yes, check their title+description which are unique or not
//if yes, we keep them; if not; we throw them away or store in another place
while(distinctOwner.next()){
count = count++;
Statement insertSt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
//store filtered images
String insertString = "INSERT INTO regexIamges"
+ "( id , owner, descriptio, title, tags) VALUES"
+ "(?,?,?,?,?)";
PreparedStatement preparedStatement = conn.prepareStatement(insertString);
//for each user exist in "flickrData_bulkUploadedFree"
String owner = distinctOwner.getString("owner");
ResultSet ownersImages;
ownersImages = ownersImagesIdsSt.executeQuery("select id, title, tags, descriptio from \"flickrData_bulkUploadedFree\" where owner = '" + owner +"';");
ownersImages.last();
ownersImages.beforeFirst();
//an list of images of a user's with the information about id, title, tags and descriptions in order to find unique Images
ArrayList<List<String>> bulkUploadList = new ArrayList<List<String>>();
while(ownersImages.next()){
String id = ownersImages.getString("id");
String title = ownersImages.getString("title");
String tags = ownersImages.getString("tags");
String description = ownersImages.getString("descriptio");
Matcher regexMatcher = checkRegex.matcher(title);
if (regexMatcher.find()){
if(regexMatcher.group().length() != 0){
List<String> rowsList = new ArrayList<String>();
rowsList.add(id);
rowsList.add(title);
rowsList.add(tags);
rowsList.add(description);
bulkUploadList.add(rowsList);
bulkUploadList.add(rowsList);
}
}
else{
insertSQL = "INSERT INTO \"regBulkfreeFlickrData\" SELECT * FROM \"flickrData_bulkUploadedFree\" where id ='"+id+"';";
insertSt.addBatch(insertSQL);
}
}
HashSet<String> hashSet = new HashSet<String>();
for(List<String> item : bulkUploadList) {
String title, tags, id, desc, uniqueString;
title = item.get(1);
tags = item.get(2);
id = item.get(0);
desc = item.get(3);
uniqueString = (tags + "#" + desc).trim().toUpperCase();
System.out.println(item);
if(!hashSet.contains(uniqueString)) {
result.add(item);
hashSet.add(uniqueString);
insertSQL = "INSERT INTO \"regBulkfreeFlickrData\" SELECT * FROM \"flickrData_bulkUploadedFree\" where id ='"+id+"';";
insertSt.addBatch(insertSQL);
} else {
// System.out.println("Filtered element " + uniqueString + "id " + id);
filteredIds.add(id);
preparedStatement.setString(1, id);
preparedStatement.setString(2, owner);
preparedStatement.setString(3, desc);
preparedStatement.setString(4, title);
preparedStatement.setString(5, tags);
preparedStatement.addBatch();
}
}
preparedStatement.executeBatch();
preparedStatement.close();
insertSt.executeBatch();
insertSt.close();
}
}
and the Error is this:
Exception in thread "main" java.sql.BatchUpdateException: Batch entry 0 INSERT INTO regexIamges( id , owner, descriptio, title, tags) VALUES('4292220054.0000000000000','23352125#N07','NoValue','IMG_2720','NoValue') was aborted. Call getNextException to see the cause.
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2743)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1928)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:405)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2892)
at uzh.textmining.RegexRemoverMain.main(RegexRemoverMain.java:116)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
and the table is:
CREATE TABLE "RegexImages"
(id numeric,
owner character varying(254),
descriptio character varying(254),
title character varying(254),
tags character varying(254),
PRIMARY KEY (id)
)
thanks hasnae;
I used try catch and I got that the tableName in my code does not match the table Name in database.
another problem was the name of the table: I change all the letters to lower case to solve all the errors.
A problem that looks similar: https://stackoverflow.com/a/39227828/755804
(spoiler:
The total number of values, that is, the number of columns multiplied by the number of rows must not exceed 32767 for a single INSERT statement.
You can divide 32767 by the number of columns to get the maximal number of rows per one SQL INSERT statement.)
Here is the original code which has defined String-Array (25). It is working perfectly. But I don't need to define it as 25. Instead, I used arraylist. Please check my code.
Using String of array:
public String[] getemailAddr(String strAccountnbr) throws Exception {
String strQuery2 = null;
ResultSet rs = null;
PreparedStatement ps = null;
String[] emailAddress = new String[25];
int i=0;
strQuery2 = "SELECT c.EmailAddress AS EmailAddress" +
" FROM customeremailid c " +
"WHERE c.AccountNbr = ? " ;
logMsg("strQuery2: "+strQuery2);
ps = getDBConn().prepareStatement(strQuery2);
ps.setString(1, strAccountnbr);
rs = ps.executeQuery();
while(rs.next())
{
emailAddress[i]=(rs.getString("EmailAddress"));
logMsg("emailAddress[i]"+" "+i+": "+emailAddress[i]);
i=i+1;
}
return emailAddress;
}
Here, I need to change String-Array to Arraylist. I tried something like this,
public String[] getemailAddr(String strAccountnbr) throws Exception {
String strQuery2 = null;
ResultSet rs = null;
PreparedStatement ps = null;
//Newly tried //
ArrayList<String> strArrEmailIds = new ArrayList<String>();
String[] emailAddress= new String[strArrEmailIds.size()];
strArrEmailIds.toArray(emailAddress);
//Newly tried //
int i=0;
strQuery2 = "SELECT c.EmailAddress AS EmailAddress" +
" FROM customeremailid c " +
"WHERE c.AccountNbr = ? " ;
logMsg("strQuery2: "+strQuery2);
ps = getDBConn().prepareStatement(strQuery2);
ps.setString(1, strAccountnbr);
rs = ps.executeQuery();
while(rs.next())
{
emailAddress[i]=(rs.getString("EmailAddress"));
logMsg("emailAddress[i]"+" "+i+": "+emailAddress[i]);
i=i+1;
}
return emailAddress;
}
Email ids are get from database instead of example.com.
But I am getting
java.lang.ArrayIndexOutOfBoundsException: 0 error
in this line.
emailAddress[i]=(rs.getString("EmailAddress"));
Please help!
This is not how you use an ArrayList.
First, you need to write:
List<String> strArrEmailIds = new ArrayList<>();
So, program to the interface and use the Java 7 diamond operator.
Next, remove the index i. You don't need this.
Finally, just do:
emailAddress.add(rs.getString("EmailAddress"));
To convert it back to an String[] you can then do:
String[] arr = emailAddress.toArray(new String[emailAddress.size()]);
Here is my suggestion for you final code:
public String[] getemailAddr(String strAccountnbr) throws Exception {
final List<String> emailAddress = new ArrayList<>();
final String strQuery2 = "SELECT c.EmailAddress AS EmailAddress"
+ " FROM customeremailid c "
+ "WHERE c.AccountNbr = ? ";
try (final PreparedStatement ps = getDBConn().prepareStatement(strQuery2)) {
ps.setString(1, strAccountnbr);
try (final ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
emailAddress.add(rs.getString("EmailAddress"));
}
}
}
return emailAddress.toArray(new String[emailAddress.size()]);
}
I have removed your pointless assignments to null. I have added try-with-resources blocks to close your external resources, you code was one massive memory leak.
If you have a ArrayList, then you dont need a array again, indeed a ArrayList is backed by Array itself and its dynamic in size.
List<String> emailAddress= new ArrayList<String>(); // dynamic array
...
while(rs.next()){
emailAddress.add((rs.getString("EmailAddress"));
...
}
return emailAddress.toArray(new String[emailAddress.size()]); // creating array of String type
And ArrayList#toArray converts List to Array which has done at last in the code.
declare it as
ArrayList<String> emailAddress= new ArrayList<String>();
...
emailAddress.add((rs.getString("EmailAddress"));
convert it to String[]:
return emailAddress.toArray(new String[emailAddress.size()]);
You use ArrayList here wrongly in your code. When you define
ArrayList<String> strArrEmailIds = new ArrayList<String>();
String[] emailAddress= new String[strArrEmailIds.size()];
strArrEmailIds.toArray(emailAddress);
strArrEmailIds by default has a size of 0, so the generated emailAddress array also gets a length of 0. Later in the while loop, you are trying to assign the value to the emailAddress[0], it will throw ArrayIndexOutOfBoundsException.
Instead, the correct way is :
ArrayList<String> strArrEmailIds = new ArrayList<String>();
//....
while(rs.next()){
//....
strArrEmailIds.add(rs.getString("EmailAddress"));
}
//....
String[] emailAddress = strArrEmailIds.toArray(new String[strArrEmailIds.size()]);
java.lang.ArrayIndexOutOfBoundsException: 0 if your result set goes beyond 25 itteration.
How to convert array to ArrayList ?
Arrays.asList(myArray)
in your case you can have a list and in the resulset itteration you can add them to the list like
List<String> emails = new ArrayList<String>();
while(...){
emails.add(rs.getString("EmailAddress"));
}
Hello I have the problem.. can anyone give me snippet? i have the table of MySql that display JList item so I can add the item easily but can't remove it from database? while pressing remove item?
I searched a lot no one has ever need of doing.. i wonder how its possible?
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con= (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","ubuntu123");
PreparedStatement stmt = null;
ResultSet rs = null;
String [] data;
data = new String[100];
int i=0;
DefaultListModel listmodel = (DefaultListModel) jList2.getModel();
int selectedIndex = jList2.getSelectedIndex();
if (selectedIndex != -1) {
listmodel.remove(selectedIndex);
String query = "delete from supplierinfo where companyname = ?";
stmt = (PreparedStatement) con.prepareStatement(query);
stmt.setInt(1, i);
stmt.execute();
con.close();
// i= i+1;
}
} catch(Exception e) {
System.out.println("3rd catch " +e);
}
}
You can save element in a variable when you remove it from ListModel.
After that you can get all important info about this item and use it in your query.
Use something like this:
YourObjectType obj = (YourObjectType) listmodel.remove(selectedIndex);
String query = "delete from supplierinfo where companyname = ?";
stmt = (PreparedStatement) con.prepareStatement(query);
stmt.setInt(1, obj.getCompanyName());
stmt.execute();
Use the ListModel#getElementAt(int) method with the currently selected index.
If you are certain your model only contains String instances, you can directly cast it to a String, then replace i with this string in stmt.setInt(1, i);
Am trying to select record from database where record id NOT IN list.
take a look # my problem below.
String Sqlids = "2,6,3,9"; // this is dynamic so the number of element is unknown
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN (2,6,3,9) ORDER BY NEWID()";
PreparedStatement stat = con.prepareStatement(str);
ResultSet rs = stat.executeQuery();
The above statement work FINE, but if i change it to
String Sqlids = "2,6,3,9";
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN (Sqlids) ORDER BY NEWID()";
PreparedStatement stat = con.prepareStatement(str);
ResultSet rs = stat.executeQuery();
//i also try this
String Sqlids = "2,6,3,9";
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN (?) ORDER BY NEWID()";
PreparedStatement stat = con.prepareStatement(str);
stat.setString(1,Sqlids );
ResultSet rs = stat.executeQuery();
THE ABOVE STATEMENT DOESN'T FILTER
Since Sqlids is one string is seeing it as one parameter so it return repeated rows, is there an integer format for storing values like 2,6,3,9 ?
since the Sqlids is from an arraylist called SqlidList
i try somtin like this
Iterator iTr = SqlidList.iterator();
while(iTr.hasNext()){
stat.setString(1,iTr.next().toString()+",");
}
but the setString(1,--) is not available since is in a while loop
Use Connection#createArrayOf after converting your ids to a String[]
String[] ids = {"2", "6", "3", "9"};
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN ? ORDER BY NEWID()";
PreparedStatement stat = con.prepareStatement(str);
stat.setArray(1, con.createArrayOf("text",ids));
ResultSet rs = stat.executeQuery();
If createArrayOf is not supported by your JDBC driver (as in this case) I'd probably just construct the query string in place e.g:
String Sqlids = "2,6,3,9";
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN ("+Sqlids+") ORDER BY NEWID()";
or if you have a collection of ids use a utility method to create the array content:
public static String toSqlArray(List<String> strings) {
StringBuilder sb = new StringBuilder();
boolean doneOne = false;
for(String str: strings){
if(doneOne){
sb.append(", ");
}
sb.append("'").append(str).append("'");
doneOne = true;
}
return sb.toString();
}
The way I've solved the problem is :
SQL = "...WHERE ID NOT IN ({0}) ..."
have a method which builds a string containing a number of ? equal to the size of SqlidList
public static String buildQuestionMarks(final int count) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
sb.append("?" + ",");
}
return sb.substring(0, sb.length() - 1);
}
use java.text.MessageFormat.format() to insert the list of ? into the sql
String finalSql = MessageFormat.format(SQL, questionMarksString);
have a method to set the params on teh prepared statement. Something similar to what you wrote although you need to increment the first parameter of stat.setString()
This should work for variable number of parameters.
Did you tried using
int[] array = {2,6,3,9};
String str= "SELECT TOP 1 * FROM student WHERE ID NOT IN (?,?,?,?) ORDER BY NEWID()";
PreparedStatement stat = con.prepareStatement(str);
for(int i = 1; i <= array.length; i++)
stat.setString(i,array[i - 1]);
ResultSet rs = stat.executeQuery();