I've encountered an some inconsistencies regarding the results from an SQL query.
Here is the query which I'm using as a prepared statement.
delete ROLE_USER_MAP
from ROLE_USER_MAP inner join ROLE_MANAGER on ROLE_USER_MAP.R_ID=ROLE_MANAGER.R_ID
where ROLE_USER_MAP.U_ID= ? and ROLE_MANAGER.M_ID= ?
Here is how I calling the prepared statement in my Java application.
public void deleteRoles(String mID, String uID) throws OperationFailedException
{
Connection conn = null;
try
{
conn = this.getConnection();
this.deleteRoles(mID, uID, conn);
}
catch (Exception e)
{
AdminLogger.error(this.getClass(), e);
throw new OperationFailedException("Failed to remove roles for user.");
}
finally
{
try
{
conn.close();
}
catch (Exception e)
{
}
}
}
private void deleteRoles(String mID, String uID, Connection conn) throws SQLException
{
PreparedStatement stmt = null;
try
{
stmt = *retrieving ps*
stmt.setString(1, uID);
stmt.setString(2, mID);
int i = stmt.executeUpdate(); // returns 1 here
if (i < 1)
{
throw new SQLException("Failed to remove roles for user.");
}
} finally
{
stmt.close();
}
}
It runs fine locally and in SSMS with all rows fitting the where clause being deleted but when I try to deploy it to my hosted server, only the first row in the table is being deleted.
Can anyone help me with this?
Thanks in advance.
Related
I am getting this error when I run my code
Below is the code I have used:
String sql="SELECT * FROM PERSONS WHERE PERSONJOB='ADMIN'";
Statement stmt=null;
ResultSet rs=null;
try
{
stmt=conn.createStatement();
rs=stmt.executeQuery(sql);
While(rs.next())
{
String name=rs.getString(1);
long id=rs.getLong(2);
System.out.println(name);
System.out.println(id);
}
}
catch(Exception e)
{
throw e;
}
finally
{
rs.close();
stmt.close();
}
I want to reuse the connection, so I didn't close the connection.
After I closed the ResultSet and Statement, I am getting the "maximum open cursors exceeded" error.
Anyone please help me to solve this error.
My guess is that the close() of your ResultSet is failing, which would result in multiple open cursors and eventually hit the max configured open cursor count. Could you modify your code to:
Statement stmt = conn.createStatement();
try
{
ResultSet rs = stmt.executeQuery("SELECT * FROM PERSONS WHERE PERSONJOB = 'ADMIN'");
try
{
while ( rs.next() )
{
String name = rs.getString(1);
long id = rs.getLong(2);
System.out.println(name);
System.out.println(id);
}
}
finally
{
try
{
rs.close();
}
catch (Exception ignore) { }
}
}
finally
{
try
{
stmt.close();
}
catch (Exception ignore) { }
}
EDIT: will be good to also clean up the already opened cursors with a combination of:
SELECT oc.user_name, oc.sql_text, s.SID, s.SERIAL#
FROM v$open_cursor oc
, v$session s
WHERE oc.sid = s.sid
EXEC SYS.KILL_SESSION(xxx,xxxxx);
or restart the DB.
I'm trying to display a list of the names of people in the database from the terminal, but not sure about how I would go about this. Right now I'm using a prepared statement
public static void showNames() throws SQLException {
Statement stmt=null;
Connection conn=null;
try {
conn = DriverManager.getConnection(DB_URL, USER, PASS);
stmt = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
String selectTable="SELECT * FROM userInfo;";
stmt.execute(selectTable);
}
You're close.
Below code is not a complete answer, but hopefully enough to get you moving in the direction of obtaining a complete answer. The below code is basically the code you posted with some modifications.
public static void showNames() throws SQLException {
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
String selectTable="SELECT * FROM userInfo;";
try {
conn = DriverManager.getConnection(DB_URL, USER, PASS);
stmt = conn.createStatement();
rs = stmt.executeQuery(selectTable);
while (rs.next()) {
Object obj = rs.getObject("name of column in database table USERINFO");
System.out.println(obj);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.close();
}
}
}
You didn't post the structure of database table USERINFO, so replace name of column in database table with the actual column name.
By the way, there are many examples of how to do this on the Internet, for example Processing SQL Statements with JDBC.
I want to insert values for multiple columns of a table. I am doing an Eclipse Project and I want to feed the data from my project into the database. There are multiple columns in the database and I have values for each of these columns from my Eclipse Project. The JDBC driver and the connections are all done. I just need to figure out how to input these values from the project into the table.
public void insert(Double num1, Double num2, Double result) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection con = null;
PreparedStatement stmt = null;
try {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/Calculator", "root", "");
stmt = con.prepareStatement("INSERT INTO RESULT(ID,VALUE1,VALUE2,RESULT) VALUES (?,?,?,?))");
stmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException ex) {
}
}
if (con != null) {
try {
con.close();
} catch (SQLException ex) {
}
}
}
}
You're close to an answer, your are missing the setXXX calls to assign values to the ? in your insert statement, you didn't provide a value for ID in your function parameter and you have an extra parenthesis in the prepareStatement.
stmt = con.prepareStatement("INSERT INTO RESULT(ID,VALUE1,VALUE2,RESULT) VALUES (?,?,?,?)");
// stmt.set___(1,___);
stmt.setDouble(2,num1);
stmt.setDouble(3,num2);
stmt.setDouble(4,result);
When i run my website it on glassfish server everything works fine but after some time its stop responding and I need to restart glassfish.. I think its cause I not closing the connection. Can someone tell me if this is the problem? if yes how to close it? Here is one of my function.
public Album get_album (String title)
{
try{
//creates a connection to the server
Connection cn = getCon().getConnection();
//prepare my sql string
String sql = "SELECT * FROM albums WHERE Title = ?";
//create prepared statement
PreparedStatement pst = cn.prepareStatement(sql);
//set sql parameters
pst.setString(1, title);
//call the statement and retrieve results
ResultSet rs = pst.executeQuery();
if(rs.next()) {
Album a = new Album();
a.setIdAlbum(rs.getInt("idAlbum"));
a.setTitle(rs.getString("Title"));
a.setYear(rs.getInt("Year"));
a.setIdArtist(rs.getInt("idArtist"));
a.setIdUser(rs.getInt("idUser"));
a.setLike(rs.getInt("Like"));
a.setDislike(rs.getInt("Dislike"));
a.setNeutral(rs.getInt("Neutral"));
a.setViews(rs.getInt("Views"));
return a;
}
}
catch (Exception e) {
String msg = e.getMessage();
}
return null;
}
Assumming the unique error in your application is for not closing the resources after using them, your code should change to:
public Album get_album (String title) {
Connection cn = null;
PreparedStatement pst = null;
ResultSet rs = null;
Album a = null;
try{
//creates a connection to the server
cn = getCon().getConnection();
//prepare my sql string
String sql = "SELECT * FROM albums WHERE Title = ?";
//create prepared statement
pst = cn.prepareStatement(sql);
//set sql parameters
pst.setString(1, title);
//call the statement and retrieve results
rs = pst.executeQuery();
if (rs.next()) {
a = new Album();
a.setIdAlbum(rs.getInt("idAlbum"));
a.setTitle(rs.getString("Title"));
a.setYear(rs.getInt("Year"));
a.setIdArtist(rs.getInt("idArtist"));
a.setIdUser(rs.getInt("idUser"));
a.setLike(rs.getInt("Like"));
a.setDislike(rs.getInt("Dislike"));
a.setNeutral(rs.getInt("Neutral"));
a.setViews(rs.getInt("Views"));
//don't return inside try/catch
//return a;
}
} catch (Exception e) {
String msg = e.getMessage();
//handle your exceptions
//e.g. show them in a logger at least
e.printStacktrace(); //this is not the best way
//this will do it if you have configured a logger for your app
//logger.error("Error when retrieving album.", e);
} finally {
closeResultSet(rs);
closeStatement(pst);
closeConnection(cn);
}
return a;
}
public void closeConnection(Connection con) {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
//handle the exception...
}
}
}
public void closeStatement(Statement st) {
if (st!= null) {
try {
st.close();
} catch (SQLException e) {
//handle the exception...
}
}
}
public void closeResultSet(ResultSet rs) {
if (rs!= null) {
try {
rs.close();
} catch (SQLException e) {
//handle the exception...
}
}
}
There are many steps involved in executing one SQL statement in Java:
Create connection
Create statement
Execute statement, create resultset
Close resultset
Close statement
Close connection
At each of these steps SQLException can be thrown. If we to handle all exception and release all the resources correctly, the code will will look like this with 4 levels of TRY stacked on the top of each other.
try {
Connection connection = dataSource.getConnection();
try {
PreparedStatement statement = connection.prepareStatement("SELECT 1 FROM myTable");
try {
ResultSet result = statement.executeQuery();
try {
if (result.next()) {
Integer theOne = result.getInt(1);
}
}
finally {
result.close();
}
}
finally {
statement.close();
}
}
finally {
connection.close();
}
}
catch (SQLException e) {
// Handle exception
}
Can you propose a better (shorter) way to execute a statement while still release all the consumed resources?
If you are using Java 7, the try with resources statement will shorten this quite a bit, and make it more maintainable:
try (Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement(queryString); ResultSet rs = ps.execute()) {
} catch (SQLException e) {
//Log the error somehow
}
Note that closing the connection closes all associated Statements and ResultSets.
Check out Apache Commons DbUtils, and in particular the closeQuietly() method. It will handle the connection/statement/result set closing correctly, including the cases where one or more are null.
An alternative is Spring JdbcTemplate, which abstracts a lot of work away from you, and you handle your database queries in a much more functional fashion. You simply provide a class as a callback to be called on for every row of a ResultSet. It'll handle iteration, exception handling and the correct closing of resources.
I create a utility class with static methods I can call:
package persistence;
// add imports.
public final class DatabaseUtils {
// similar for the others Connection and Statement
public static void close(ResultSet rs) {
try {
if (rs != null) {
rs.close();
}
} catch (Exception e) {
LOGGER.error("Failed to close ResultSet", e);
}
}
}
So your code would be:
Integer theOne = null;
Connection connection = null;
PreparedStatement statment = null;
ResultSet result = null;
try {
connection = dataSource.getConnection();
statement = connection.prepareStatement("SELECT 1 FROM myTable");
result = statement.executeQuery();
while (result.next()) {
theOne = result.getInt(1);
}
} catch (SQLException e) {
// do something
} finally {
DatabaseUtils.close(result);
DatabaseUtils.close(statement);
DatabaseUtils.close(connection);
}
return theOne;
I'd recommend instantiating the Connection outside this method and passing it in. You can handle transactions better that way.
Connection connection = null;
PreparedStatement statement = null;
ResultSet result = null;
try {
connection = dataSource.getConnection();
statement = connection.prepareStatement("SELECT 1 FROM myTable");
result = statement.executeQuery();
if (result.next()) {
Integer theOne = result.getInt(1);
}
}
catch (SQLException e) { /* log error */ }
finally {
if (result != null) try { result.close(); } catch (Exception e) {/*log error or ignore*/}
if (statement != null) try { statement.close(); } catch (Exception e) {/*log error or ignore*/}
if (connection != null) try { connection.close(); } catch (Exception e) {/*log error or ignore*/}
}
Just close the Connection, this releases all resources*. You don't need to close Statement and ResultSet.
*just make sure you don't have any active transactions.
Your code can be shortened and written in this way...
Connection connection = dataSource.getConnection();
PreparedStatement statement = null;
ResultSet result = null;
try {
statement= connection.prepareStatement("SELECT 1 FROM myTable");
result = statement.executeQuery();
if (result.next()) {
Integer theOne = result.getInt(1);
}
} catch (SQLException e) {
// Handle exception
} finally {
if(result != null) result.close();
if(statement != null) statement.close();
if(connection != null) connection.close();
}