I have a problem where I can't seem to get this simple delete command working. Everytime I run it it just locks the database and crashes
The id parameter exists in the database
the database is small. Only a few tables.
update commands work completely fine.
The id is an in and resulting command is - DELETE from Employees where ID = 2;
public static void EmployeeDeleteByID(int idIn){
Connection c = null;
Statement stmt = null;
try {
c = Connect();
c.setAutoCommit(false);
System.out.println("Opened database successfully");
stmt = c.createStatement();
String sql = "DELETE from Employees where ID = " + idIn + ";";
System.out.println(sql);
stmt.executeUpdate(sql);
c.commit();
stmt.close();
c.close();
} catch ( Exception e ) {
System.err.println("Error 1 : " + e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Operation done successfully");
}
Error after running : java.sql.SQLException: database is locked
"database is locked" means that some other connection still has an active transaction.
If there is no other process accessing the database, you have to check all connections in your program; at least one of them forgot a commit().
The code actually works fine.
It turned out another method was being called to fill a JCombo which was keeping a connection open due to an error being caused by calling a null value from database.
It wasnt obvious as there was no code in the exception box.
Silly little problem so people always make an error throw some kind of stack trace or warning.
Thanks
Related
Issue:
In DB, Have around 20000 records and I'm trying to generate the report of all the records via UI ,it fetches the records available in db till 12679th record . When it tries to generate the records for 12680th one, Observing the below mentioned error in the UI page. As a result, observing java null pointer exception issue.
Note: Handled the code to fetch around 30000 records via preparedStatement object(setMaxRows)
Errors Observed:
Unable to Execute Query:Could not open database table(root.tablename).
select * from tablename a where x=12680 order by y;
Exception in thread "main" java.lang.NullPointerException
And it has been observed due to this piece of code
s1 is the select query which we are parsing as an argument to the prepareStatement.
pStmt is nothing but the preparedStatement object.
dbCon is connection object
Looped through the query for each records one by one
private Connection dbCon;
PreparedStatement pStmt = null;
try {
pStmt = dbCon.prepareStatement (s1);
try {
pStmt.setMaxRows(30000);
rs = pStmt.executeQuery ();
} catch (Exception e) {
System.out.println ("\nUnable to Execute Query:" + e.getMessage() +"Stack Trace::"+e.getStackTrace() + " (Query: " + s1 + ")\n");
}
} catch (Exception e) {
System.out.println ("\nUnable to Prepare Query:" + e.getMessage() + " (Query: " + s1 + ")\n");
}
When we execute the select query command for 12680th record via CLI informix db access, the query seems to be working fine and it fetches the record without any issues.
It looks like a java issue because if its a db issue ,it should not allow us to fetch the query results via CLI but it allows us to fetch without any issues via informix db access.
Got struct at this point on how to solve this java exception issue?
Could someone guide me to proceed further on this activity to fix the issue?
Expectation:
Need to capture all the 20000 records
My question is related to this post and a post of mine . I am trying to pass REF_CURSOR as an IN parameter while calling a PL/SQL procedure using JDBC. Here is my code:
public int printMaxSalAllDept()
{
Connection conn = null;
OracleCallableStatement callStmt = null;
int rowCount = -1;
try
{
// Register the Jdbc Driver
// Class.forName(JDBC_DRIVER_ORACLE);
// Create a Database connection
conn = DriverManager.getConnection(DB_URL,DB_USER,DB_PWD);
// Create a query string to get the ResultSet of your choice
String getRsQuery = "SELECT e.department_id , e.last_name , "
+ "e.salary FROM employees e , (SELECT department_id , "
+ "MAX(salary) AS maxSal FROM employees GROUP BY department_id) "
+ "m WHERE e.department_id = m.department_id "
+ "AND e.salary = m.maxSal ORDER BY e.salary";
// Create a Statement
Statement stmt = conn.createStatement();
// Execute the statement
ResultSet rs = stmt.executeQuery(getRsQuery);
// Create a SQL String
String callProc = "{ call HR.EMP_PKG.print_max_sal_all_dept(? , ?) }";
// Create a Callable Statement
callStmt = (OracleCallableStatement) conn.prepareCall(callProc);
// Bind values to the IN parameter
callStmt.setCursor(1, rs);
// callStmt.setNull(1,OracleTypes.CURSOR);
// Register OUT parameters type to the SQL type of the value returned
callStmt.registerOutParameter(2, java.sql.Types.NUMERIC);
// Execute Callable Statements
callStmt.execute();
// Retrieve value from the OUT parameters
rowCount = callStmt.getInt(0);
System.out.println("Number of rows in the cursor :" + rowCount);
}
catch (SQLException se)
{
System.out.println("Exception occured in the database");
System.out.println("Exception message: "+ se.getMessage());
System.out.println("Database error code: "+ se.getErrorCode());
se.printStackTrace();
}
finally
{
// Clean up
if(callStmt != null)
{
try
{
callStmt.close();
}
catch (SQLException se2)
{
se2.printStackTrace();
}
}
if(conn != null)
{
try
{
conn.close();
}
catch (SQLException se2)
{
se2.printStackTrace();
}
}
}
return rowCount;
}
When I run the above code I get the following exception:
Exception occured in the database
java.sql.SQLException: Unsupported feature
at oracle.jdbc.driver.OraclePreparedStatement.setCursorInternal(OraclePreparedStatement.java:5867)
at oracle.jdbc.driver.OracleCallableStatement.setCursor(OracleCallableStatement.java:5297)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.setCursor(OraclePreparedStatementWrapper.java:410)
at com.rolta.HrManager.printMaxSalAllDept(HrManager.java:1038)
at com.rolta.HrManager.main(HrManager.java:1344)
Exception message: Unsupported feature
Database error code: 17023
I have seen couple of posts in this forum and others which suggests updating to the latest version of JDBC driver fixes this issue. In my case I am using the latest version of JDBC driver for Oracle ( ojdbc6.jar the very first jar under Oracle Database 11g Release 2 11.2.0.4 JDBC Drivers) . So i don't think its the version that's causing the issue.
If what I was doing was illegal the exception message thrown would have indicated that. But here with "Unsupported Feature" message it seems like this feature is either unavailable for my database(or its version that I am using (11g) ) or for the version of the JDBC driver that I am using. Is this the right interpretation of this exception ?
I would say that the feature is not supported in any version of the JDBC driver, and will never be supported. The version of the database in this situation is not relevant.
I can't say why there ever was a setCursor() method declared in OraclePreparedStatement. I would guess that it was a mistake in the design of the API. In fact, you get a deprecation warning if you compile any code that attempts to call setCursor():
C:\>javac -Xlint JavaRefCursorTest.java
JavaRefCursorTest.java:28: warning: [deprecation] setCursor(int,ResultSet) in OraclePreparedStatement has been deprecated
((OracleCallableStatement)cstmt2).setCursor(1, rSet);
^
1 warning
This deprecation warning suggests that Oracle are planning to remove this method in the future.
I've also run my JavaRefCursorTest class from my answer to one of your previous questions with the Oracle 12c JDBC driver (ojdbc7.jar). The end result is only slightly different: the type of exception thrown when calling setCursor() is java.sql.SQLFeatureNotSupportedException instead of java.sql.SQLException. So upgrading the JDBC driver JAR won't help.
In your case, I can't see the reason why you would want to get a ref cursor out of the database and into a JDBC ResultSet, only to pass the same ResultSet straight back to the database. You can call the procedure with a ref cursor directly, using a PL/SQL block such as the one below:
String plsql =
"DECLARE" +
" l_curs SYS_REFCURSOR; " +
"BEGIN" +
" OPEN l_curs FOR" +
" SELECT e.department_id , e.last_name ," +
" e.salary FROM employees e , (SELECT department_id ," +
" MAX(salary) AS maxSal FROM employees GROUP BY department_id)" +
" m WHERE e.department_id = m.department_id" +
" AND e.salary = m.maxSal ORDER BY e.salary;" +
"" +
" HR.EMP_PKG.print_max_sal_all_dept(l_curs, ?);" +
"END;"
PreparedStatement stmt = conn.prepareStatement(plsql);
stmt.registerOutParameter(1, java.sql.Types.NUMERIC);
stmt.execute();
So I was purposely trying to break my program, and I've succeeded.
I deleted the sqlite database the program uses, while the program was running, after I already created the connection. Then I attempted to update the database as seen below.
Statement stmt;
try
{
stmt = Foo.con.createStatement();
stmt.executeUpdate("INSERT INTO "+table+" VALUES (\'" + itemToAdd + "\')");
}
catch(SQLException e)
{
System.out.println("Error: " + e.toString());
}
The problem is, it didn't catch the exception, and continued to run as if the database was updated successfully. Meanwhile the database didn't even exist at that point since this was after I deleted it.
Doesn't it check if the database still exists when updating?
Do I have to check the database connection manually, every time I update to ensure that the database wasn't corrupted/deleted?
Is this the way it is normally done, or is there a simpler/more robust approach?
Thank you.
Interestingly, I found that if I delete my database when using it and then attempt to update it, it updates the database in its new location (in the trash!). You cannot permanently delete it while it is in the trash can and you are accessing it via your program.
It looks like this is not a SQLException that is thrown...
Try catching every Exception type and see if you get your error :
Statement stmt;
try
{
stmt = Foo.con.createStatement();
stmt.executeUpdate("INSERT INTO "+table+" VALUES (\'" + itemToAdd + "\')");
}
catch(Exception e)
{
System.out.println("Error: " + e.toString());
}
or
Statement stmt;
try
{
stmt = Foo.con.createStatement();
stmt.executeUpdate("INSERT INTO "+table+" VALUES (\'" + itemToAdd + "\')");
}
catch(Throwable e)
{
System.out.println("Error: " + e.toString());
}
I have problem with creating tables by JDBC controller on Oracle database.
When I create table by "creata table...." is ok. Table create and I see that table by SQL Developer. I have method to check if table with that name exist - and it works good.
So when I create table (I try to do commit, too - do not help), table appear in SQL developer but when i check by my method if that table exist i get 'false' (do not exist), when I restart database and run again, my method return 'true'.
I think is a problem with session but I don't now how to get over with that.
enter code here public void prepStatExecuteCreateTable(String name){
String createTable= "Create table "+ name +" (ID NUMBER(*, 0) NOT NULL PRIMARY KEY, CZAS NUMBER(*, 0) NOT NULL, OTWARCIE NUMBER(6, 2) NOT NULL , MAX_KURS NUMBER(6, 2) NOT NULL , MIN_KURS NUMBER(6, 2) NOT NULL , ZAMKNIECIE NUMBER(6, 2) NOT NULL , VOLUMEN NUMBER(*, 0) NOT NULL , FOREIGN KEY(czas) references CZAS(ID))";
PreparedStatement ps=null;
try{
ps = returnConnection().prepareStatement(createTable);
}catch(SQLException e){
System.out.println("Error with preperadStatement(create table): "+ e.getMessage());
}
try{
ps.execute();
returnConnection().commit();
ps.close();
closeConnection();
}
catch(SQLException e){
System.out.println("Error with execute: "+ e.getMessage());
}
}
public boolean ifExistTable(String tablename) throws SQLException{
String sql = "Select TABLE_NAME from user_tables where table_name='"+tablename.toUpperCase()+"' ";
System.out.println(sql);
ResultSet rs =null;
Statement ps = null;
try{
ps = returnConnection().createStatement();
}catch(SQLException e){
System.out.println("Error with preperadSatement(checking): "+ e.getMessage());
}
try{
rs=ps.executeQuery(sql);
while (rs.next()){
System.out.println (rs.getString(1)); // Print col 1
if(rs.getString(1).equals(tablename)){
return true;
}
}
}
catch(SQLException e){
System.out.println("Error with executing checking " +e.getMessage()+ " " + e.getStackTrace());
}
ps.close();
return false;
}
this is how I use in the Main method: (condDB is a object that has above methods)
enter code here String table_name="BBB";
System.out.println(conDB.ifExistTable(table_name));
conDB.prepStatExecuteCreateTable(table_name);
so if I run first, I get message "false" (table do not exist)
and is created (check by SQL developer, table with name 'BBB' appear)
when I run secondly I get message "false" and error message from second method:
Error with execute: ORA-00955: name is already used by an existing object
1) Your ifExistTable function really ought to be using bind variables rather than building the SQL statement using string concatenation if only to avoid SQL injection attacks.
2) Your ifExistTable function is running a query that uses the upper-case value of the tablename that is passed in. But then when you're fetching the data from rs, you're making a case-sensitive comparison with rs.getString(1).equals(tablename). At a minimum, that ought to be equalsIgnoreCase. But there should be no need to do the comparison at all in Java since your SQL statement is already doing it. If the ResultSet has a row, the table exists (or you can write the query as a COUNT(*) and check to see whether the row that is returned has a value of '1').
Perhaps when you created your stored procedure inside the package, you didn't close it with '/'
...
END;
/
so the connection is stucked and the resource is not liberated to be used by other query (which is actually another logical connection). commit will not work as you are performing a DDL sentence which could care less about commiting hehehe
I'd like to write to my Oracle DB the user ID and IP address of the logged in user (web app) whenever I perform SQL UPDATEs and INSERTs. Such as
public static int updateUser(STKUser user, STKUser loggedIn) throws DAOException {
Connection connection = null;
connection = DB.getConnFromCache();
PreparedStatement ps = null;
String query = "INSERT INTO xtblPersonnel (pID, pPssWrd, pAdminDate, pAdminIP, pAdminBy) VALUES (?,?,SYSDATE,?,?)";
try {
ps = connection.prepareStatement(query);
ps.setString(1, user.getBadge());
ps.setString(2, user.getPassword());
ps.setString(3, loggedIn.getIpAddress());
ps.setString(4, loggedIn.getBadge());
return ps.executeUpdate();
}
catch (Exception e) {
System.out.println("SQL Exception inserting new user with badge: " + user.getBadge() + ". Error Message: " + e.getMessage());
LOGGER.log(Level.INFO, "SQL Exception inserting new user with badge: " + user.getBadge() + ". Error Message: " + e.getMessage(), user);
throw new DAOException("SQL Exception inserting new user!");
// return 0;
}
finally {
DB.closePreparedStatement(ps);
DB.releaseConnToCache(connection);
}
}
STKuser is a Javabean
My application uses a general Oracle db username and password so that is the reason why I want to record who did the update or insert and from which machine.
Is this an acceptable approach. I used to pass in the session but have realized this is a no no.
Assuming that you're properly closing all DB resources as Connection, Statement and ResultSet in the finally block of the try block where you acquired them and the code is doing what it should do, I don't forsee problems with the approach in question. There is no risk for SQL injections since you're using PreparedStatement, if that was your actual concern. Declaring the method static is however a bit a smell, but then we need to know more about the context the code is running in.