I need to execute procedure from sql using java.
I have call my procedure in sql management like exec MyProcedure and works well.
But when I use it in java code I get error :
The statement did not return a result set.
This is my code:
ResultSet rs = null;
PreparedStatement cs = null;
Connection conn = DbM.dbConnect();
try {
cs = conn.prepareStatement("exec MyProcedure ?,?,?");
cs.setEscapeProcessing(true);
cs.setQueryTimeout(90);
cs.setString(1, "1");
cs.setString(2, "2019-01-01");
cs.setString(3, "2019-02-02");
rs = cs.executeQuery();
ArrayList<Data> listaObjectX = new ArrayList<Data>();
while (rs.next()) {
Data to = new Data();
to.setEmployeNo(rs.getString(1));
to.setValidFrom(rs.getDate(2));
to.setValidTo(rs.getDate(3));
listaObjectX.add(to);
}
} catch (SQLException se) {
System.out.println("Error al ejecutar SQL"+ se.getMessage());
se.printStackTrace();
throw new IllegalArgumentException("Error al ejecutar SQL: " + se.getMessage());
} finally {
try {
rs.close();
cs.close();
conn.close();;
} catch (SQLException ex) {
ex.printStackTrace();
}
}
When run code I got error:
The statement did not return a result set.
Any idea how to solve this problem?
If I put cs= conn.prepareStatement("exec MyProcedure (?,?,?)");
I get error
Incorrect syntax near '#P0'
If this procedure is not returning a result, you should be using execute() instead of executeQuery() which is expected to always return a ResultSet.
Related
I'm not sure the best practice for this, but my overall problem is that I can't figure out why my connection isn't closing.
I'm basically iterating through a list, and then inserting them into a table. Before I insert them into a table, I check and make sure it's not a duplicate. if it is, I update the row instead of inserting it. As of now, I can only get 13 iterations to work before the debug lets me know I had a connection not close.
Since I have 2 connections, I'm having trouble figuring out where I'm suppose to close my connections, and I was trying to use other examples to help. Here is what I got:
Connection con = null;
PreparedStatement stmt = null;
PreparedStatement stmt2 = null;
ResultSet rs = null;
Connection con2 = null;
for (Object itemId: aList.getItemIds()){
try {
con = cpds2.getConnection();
stmt = con.prepareStatement("select [ID] from [DB].[dbo].[Table1] WHERE [ID] = ?");
stmt.setInt(1, aList.getItem(itemId).getBean().getID());
rs = stmt.executeQuery();
//if the row is already there, update the data/
if (rs.isBeforeFirst()){
System.out.println("Duplicate");
stmt2 = con2.prepareStatement("UPDATE [DB].[dbo].[Table1] SET "
+ "[DateSelected]=GETDATE() where [ID] = ?");
stmt2.setInt(1,aList.getItem(itemId).getBean().getID());
stmt2.executeUpdate();
}//end if inserting duplicate
else{
con2 = cpds2.getConnection();
System.out.println("Insertion");
stmt.setInt(1, aList.getItem(itemId).getBean().getID());
//Otherwise, insert them as if they were new
stmt2 = con.prepareStatement("INSERT INTO [DB].[dbo].[Table1] ([ID],[FirstName],"
+ "[LastName],[DateSelected]) VALUES (?,?,?,?)");
stmt2.setInt(1,aList.getItem(itemId).getBean().getID() );
stmt2.setString(2,aList.getItem(itemId).getBean().getFirstName());
stmt2.setString(3,aList.getItem(itemId).getBean().getLastName() );
stmt2.setTimestamp(4, new Timestamp(new Date().getTime()));
stmt2.executeUpdate();
}//End Else
}catch(Exception e){
e.printStackTrace();
}//End Catch
finally{
try { if (rs!=null) rs.close();} catch (Exception e) {}
try { if (stmt2!=null) stmt2.close();} catch (Exception e) {}
try { if (stmt!=null) stmt.close();} catch (Exception e) {}
try { if (con2!=null) con2.close();} catch (Exception e) {}
try {if (con!=null) con.close();} catch (Exception e) {}
}//End Finally
} //end for loop
Notification.show("Save Complete");
This is my pooled connection:
//Pooled connection
cpds2 = new ComboPooledDataSource();
try {
cpds2.setDriverClass("net.sourceforge.jtds.jdbc.Driver");
} catch (PropertyVetoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //loads the jdbc driver
cpds2.setJdbcUrl( "jdbc:jtds:sqlserver://SERVERNAME;instance=DB" );
cpds2.setUser("username");
cpds2.setPassword("password");
cpds2.setMaxStatements( 180 );
cpds2.setDebugUnreturnedConnectionStackTraces(true); //To help debug
cpds2.setUnreturnedConnectionTimeout(2); //to help debug
My main questions are, am i closing my connections right? Is my connection pool set up right?
Should I be closing the connection inside the for loop or outside?
Is my problem with c3p0? Or JTDS?
It's great that you are working to be careful to robustly close() your resources, but this is overly complicated.
Unless you are using a pretty old version of Java (something prior to Java 7) you can use try-with-resources, which really simplifies this stuff. Working with two different Connections in one logic unit-of-work invites misunderstandings. Resources should be a close()ed as locally to their use as possible, rather than deferring everything to the end.
Your Exception handling is dangerous. If an Exception occurs that you don't understand, you might want to print its stack trace, but your code should signall the fact that whatever you were doing didn't work. You swallow the Exception, and even notify "Save Complete" despite it.
All this said, your life might be made much easier by a MERGE statement, which I think SQL Server supports.
Here is an (untested, uncompiled) example reorganization:
try ( Connection con = cpds2.getConnection() ) {
for (Object itemId: aList.getItemIds()){
boolean id_is_present = false;
try ( PreparedStatement stmt = con.prepareStatement("select [ID] from [DB].[dbo].[Table1] WHERE [ID] = ?") ) {
stmt.setInt(1, aList.getItem(itemId).getBean().getID());
try ( ResultSet rs = stmt.executeQuery() ) {
id_is_present = rs.next();
}
}
if ( id_is_present ) {
System.out.println("Duplicate");
try ( PreparedStatement stmt = con.prepareStatement("UPDATE [DB].[dbo].[Table1] SET [DateSelected]=GETDATE() where [ID] = ?") ) {
stmt.setInt(1,aList.getItem(itemId).getBean().getID());
stmt.executeUpdate();
}
} else {
System.out.println("Insertion");
try ( PreparedStatement stmt = con.prepareStatement("INSERT INTO [DB].[dbo].[Table1] ([ID],[FirstName], [LastName],[DateSelected]) VALUES (?,?,?,?)") ) {
stmt.setInt(1,aList.getItem(itemId).getBean().getID() );
stmt.setString(2,aList.getItem(itemId).getBean().getFirstName());
stmt.setString(3,aList.getItem(itemId).getBean().getLastName() );
stmt.setTimestamp(4, new Timestamp(new Date().getTime()));
stmt.executeUpdate();
}
}
}
Notification.show("Save Complete");
}
I have a stored procedure in Oracle Database like this:
CREATE OR REPLACE PROCEDURE PSTATISTIC
AS
BEGIN
UPDATE PLACE_STATISTIC
SET POPULARITY = 0;
UPDATE PLACE_STATISTIC
SET POPULARITY = POPULARITY + 1
WHERE PLACE_ID IN (SELECT PLACE_COMMENT.PLACE_ID
FROM PLACE_COMMENT);
END PSTATISTIC;
When I called it on SQL Developer:
EXECUTE PSTATISTIC
It executed normally, the PLACE_STATISTIC table was updated
But when I tried to use it on Java:
String sql="EXECUTE HR.PSTATISTIC";
Statement statement=(Statement)connectionDB.createStatement();
statement.execute(sql);
It didn't work out on Java, citing sort of errors:
java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:395)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:802)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:521)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:194)
at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:1000)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307)
at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1882)
at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1847)
at oracle.jdbc.driver.OracleStatementWrapper.execute(OracleStatementWrapper.java:301)
How can I execute my PSTATISTIC procedure on Java? I granted all necessary privileges
To execute a stored procedure from Java code, you need to use CallableStatement. Statement cant be used to execute Stored Proc.
Connection con = getConnection();
CallableStatement cs = null;
try {
cs = con.prepareCall("{call EXECUTE PSTATISTIC}");
cs.execute();
} catch (SQLException e) {
System.err.println("SQLException: " + e.getMessage());
}
finally {
if (cs != null) {
try {
cs.close();
} catch (SQLException e) {
System.err.println("SQLException: " + e.getMessage());
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
System.err.println("SQLException: " + e.getMessage());
}
}
}
}
You need to use CallableStatement for executing your Stored procedure
String procName= "{call PSTATISTIC}";
CallableStatement cs = conn.prepareCall(procName);
cs.executeQuery();
I'm trying to get information from a MySQL database. I can connect and do things such as insert data into tables fine, and although I receive a ResultSet, I can't read it. Here's my code:
public ResultSet executeQuery(String query) {
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(query);
if (stmt.execute(query)) {
rs = stmt.getResultSet();
}
return rs;
}
catch (SQLException ex){
System.err.println("SQLException: " + ex.getMessage());
System.err.println("SQLState: " + ex.getSQLState());
System.err.println("VendorError: " + ex.getErrorCode());
}
finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) { } // ignore
stmt = null;
}
}
return null;
}
Trying to read the ResultSet:
ResultSet set = executeQuery("SELECT rank FROM players");
try {
while(set.next()) {
System.out.println(set.getInt("rank") + "");
}
} catch(Exception ex) {
ex.printStackTrace();
} finally {
try {
set.close();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
I get this error:
java.sql.SQLException: Operation not allowed after ResultSet closed
I've been looking around the internet and on different forums all day. What's wrong with my code?
Your finally block in executeQuery closes your statement before you've iterated over the results.
Well, two things -
1) I do not get why you have both execute() and executeQuery() in your method? I think executeQuery() should work for you.
2) Do not close the statement before iterating through resultset. Make it an instance variable and close it after iterating.
TL;DR Your executeQuery closes the Statement.
From the JavaDoc for Statement.close
Releases this Statement object's database and JDBC resources
immediately instead of waiting for this to happen when it is
automatically closed.
You close() your Statement before you read your ResultSet. Closing a Statement causes all of the ResultSet instances associate with that Statement to also be closed.
You need to pass in a Consumer<ResultSet> into a different method, and process the ResultSet whilst the Statement is open:
public void executeQuery(final String query, final Consumer<ResultSet> consumer) {
try(final Statement stmt = conn.createStatement();
final ResultSet rs = stmt.executeQuery(query)) {
consumer.accept(rs);
}
catch (SQLException ex){
System.err.println("SQLException: " + ex.getMessage());
System.err.println("SQLState: " + ex.getSQLState());
System.err.println("VendorError: " + ex.getErrorCode());
}
}
I have also fixed your code:
I have replaced your try..finally with a try-with-resources
You execute your query twice by calling stmt.executeQuery(query) and then stmt.execute(query). This is not only wasteful, but you lose the reference to the first ResultSet and if Statement.close didn't close all the associated resultsets you would have had a memory leak.
I need to get the output of a jdbc query, but wherever I google, it returns a resultset. But, its just a single row. Here is my query
ResultSet rsLocationId = null;
rsLocationId = stmtLocation.executeQuery("SELECT apmcid FROM userbusinesstoapmc WHERE userbusinessid='"+userBusinessKey+"'");
It should return a single record as a string. How can I convert it? Any ideas would be greatly appreciated.
I suggest you use PreparedStatement and bind the parameter, currently you are vulnerable to SQL Injection attacks.
PreparedStatement ps = null;
ResultSet rs = null;
String result = null;
final String sql = "SELECT apmcid FROM userbusinesstoapmc "
+ "WHERE userbusinessid=?";
try {
ps = conn.prepareStatement(sql);
ps.setString(1, userBusinessKey);
rs = ps.executeQuery();
if (rs.next()) {
result = rs.getString("apmcid");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
you can try like this
ResultSet rsLocationId = null;String result="";
rsLocationId = stmtLocation.executeQuery("SELECT apmcid FROM userbusinesstoapmc WHERE userbusinessid='"+userBusinessKey+"'");
if(rsLocationId.next())
{
result=rsLocationId.getString('apmcid');
}
Even though your particular query only returns a single column, presumably some CHAR type if you expect the result to be a String, the executeQuery method returns a result set object, not a String object. So, you have to process the result set to get your String data. SpringLearner has provided a good example of how to do this.
In the below code I want to call one stored procedures and execute one Query. I am facing error at statement.executeUpdate(); Please help in fixing it. I am not sure where it going wrong.
public void Dbexe() {
Connection connection;
connection = DatabaseConnection.getCon();
CallableStatement stmt;
try {
stmt = connection.prepareCall("{CALL optg.Ld_SOpp}");
stmt.executeUpdate();
stmt.close();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Stored Procedure executed");
//PreparedStatement statement = null;
// ResultSet rs = null;
try{
PreparedStatement statement;
try {
statement = connection.prepareStatement("MERGE INTO OPTG.R_VAL AS TARGET USING" +
........... +
"");
statement.executeUpdate(); //Here the exception is thrown
statement.close();
connection.commit();
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// statement = connection.prepareStatement(query);
//statement.close();
}
finally{
System.out.println("Data is copied to the Table");
}
}
Little off-topic: You should use CallableStatement instead if you want to call a store procedure (see documentation):
CallableStatement callableStatement = connection.prepareCall("{call opptymgmt.Load_SiebelOpportunity}");
ResultSet rs = callableStatement.executeQuery();
I would also suggest you check this topic How to properly clean up JDBC resources in Java?. It was very helpful to me.
Update: based on this stack trace:
com.ibm.db2.jcc.am.mo: DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=MERGE INTO OPPTYMGMT.REVENUE_VALIDAT;BEGIN-OF-STATEMENT;<variable_set>, DRIVER=4.7.85
The problem seems to be in the sql sentence you're trying to execute. I mean, is an error from DB2, not java. You should check your sql statement.
I got it working in this method:
PreparedStatement myStmt = conn.prepareStatement(sqlQuery);
myStmt.setInt(1, id); //position of parameter (1,2,3....) , value
ResultSet rs = myStmt.executeQuery();
while (rs.next()) {
int jobId = rs.getInt("jobId"); ....... }