Java jdbc Resultset data not updated if any change in database - java

I'm using TYPE_SCROLL_SENSITIVE so that my resultset is sensitive to any changes,
Now what i have understood, while reading from database resultset maintained cursor in the database
.Any (commit)changes to tuples in the database while reading must be reflected in result.
But this not happening in my scenario.
i m using mysql.
Is resultset caching in memory ????
PreparedStatement st = con.prepareStatement("SELECT name FROM user",ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
ResultSet res = st.executeQuery();
res.setFetchSize(1);
while (res.next()) {
System.out.println(res.getString("name"));
bufferRead.readLine(); //hold
}

Related

Resultset is slow for oracle ref cursor

Getting a cursor result set from procedure and iterating it is much slower than query result set. I have a procedure which returns a cursor but it took 5s to fetch the next result set.
String callProcedure = "{ call SCHEMANAME.TEMP_PACKAGE.GET_CURSOR_RESULTS(?,?,?,?) }";
cs = con.prepareCall(callProcedure);
cs.setString(1, "Variable1");
cs.setString(2,"Variable2");
cs.setString(3,"Variable3");
cs.registerOutParameter(4, OracleTypes.CURSOR);
ResultSet rs = (ResultSet) cs.getObject(4);
while (rs.next()){
}
I have used logs and found that rs.next() get 5-6 seconds.
So I have changed the logic as below,
String callProcedure = "{ call SCHEMANAME.TEMP_PACKAGE.GET_CURSOR_RESULTS(?,?,?,?,?) }";
cs = con.prepareCall(callProcedure);
cs.setString(1, "Variable1");
cs.setString(2,"Variable2");
cs.setString(3,"Variable3");
cs.registerOutParameter(4,java.sql.Types.VARCHAR);
cs.registerOutParameter(5,java.sql.Types.INTEGER);
I got those parameters from the procedure and use a preparedStatement to execute the query which was used in the cursor.
PreparedStatement ps = con.prepareStatement(query);
ResultSet rs = ps.executeQuery();
while (rs.next()){
}
Above approach is faster than using a sys_refcursor. Please explain why using sys_refcursor taking much time than a normal query.
PS: Cursor will not return more than 20 rows.
Thanks.
this should be helpful
http://docs.oracle.com/cd/E11882_01/java.112/e16548/resltset.htm#JJDBC28621
By default, when Oracle JDBC runs a query, it retrieves a result set
of 10 rows at a time from the database cursor. This is the default
Oracle row fetch size value. You can change the number of rows
retrieved with each trip to the database cursor by changing the row
fetch size value.
Statement, PreparedStatement, CallableStatement, and ResultSet objects for setting and getting the fetch size:
void setFetchSize(int rows) throws SQLException
int getFetchSize() throws SQLException

DatabaseChangeNotification is not triggering when blob content is updated

When I updated blob in Database, DatabaseChangeNotification has to trigger but it's not happening.
Working fine with normal string/varchar but it's not working with blob.
I am trying as below
OracleConnection conn = connect();
Properties prop = new Properties();
prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS,"true");
prop.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION,"true");
DatabaseChangeRegistration dcr = conn.registerDatabaseChangeNotification(prop);
try {
DCNDemoListener list = new DCNDemoListener(this);
dcr.addListener(list);
Statement stmt = conn.createStatement();
((OracleStatement) stmt).setDatabaseChangeRegistration(dcr);
ResultSet rs = stmt.executeQuery("select * from TEST_MODEL");
rs.close();
stmt.close();
stmt = conn.createStatement();
ResultSet rss = stmt.executeQuery("select TESTSUITE_NAME,TESTSUITE_DEFINITION from TESTSUITE_MODELS");
while (rss.next()) {
System.out.println(rss.getString("TESTSUITE_NAME"));
System.out.println(rss.getBlob("TESTSUITE_DEFINITION"));
}
rss.close();
stmt.close();
Can anyone help me in this?
If I am trying to query table which conatian blob column I am getting "ORA-29977: Unsupported column type for query registration in guaranteed mode for blolb" exception
ResultSet rss = stmt.executeQuery("select TESTSUITE_NAME,TESTSUITE_DEFINITION from TESTSUITE_MODELS");
I haven't used database change notification (thanks for the hint, looks quite interesting!), but found the following in the documentation:
To be registered for QRCN in guaranteed mode, a query must conform to the following rules:
Every column that it references is either a NUMBER data type or a VARCHAR2 data type.
The section about QRCN in best effort mode seems not to have this restriction.
Does anybody know how to use the best effort mode from JDBC?

Why does this Query return NULL?

I have a derby users database which I query, when the user clicks login on the application.
However, when I query the users table with the parameter [user] derby returns a null Object instead of the record it ought to return.
Here is my code:
String ssql = "SELECT * FROM USERS WHERE UNAME LIKE ?";
try{
DriverManager.registerDriver(new org.apache.derby.jdbc.EmbeddedDriver());
con = DriverManager.getConnection(url);
sql = con.prepareStatement(ssql, Statement.RETURN_GENERATED_KEYS);
sql.setString(1, cbox_chooseUser.getSelectedItem().toString());
sql.executeQuery();
ResultSet rs = sql.getGeneratedKeys();
try{
while (rs.next()) {
if(rs.getString("PW").toCharArray().equals(txt_password.getPassword())){
sql.close();
con.close();
return true;
}
} catch (NPE ...) {...}
}
I tried it multiple times wit a test user with both the pw and the username set to "test"; but I always get the same error.
Why is the recordset always Null?
Thanks for your help :)
The documentation says
ResultSet getGeneratedKeys() throws SQLException
Retrieves any auto-generated keys created as a result of executing this Statement
object.
If this Statement object did not generate any keys, an empty
ResultSet object is returned.
Your select statement isn't generating any keys that's why it's returning an empty ResultSet. You aren't inserting anything hence no keys are being generated.
You can try ResultSet rs = sql.executeQuery();. It should work.
You are using it in wrong way.
The generated keys concept should be used only in the case DML of insert type query but not in the case of select query.
select simply select the rows from the table. In this case there is no chance of any keys getting generated.
In the case of insert query if any column is configured as auto increment or kind of functionality then some keys will get generated. These keys can be caught using Statement.RETURN_GENERATED_KEYS in java.
As you are using select query there is no need of using Statement.RETURN_GENERATED_KEYS.
You just modify below lines and everything will be fine.
sql = con.prepareStatement(ssql, Statement.RETURN_GENERATED_KEYS);
sql.setString(1, cbox_chooseUser.getSelectedItem().toString());
sql.executeQuery();
ResultSet rs = sql.getGeneratedKeys();
with
sql = con.prepareStatement( ssql );
sql.setString( 1, cbox_chooseUser.getSelectedItem().toString() );
ResultSet rs = sql.executeQuery();

Getting a result back from a stored procedure in Java

I am having the hardest time calling an Oracle stored procedure from a java runtime environment. The stored procedure that I am calling has 2 parameters 1 in and 1 out. Here is how I call the stored procedure... How do you get the resultSet from an Oracle ref_cursor
ds = (DataSource)initialContext.lookup("JDBC/EPCD13DB");
conn = ds.getConnection();
callableStatement = conn.prepareCall(storedProcCall);
callableStatement.setString(1, input1);
callableStatement.registerOutParameter(2, OracleTypes.CURSOR);
callableStatement.execute();//(ResultSet) callableStatement.getObject(1);
ResultSet rs = callableStatement.getResultSet();
while(rs.next()){
Provider tempProv = new Provider();
tempProv.setResourceId(rs.getLong("res_id"));
tempProv.setFirstName(rs.getString("First_Name"));
tempProv.setLastName(rs.getString("Last_Name"));
tempProv.setMiddleName(rs.getString("Middle_Name"));
ObjList.add(tempProv);
}
rs.close();
You should be able to retrieve the ResultSet with:
ResultSet rSet = (ResultSet)callableStatement.getObject(2);
Does this help you? Seems like you have to call getObject and cast it into a result set before querying on the result set.
Credit:: http://www.mkyong.com/jdbc/jdbc-callablestatement-stored-procedure-cursor-example/
I believe it returns only one output(oracle cursor)
ResultSet rs=(ResultSet) callableStatement.getObject(2);
and then iterate your cursor result set for records inside:
while(rs.next()){
Provider tempProv = new Provider();
tempProv.setResourceId(rs.getLong("res_id"));
tempProv.setFirstName(rs.getString("First_Name"));
tempProv.setLastName(rs.getString("Last_Name"));
tempProv.setMiddleName(rs.getString("Middle_Name"));
ObjList.add(tempProv);
}
In spring framework fetching database cursor results can be easily achieved. It has inbuilt classes like maprow, storedprocedure to serve the purpose. PFB the link
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/jdbc.html#jdbc-simple-jdbc-call-1

Result Set Problem

It is possible to Use two query with in single ResultSet
A result set corresponds to a single SQL query. However your "single" query could use UNION to effectively combine more than one query.
No you should not do this.
For example
ResultSet rs = null;
Statement stmt1 = con.createStatement("Query1");
Statement stmt2 = con.createStatement("Query2");
rs = stmt1.executeQuery();
while(rs.next()){
}
//Here result set should be closed before assigning new result set to "rs" variable like
stmt1.close();
rs.close();
rs = stmt2.executeQuery();
You should close old result set before using it again. If you don't close the old resultset object then it will be in memory and never be garbage collected.
If you close the DB connection object in this case(without closing resultset properly) then connection object is not garbage collected(not retuned to pool) as connection have reference(i.e. unclosed resultset).

Categories