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.
Related
I have return Db2 procedure which is returning cursor for one of table.
This procedure is called from my java code and truing to retrieve cursor as a result set and having flowing SQLexception exception log,
com.ibm.db2.jcc.am.jo: [jcc][t4][10335][10366][4.7.85]
Invalid operation: Connection is closed. ERRORCODE=-4470, SQLSTATE=08003
at com.ibm.db2.jcc.am.dd.a(dd.java:666)
at com.ibm.db2.jcc.am.dd.a(dd.java:60)
I searched solution for this exception and found this solution on ibm website link which suggest to change log configuration,
Increase the log file size and the number of primary and secondary log
files. The num_log_span value can also be adjusted.
Here is procedure example,
CREATE OR REPLACE PROCEDURE ABC(c_dump OUT SYS_REFCURSOR) IS
BEGIN
open c_dump FOR
select feild1,feild1,.... from RSPNSE_TABLE;
END;
Java Code is given below,
public void callStoredProc(){
Connection dbConnection = null;
CallableStatement callableStatement = null;
ResultSet rs = null;
String proc = "{call ABC(?)}";
try {
dbConnection = connection;
callableStatement = dbConnection.prepareCall(proc);
callableStatement.registerOutParameter(1, DB2Types.CURSOR);
// execute getDBUSERCursor store procedure
callableStatement.executeUpdate();
// get cursor and cast it to ResultSet
rs = (ResultSet) callableStatement.getObject(1);
} catch (SQLException e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
Now in this java code is breaking at this line callableStatement = dbConnection.prepareCall(proc);
Note: Despite exception log contains "Connection is closed" text I want to mention that I had successfully established the connection with database normal retrieval using JDBC does not have problem.
The prepare call failing indicates you don't have an open connection. You'll have to dig into the SQLException and determine exactly why.
I am trying to call a procedure defined with a PL/SQL package in a Java program.
I am aware one can call stored procedures using connection.prepareCall in Jdbc. But there is very little information out there on how to call a procedure within a package.
I am at a stage in development where i am still considering what db framework to use. Just wondering what are the pros and cons of using JDBC for PLSQL ? For this usecase are there better alternatives to JDBC ?
Follow the simple steps below:
public static final String SOME_NAME = "{call schema_name.org_name_pkg.return_something(?,?)}"; // Change the schema name,packagename,and procedure name.
// Simple JDBC Connection Pooling
// Here I am passing param companyId which is IN param to stored procedure which will return me some value.
Connection conn = null;
CallableStatement stmt = null;
ResultSet rset = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://hostname:port/dbname","username", "password");
stmt = conn.prepareCall(SOME_NAME);//We have declared this at the very top
stmt.setString(1, companyid);//Passing CompanyID here
stmt.registerOutParameter(2, OracleTypes.CURSOR);//Refcursor selects the row based upon query results provided in Package.
stmt.execute();
rset = (ResultSet) stmt.getObject(2);
while (rset.next()) {
String orgId=rset.getString("RPT_ORG_ID");
// When using refcursor easy to get the value just by using Column name
String orgName=rset.getString("RPT_ORG_NAME");
// Some Logic based what do you want to do with the data returned back from query
} catch (Exception e) {
LOGGER.error("Error extracting ", e);
} finally {
DBUtils.cleanUp(conn, stmt, rset);
}
// Clean and close you connection
I have a java class from which i am connecting to the SQL Server 2008 which is on a remote machine.I Can retrieve data using a class which means the connection is working fine.
But when i try to run a stored procedure it gives me
Exception as com.microsoft.sqlserver.jdbc.SQLServerException - Invalid JDBC data type -10.
Find the code below. Can anyone help me with this? I have added the sqljdbc, sqljdbc4 jars to my class buildpath.
CallableStatement cs=null;
con = SqlConnectionManager.getConnection();
cs = con.prepareCall("{call dbo.PKG_ER_SEL.sp_ERGetJobCode(?,?,?)}");
cs.setInt(1, orgId);//v_org
cs.setString(2, compCode);//v_type
cs.registerOutParameter(3, OracleTypes.CURSOR); //getting exception here
cs.executeUpdate();
ResultSet resultSet = (ResultSet) cs.getObject(3);
if (resultSet != null) {
while ( resultSet.next() ) {
JobVO obj = new JobVO();
obj.setCode(resultSet.getString("CODE"));
obj.setName(resultSet.getString("NAME"));
seqAttList.add(obj);
}
resultSet.close();
}
}catch(Exception e){
e.printStackTrace();
}finally{
SqlConnectionManager.releaseConnection(con);
}
Thanks
In JAVA get the ResultSet from the call to executeQuery on the Statement object. The ResultSet instance is the equivalent of a CURSOR in T-SQL. Read some more about using ResultSet here.
For SQL Server you call/execute a stored procedure as detailed here. A simple example would be EXECUTE my_stored_procedure if your stored procedure is called my_stored_procedure.
Given a simple stored procedure which has a table with a single column of integers as argument:
CREATE PROCEDURE [dbo].[table_sel]
#tbl INT32Table READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT value FROM #tbl
END
How do I execute this stored procedure from Java? From C# this does what I want:
SqlConnection sqlconn;
System.Data.DataTable tbl = new System.Data.DataTable("INT32Table", "dbo");
tbl.Columns.Add("value", typeof(int));
tbl.Rows.Add(2);
tbl.Rows.Add(3);
tbl.Rows.Add(5);
tbl.Rows.Add(7);
tbl.Rows.Add(11);
using (SqlCommand command = new SqlCommand("table_sel"))
{
command.Connection = sqlconn;
command.Parameters.AddWithValue("#tbl", tbl);
command.CommandType = System.Data.CommandType.StoredProcedure;
SqlDataReader reader = command.ExecuteReader();
//do stuff
}
Oh sorry,
as far as I know there's no such table object in Java, you can use cs.setObject() but then again you should obtain that object from somewhere (query on mssql server ?).
If you're looking for performance on inserts with JDBC then you should consider preparedStatements and batch execution.
java.sql.connection connection = //driver, url, database, credentials ...
try
{
PreparedStatement ps =
connection.prepareStatement("insert into tbl values (?)");
ps.setInt(1, your 1st int);
ps.addBatch();
ps.setInt(1, your 2nd int);
ps.addBatch();
ps.setInt(1, your 3rd int);
ps.addBatch();
ps.executeBatch();
}
catch (SQLException e)
{
// err handling goes here
}
finally
{
// close your resources
}
Regards
S
You Cannt pass TVP's using JDBC. The Microsoft JDBC team is still working on this as they mentioned 2 years ago. Refer the Link :
visit : http://blogs.msdn.com/b/jdbcteam/archive/2012/04/03/how-would-you-use-table-valued-parameters-tvp.aspx
Try some alternate solution instead of using TVP's by passing XML parameter and with OPENXML() in procedure body.
In Java you should use CallableStatement.
eg.
java.sql.connection connection = //driver, url, database, credentials ...
try
{
CallableStatement cs =
connection.prepareCall("{ call table_sel(?) }");
cs.setInt(1, your int);
cs.execute();
}
catch (SQLException e)
{
// err handling goes here
}
finally
{
// close your ressources
}
Regards
S
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.