I am trying to retrieve data from DB2 using Java prepared statement
String select_statement = "SELECT * FROM schema_name.table_name where NME='xxx002' and LINE =7200 and FILE_NME='720001042021XYZ002' with ur";
try (Connection connection = DataBaseConnection.getGeoCarDBConnection_TESTDATA();
PreparedStatement ps = connection.prepareStatement(select_statement);) {
ResultSet rs = null;
rs = ps.executeQuery();
}
The problem I am facing is that I include the FILE_NME in the where clause of the query, as shown above, 0 rows are returned. But any other string fields can be passed and I get the desired number of rows.
Any integer fields in the where clause works too.
But only the string fields that are large(In this case, FILE_NME field) are not working. In the DB2 table, where I am pulling the data from, the FILE_NME field is of varchar(30).
Things that did not work for me was
String select_statement = "SELECT * FROM schema_name.table_name where NME='xxx002' and LINE =7200 and FILE_NME = ? with ur";
then I set the String value using,
ps.setString(1, "'720001042021XYZ002'")
ps.setString(1, "720001042021XYZ002")
Both did not work.
None of the google links were helpful. Have spent more than a day on it.
This code used to work flawlessly before, Even the java version hasn't changed(as per my knowledge)
I am running it in windows 10.
Java version : 1.8 ((build 1.8.0_221-b11))
I run the same query in the database client and it works.
Someone please help me or point me in the right direction. I don't know what I am missing
Thank in advance
The problem was that there was indeed no data, I was checking the same query in the database client in a different environment. I am closing this.
Hello there and thanks for reading.
I'm trying to retrieve the ID of the newly inserted data, but I always get an empty ResultSet.
Connection con = main.getCon();
String sqlCommand = "Insert Into Relations(name,explanation) values(?,?)";
PreparedStatement state =
con.prepareStatement(sqlCommand,Statement.RETURN_GENERATED_KEYS);
state.setString(1,name.getText());
state.setString(2,explanation.getText());
int affectedRows = state.executeUpdate();
assert (affectedRows>0);
ResultSet rs = state.getGeneratedKeys();
assert rs.next();
int instertedID= rs.getInt("ID");
Not sure what's wrong with it. Checked different samples online, but couldn't figure out what's my mistake.
I also tried it with Statement, but no luck with that either.
Point 1: the code runs smoothly and my data in inserted into the database.
Point 2: there are examples online for this very case, you can check it here:
https://www.baeldung.com/jdbc-returning-generated-keys
I just realized that my ResultSet wasn't empty, I had problem with using my debugger and that's why I thought it was empty.
As Mark Rotteveel mentioned in a comment, the problem was with "assert" statement.
The problem is your use of assert rs.next(). Assertions in Java are intended for checking invariants (eg during testing), but when you normally run Java, assert statements are not executed, they are only executed when explicitly enabling this with the -ea commandline option.
As a result, rs.next() is not called, so your result set is still positioned before the first row when you call rs.getInt(1). Instead use if (rs.next()) { ... }.
This is DB engine dependent. Some tips:
JDBC is low-level and not appropriate to program with
It's a complicated API. Use something that makes it easier: JDBI, or JOOQ. They may have abstractions over insertion that takes care of this stuff for you.
Some DB engines require that you list the column name
Try:
con.prepareStatement(sqlCommand, new String[] {"UNID"});
Some DB engines will only return generated values as direct resultset
Don't call .executeUpdate(); instead, call .executeQuery() which returns a ResultSet; check that one.
Something else
Post the exact table structure and DB engine you're working with if the above doesn't help.
Your code is broken
You can't create resource objects (once that must be closed) unless you do so safely, and you're not doing so safely. Use try-with-resources:
String sql = "INSERT INTO relations(name, explanation) VALUES (?, ?)";
try (Connection con = main.getCon();
PreparedStatement ps = con.prepareStatement(sql, new String[] {"unid"})) {
state.setString(1, name.getText());
state.setString(2, explanation.getText());
try (ResultSet rs = state.executeQuery()) {
if (!rs.next()) throw new SQLException("insert didn't return autogen?");
System.out.println(rs.getInt(1));
}
}
ResultSets, Statements, PreparedStatements, and Connections are all resources (must be closed!) - if you want to store one of those things in a field, you can do that, but only if the class that contains this field is itself a resource: It must have a close() method, it must implement AutoClosable, and you can then only make instances of this class with try-with-resources as above.
Failure to adhere to these rules means your app seems to work, but is leaking resources as it runs, thus, if you let it run long enough, it will start crashing. Also, your DB engine will grind to a halt as more and more connections are left open, stuck forever.
change the last line of code to this because the DBMS you are using may not support the getting value by column name so pass the index of that column:
int instertedID = rs.getInt(1);
String sqlCommand = "Insert Into Relations (name, explanation) values(?, ?)";
PreparedStatement state = con.prepareStatement(sqlCommand, Statement.RETURN_GENERATED_KEYS);
state.setString(1,name.getText());
state.setString(2,explanation.getText());
state.executeUpdate();
ResultSet resultSet = state.getGeneratedKeys();
if(resultSet.next()) {
System.out.println(resultSet.getInt(1)); //Indicate the corresponding column index value.
}
When I execute a query using PreparedStatement.executeQuery() from a Java application, I get a resultSet object with wrong values for one of the fields. When I use run the same query in SQL developer, then I see the values correctly.
For e.g. In my query output,I am able to see the values as below:
ID_TABLE VALUE_ID
-------------------------
1234 111111
1234 222222
5678 333333
5678 444444
But, in java, when I am iterating the result set in while loop, I have printed logs with rs.getString("ID_TABLE") and rs.getString("VALUE_ID") on a single line as
System.out.println(" Table Id= "+rs.getString("ID_TABLE")+" -Value Id= "+rs.getString("VALUE_ID"));
Here, I am getting in logs as Table Id=5678 -Value Id=222222 which is incorrect. I am always getting the same output in sql developer and it is running in a single thread only. Nothing is running in parallel.
I am using Oracle 12c (version-12.1) and jdk 1.7.0_45.
Do you think it's a Java side problem or Oracle side data fetching problem?
Please let me know if you need additional details.
Please find below my method code snippet:
Connection conn = null;
ResultSet res = null;
String strQuery = "SELECT ID_TABLE,VALUE_ID FROM AppTableDetails";
PreparedStatement pStmt = null;
conn = getConnection();
pStmt = conn.prepareStatement(strQuery);
res = pStmt.executeQuery();
while (res.next())
{
System.out.println("Table Id= "+res.getString("ID_TABLE")+" -Value Id= "+res.getString("VALUE_ID"));
}
One more thing, this error is occurring randomly and not every time when I run the process.
I'm having a weird problem with an Grails application accessing data. Going deeper I've isolated the problem to a plain java8 small application using PreparedStatement.executeQuery vs Statement.executeQuery.
Consider the following snippet of code:
// executes in milliseconds
directSql = "select top(10) * from vdocuments where codcli = 'CCCC' and serial = 'SSSS' ORDER BY otherField DESC;";
stmt = con.createStatement();
rs = stmt.executeQuery(directSql);
// More than 10 minutes
sqlPrepared = "select top(10) * from vdocuments where codCli = ? and serial = ? ORDER BY otherField DESC;";
PreparedStatement pStatement = con.prepareStatement( sqlPrepared );
pStatement.setString(1, "CCCC");
pStatement.setString(2, "SSSS");
rsPrepared = pStatement.executeQuery();
Same query.
Data comes from a view on SqlServer (2008, I think, have no access right now) from a table with more than 15 Million records. There are indexes for all needed fields and the same query (the first one) executed from console runs also quite fast.
If I execute the slow PreparedStatement query without the ORDER clause it also runs fast.
It looks clear to me that for any cause the database it's not using indexes and make a full scan when using preparedStatement, but maybe I'm wrong so I'm open to any idea.
I thought maybe the driver (sqlserver official latest and jtds has been tested) was holding the data waiting for any kind of EOF from connection but I've checked with tcpdump on my side and no data is received.
I can't find why this is happening so any idea will be welcomed.
Thank you in advanced!
I've finally found a solution, at least in for my case. I got it here http://mehmoodbluffs.blogspot.com.es/2015/03/hibernate-queries-are-slow-sql-servers.html . Telling (driver? sqlServer?) not to send parameters as Unicode have resolved the problem.
Current connection string it's now:
String connectionUrl = "jdbc:sqlserver://server:port;databaseName=myDataBase;sendStringParametersAsUnicode=false";
And now both direct queries and preparedStatements runs at millisecond speed.
Thank you #DanGuzman for your suggestions!
I'm using java to do batch inserts into a mysql table:
cnx = lconnect.openConnection();
mStatement = cnx.createStatement();
boolean firstTime = true;
PreparedStatement preparedStatement = null;
preparedStatement = cnx.prepareStatement(strQuery);
preparedStatement.setString(param1);
preparedStatement.setString(param2);
....
preparedStatement.addBatch();
preparedStatement.setString(param1);
preparedStatement.setString(param2);
preparedStatement.addBatch();
preparedStatement.setString(param1);
preparedStatement.setString(param2);
preparedStatement.execute();
Is there any way to really know the number of inserted lines ?
I think my piece of code it's working (?) by the number of lines in the DB does not match with the number of lines supposed to be inserted, so I'm thinking I have a problem with y inserts maybe.
You have to call executeBatch(). The returned array contains the information you want.
From the JavaDoc:
Returns:
an array of update counts containing one element for each command in the batch. The elements of the array are ordered according to the
order in which commands were added to the batch.
Use PreparedStatement object for each batch record :)