How to call Stored Procedure and prepared statement - java

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"); ....... }

Related

Java - execute stored procedure

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.

Syntax for SQL statement using mysql database

public void insertTags(Elements[] elements) {
Connection con = (Connection) DbConnection.getConnection();
try {
String sql = "insert into htmltags(source) values(?),(?),(?)";
PreparedStatement ps = (PreparedStatement) con.prepareStatement(sql);
ps.setString(1, elements[0].toString());
ps.setString(2, elements[1].toString());
ps.setString(3, elements[2].toString());
int rs = ps.executeUpdate(sql);
System.out.println("Data inserted" + rs);
} catch (SQLException e) {
e.printStackTrace();
}
}
is this a valid syntax for Prepared statement.
This is your problem:
int rs = ps.executeUpdate(sql);
From the JavaDoc we see that PreparedStatement#executeUpdate() does not take any parameters. The reason is that we already passed the query earlier when preparing the statement. Your code should be this:
int rs = ps.executeUpdate(); // no parameter
Also no need to cast the result of prepareStatement to PrepareStatement
To insert multiple values, I don't thing using values(?),(?),(?) is the right syntax, instead use a loop, or for better way you can use batch :
String sql = "insert into htmltags(source) values(?)";
try (PreparedStatement ps = con.prepareStatement(sql);) {
for (Elements element : elements) {
ps.setString(1, element.toString());
ps.addBatch();//Add a new batch for each Element
}
int[] result = ps.executeBatch();//Submits a batch of commands to the database
} catch (SQLException e) {
e.printStackTrace();
}

Connection to SqlServer not closing in for loop java

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");
}

Insert data into mysql using java

This code hasn't error or exception, but after running the table features in the data base remain empty
try {
Class.forName("com.mysql.jdbc.Driver");
con= (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/sounds","root","");
statment = (Statement) con.createStatement();
String query = "INSERT INTO featuers (avg_Bandwidth) values (?)";
PreparedStatement preparedStmt = (PreparedStatement)con.prepareStatement(query);
preparedStmt.setDouble(1, avarage_Bandwidth);
preparedStmt.executeUpdate();
con.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Two things of note :
statment = (Statement) con.createStatement(); This variable is not used if I see it correctly. But this should not be the problem in itself
preparedStmt.executeUpdate(); This executeUpdate method should return a int based on the query itself. So it should return 1 in your case for the no of rows affected. So try to check what is returned.
This may not be the exact solutions but do try these and you may get some idea on what is happening
Hi try to use this one.
int status = 0; // to get the status to know if statement is executed properly or not
try {
Connection con = DBConnection.getConnect();//Your database Connection
Statement st = con.createStatement();
status = st.executeUpdate(query); //After executing this it will return an int value
} catch (Exception ex) {
ex.printStackTrace();
}
I hope this will help you.

Reading ResultSet: java.sql.SQLException: Operation not allowed after ResultSet closed

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.

Categories

Resources