I have written code which should call MSSQL 2005 procedure from my servlet. The problem is the procedure is to SELECT data from table so I want to get ResultSet but the result set is never returns :( I tested the procedure with another procedure and it works, moreover, the client connection privileges are dbowner so there should be no problem with connection but still the execute returns false :(
Here is the problem code (current connection is connected I checked):
...
SQLServerCallableStatement callableStatement = null;
callableStatement = (SQLServerCallableStatement) connection.prepareCall(
"{call "+
DATABASE_NAME+
"."+
SCHEMA_NAME+
".select_item_proc(?,?,?)}");
callableStatement.setInt(1, 0);
callableStatement.setString(2, "value1");
callableStatement.setString(3, "value2");
boolean rs=callableStatement.execute();
if(rs)
{
ResultSet result=callableStatement.getResultSet();
while (result.next()) {
String col1= result.getString(1);
String col2=result.getString(2);
System.out.print(col1+",");
System.out.println(col2);
}
}
...
So I need your fresh sight what the problem really can be? Any useful comment is appreciated
Please try using ResultSet rs = callableStatement.executeQuery(); instead of the boolean rs=callableStatement.execute(); line.
Related
public static void main(String args[])
{
SQLConnector sqlConnect = new SQLConnector();
Connection conn = null;
try
{
conn= sqlConnect.getConnection();
CallableStatement cStmt = conn.prepareCall("{ call test(?,?,?)}");
cStmt.setDouble(1, 100.0);
cStmt.setInt(2, 1);
cStmt.registerOutParameter(3, java.sql.Types.VARCHAR);
ResultSet rs = cStmt.executeQuery();
if (rs.next()) {
System.out.println(rs.getString(3);
}
cStmt.execute();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
sqlConnect.closeConnection(conn);
}
}
This snippet throws the error
java.sql.SQLException: ResultSet is from UPDATE. No Data.
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
But if I pass the same parameters from MySQL Workbench it gives proper output.
I am using MySQLServer 5.6.25 and MySQLConnector 5.1.6.
Please help me solve this problem. This looks like a bug in the way I call MySQL from Java
See section 4 of this MySQL documentation page: Using JDBC CallableStatements to Execute Stored Procedures.
You don't use executeQuery(). You have to use execute() and getResultSet().
Since you know the statement will return exactly one ResultSet, your code becomes:
cStmt.execute();
try (ResultSet rs = cStmt.getResultSet()) {
if (rs.next())
System.out.println(rs.getString(3));
}
Except of course you might be wrong, because the call doesn't return a result set, but instead returns a string in an output parameter, and that totally changes the code:
cStmt.execute();
System.out.println(cStmt.getString(3));
Remove the below line in your code to resolve the issue:
cStmt.execute();
it's all about changes in your procedure
remove into declared_veritable from procedure
because at the end you will get all data from result-set only so no need to provide into clause in your select query of procedure.
Here's how I'm able to execute my stored procedure through SqlDeveloper
var p refcursor;
exec DMG.Getstudentids(12342343,:p);
print p;
Output
P
-----------
STUDENT_ID
-----------
23432425
54353455
Now I'm trying execute the stored procedure the same way but in Java. Here's my code and I'm missing something about the input/output parameters or their datatypes.
Connection connection = DriverManager.getConnection(url, user, pass);
CallableStatement cs = connection.prepareCall("{call DMG.Getstudentids(?,?)}");
cs.setFloat(1, 12342343);
cs.registerOutParameter(2, Types.OTHER);
cs.execute();
List<Integer> result = (List<Integer>) cs.getArray(2);
I get the following error
java.sql.SQLException: Invalid column type: 1111
I think I'm missing something fundamental here. Anyone see where I'm failing? Thanks.
Try following:
Connection connection = DriverManager.getConnection(url, user, pass);
CallableStatement cs = connection.prepareCall("{call DMG.Getstudentids(?,?)}");
cs.setFloat(1, 12342343);
cs.registerOutParameter(2, OracleTypes.CURSOR);
cs.executeQuery();
ResultSet resultSet=cs.getObject(1);
List<Integer> result = new ArrayList<Integer>();
while(resultSet.next()){
result.add(resultSet.getInt(STUDENT_ID));
}
Note : Since the procedure is returning refcursor, you need to register OracleTypes.CURSOR as output parameter.
Nother thing to note is you need to catch the whole dataset(refcursor) into Result Set, iterate it and put the extracted value into List.
I am unable to call my stored procedure from java hibernate using session factory
I have written a sql procedure which takes 5 parameters and return a result set which works fine in MS SQL studio
EXEC SlaGrid #appID=245,#fromYear=2012,#toYear=2013,#fromMon=1,#toMon=12 --- sql
EXEC SlaGrid #applID=:applID,#fromYear=:fromYear,#toYear=:toYear,#fromMon=:fromMon,#toMon=:toMon --hibernate
i am setting the parameters for the above query
String queryString = "EXEC SlaGrid #applID=:applID,#fromYear=:fromYear,#toYear=:toYear,#fromMon=:fromMon,#toMon=:toMon"
Query query = sessionFactory.getCurrentSession().createSQLQuery(queryString);
//set query parameters here
query.list() --- giving sql grammer exception
You can use callable statement on hibernate session.
Connection con = getSessionFactory().getCurrentSession().connection();
/**
* Amend to include your parameters and proc
*/
CallableStatement cs = con.prepareCall( "{ call myprocedure }");
cs.execute();
create a SessionFactory and Open a session then
CallableStatement callableStatement = session.connection().prepareCall("call GetMarketDataCDS(?,?)");
callableStatement.setString(1,"JPM");
callableStatement.registerOutParameter(1, OracleTypes.CURSOR);
callableStatement.execute();
ResultSet resultSet=(ResultSet) callableStatement.getObject(1);
here i am using oracle and my first param is IN Parameter and second is OUT which is nothing but a resultset returning multiple rows.
Then in last line we get the ResultSet with all row and then you can iterate through the rows.
I solved it simply by the following code...Just pass the parameters in CSV.Thanks for the help guys..
String queryString = "SlaGrid 245,2012,2013,1,12"
Query query = sessionFactory.getCurrentSession().createSQLQuery(queryString);
query.list();
Works Perfect :)
Try this
Query query = sessionFactory.getCurrentSession().createSQLQuery(
"CALL SlaGrid(:appID, :fromYear, :toYear, :fromMon, :toMon)")
.setParameter("appID", 245)
.setParameter("fromYear", 2012)
.setParameter("toYear", 2013)
.setParameter("fromMon", 1)
.setParameter("toMon", 12);
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
I'm new to using Oracle so I'm going off what has already been previously answered in this SO question. I just can't seem to get it to work. Here's the statement that I'm using:
declare
lastId number;
begin
INSERT INTO "DB_OWNER"."FOO"
(ID, DEPARTMENT, BUSINESS)
VALUES (FOO_ID_SEQ.NEXTVAL, 'Database Management', 'Oracle')
RETURNING ID INTO lastId;
end;
When I call executeQuery the PreparedStatement that I have made, it inserts everything into the database just fine. However, I cannot seem to figure out how to retrieve the ID. The returned ResultSet object will not work for me. Calling
if(resultSet.next()) ...
yields a nasty SQLException that reads:
Cannot perform fetch on a PLSQL statement: next
How do I get that lastId? Obviously I'm doing it wrong.
make it a function that returns it to you (instead of a procedure). Or, have a procedure with an OUT parameter.
Not sure if this will work, since I've purged all of my computers of anything Oracle, but...
Change your declare to:
declare
lastId OUT number;
Switch your statement from a PreparedStatement to a CallableStatement by using prepareCall() on your connection. Then register the output parameter before your call, and read it after the update:
cstmt.registerOutParameter(1, java.sql.Types.NUMERIC);
cstmt.executeUpdate();
int x = cstmt.getInt(1);
I tried with Oracle driver v11.2.0.3.0 (since there are some bugs in 10.x and 11.1.x, see other blog). Following code works fine:
final String sql = "insert into TABLE(SOME_COL, OTHER_COL) values (?, ?)";
PreparedStatement ps = con.prepareStatement(sql, new String[] {"ID"});
ps.setLong(1, 264);
ps.setLong(2, 1);
int executeUpdate = ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next() ) {
// The generated id
long id = rs.getLong(1);
System.out.println("executeUpdate: " + executeUpdate + ", id: " + id);
}
When you prepare the statement set the second parameter to RETURN_GENERATED_KEYS. Then you should be able to get a ResultSet off the statement object.
You can use Statement.getGeneratedKeys() to do this. You just need to make sure to tell JDBC what columns you want back using one of the method overloads for that, such as the Connection.prepareStatement overload here:
Connection conn = ...
PreparedStatement pS = conn.prepareStatement(sql, new String[]{"id"});
pS.executeUpdate();
ResultSet rS = pS.getGeneratedKeys();
if (rS.next()) {
long id = rS.getLong("id");
...
}
You don't need to do the RETURNING x INTO stuff with this, just use the basic SQL statement you want.
Are you doing that in a stored procedure ? According to this Oracle document, it won't work with the server-side driver.
The Oracle server-side internal driver does not support
the retrieval of auto-generated keys feature.