I'm checking the size of my database(when I check the used database size I found it's in floating value) : I'm using this piece of code :
Public class DBSize{
private float dbSize;
public float databaseSize(Float dbSize,String dataSize,String indexsize){
String apps="apps"; // It's my DB name
String query_data = "select table_schema,SUM(data_length+index_length)/1024/1024 AS total_mb,SUM(data_length)/1024/1024 AS data_mb,SUM(index_length)/1024/1024 AS index_mb,COUNT(*) AS tables,CURDATE() AS today FROM information_schema.tables where table_schema='"+apps+"' GROUP BY table_schema ORDER BY table_schema;";
try {
connection = getConnection();
stmt = connection.createStatement();
ResultSet rs=stmt.executeQuery(query_data);
if(rs.next()) //as I'm selecting a particular database's information
this.dbSize=rs.getFloat(2);
this.dataSize=rs.getString(3);
this.indexSize=rs.getString(4);
System.out.println("DB Size : "+this.dbSize);
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
finally
{
try {
if(stmt != null)
stmt.close();
if(connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return dbSize;
}
public float getDbSize(){
return dbSize;
}
}
rs is getting null value(don't know whether unable to fetch the value from database or not),even I have used String type the function but also getting the null value,
Any inputs ...that where I'm going wrong :( :(
Keep those three statements of assignment after if inside a block otherwise only first statement will get executed if the condidion rs.next() evaluates to true and next 2 statements will always execute even if the condidion rs.next() evaluates to false which may cause some exception
if(rs.next()){
this.dbSize=rs.getFloat(2);
this.dataSize=rs.getString(3);
this.indexSize=rs.getString(4);
}
Related
I am using Java 1.8 and H2 1.4.199.
I have a method insertRecord(DATA_OBJECT) which inserts single row into table, and then returns the generated ID for this row. It instantiates a Task object and submit it onto SingleThreadExecutorService one-by-one, and the generated ID is retrieved from Future object. Most of the time it works just fine. However, sometimes a situation like this happens:
Row 10 insert is submitted to ExecutorService
Row 11 insert is meant to be waiting in front of "synchronized" block to be submitted to ExecutorService
Row 10 is being inserted by code, and Future returns generated ID = 11
Row 11 is being inserted by code, and Future returns generated ID = 11
I have no working and reproducible example, because it is a very rare situation, but it happens.
No exceptions thrown and I have no idea how this could happen.
Below is the example of code:
private static final ExecutorService singleExecutor = Executors.newSingleThreadExecutor();
private static String insertRecord(DATA_OBJECT dataObject) {
Future<String> future;
synchronized (singleExecutor) {
future = singleExecutor.submit(new Task(dataObject));
}
try {
return future.get();
} catch (InterruptedException ex) {
Logger.getLogger(CLASS_NAME.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(CLASS_NAME.class.getName()).log(Level.SEVERE, null, ex);
}
}
private class Task implements Callable<String> {
private DATA_OBJECT dataObject;
public Task(DATA_OBJECT dataObject) {
this.dataObject = dataObject;
}
#Override
public String call() {
try {
return execute(dataObject);
} catch (SQLException ex) {
Logger.getLogger(CLASS_NAME.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
private static String execute(DATA_OBJECT dataObject) {
Connection conn = Database.getTransactedConnection();
String lastId = null;
boolean success = false;
try (
PreparedStatement statement =
conn.prepareStatement(
"insert into TABLE (COLUMN_NAMES) values (VALUES)",
Statement.RETURN_GENERATED_KEYS
)
) {
statement.setString(1, dataObject.STRING_1);
statement.setString(N, dataObject.STRING_N);
success = statement.executeUpdate() == 1;
if (success) {
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
if (generatedKeys.next()) {
lastID = generatedKeys.getString(1);
}
}
}
} finally {
if (success)
conn.commit();
else
conn.rollback();
Database.releaseConnection(conn);
}
return lastId;
}
I am trying to find a way to avoid 100% of these events because the consequences are devastating. How can I do this?
What could be the problem leading to the return of the identifier from the future?
I need to display the data returned from a SQL SERVER stored procedure in a Jtable, and yet I have not been able to do it because it gives me the following error: the requested operation is not supported on forwarding-only result sets.
this is the code that I implemented:
try
{
CallableStatement mostararPacientesAusentes = conexionBBDD.getConexionBBDD()
.prepareCall("{call mostararPacientesAusentes()}");
ResultSet tabla = mostararPacientesAusentes.executeQuery();
AbstractTableModel mTN=new ModeloTabla(tabla);
ventanaNotificacion.getTabla().setModel(mTN);
ventanaNotificacion.getTabla().validate();
} catch (SQLException e1) {
JOptionPane.showMessageDialog(null, e1.getMessage(), "BBDD", 2, null);
}
and this is the class that inherits AbstractTableModel
public class ModeloTabla extends AbstractTableModel {
private ResultSet tabla;
private ResultSetMetaData datosBBDD;
public ModeloTabla(ResultSet unResulset)
{
tabla=unResulset;
try
{
datosBBDD=tabla.getMetaData();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
try
{
tabla.absolute(rowIndex+1);
return tabla.getObject(columnIndex+1);
}
catch (SQLException e)
{
e.printStackTrace();
return null;
}
}
public String getColumnName(int c)
{
try
{
return datosBBDD.getColumnName(c+1);
}
catch (SQLException e) {
e.printStackTrace();
return null;
}
}
#Override
public int getRowCount() {
try {
tabla.last();
return tabla.getRow();
}
catch (SQLException e) {
e.printStackTrace();
return 0;
}
}
#Override
public int getColumnCount()
{
try
{
return datosBBDD.getColumnCount();
}
catch (SQLException e)
{
e.printStackTrace();
}
return 0;
}
}
The titles of the columns of the table show it in the JTable, but the data does not.
I have already searched unsuccessfully for information to solve the problem.
Thank you very much.
Documentation of ResultSet:
... A default ResultSet object is not updatable and has a cursor that moves forward only. Thus, you can iterate through it only once and only from the first row to the last row. It is possible to produce ResultSet objects that are scrollable and/or updatable. ...
There is a version of prepareCall() that accepts additional arguments to do that, like in:
...prepareCall("{call mostararPacientesAusentes()}",
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
Please check the documentation for other constants/types.
I am not sure if using a ResultSet to maintain the data is such a good idea - it is probably holding a lot of resources (connection, statement, ...) - IMHO better read the data once and save it in a list or similar structure; releasing the database resources ASAP.
I made the DAO to create a sales offer and it is similar to an other DAO where it makes users and that connects and works. But the one below keeps skipping the if statements and I'm not sure why it isn't adding to the data base. I ran the same command in the SQL string in oracle and it worked there.
public boolean sendOffer(Sales sell) {
boolean done = false;
int key =0;
Connection conn = cu.getConnection();
try {
String sql = "INSERT INTO sales (offer_amount, offer_who, car_id) values(?,?,?)";
String[]keys= {"ID"};
PreparedStatement ps = conn.prepareStatement(sql,keys);
ps.setInt(1, sell.getOfferAmount());
ps.setInt(2, sell.getOwnerID()); //foriegn key
ps.setInt(3, sell.getCarID()); // forgien key
int number = ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if(number!=1)
{
log.warn("data insert fail");
}
else
{
log.trace("success");
done=true;
}
if(rs.next()) {
key=rs.getInt(1);
sell.setID(key);
conn.commit();
}
else {
log.warn("data not found");
}
}catch(SQLException e)
{
}
finally {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
// TODO Auto-generated method stub
return done;
}'''
The main issue is that an exception is happening in your code but the try/catch block is intercepting it and swallowing it silently. While it may be tempting to catch and swallow exceptions, truth is it always causes more problems than it solves and the key concept of handling exceptions is to NOT handle them: just put the throws declaration and let the application crash.
You then have other possible side-issues depending on how the Connection was obtained in the first place, like the fact that you're never closing the PreparedStatement and the ResultSet (if the connection is closed, they are closed as well... but if the connection is returned to a pool then they are never going to be closed).
In general the above code tends to pack too much functionality in a single method and can quickly spiral out of control, so you might want to divide it in smaller chunks with clear individual responsibilities.
All of the above is common to observe wherever Connection and PreparedStatement are used directly, be it for maximum performance reasons or for lack of experience. Typically in web applications using the Spring framework this is solved through the use of a JdbcTemplate but I cannot assume that you are using Spring so I won't show its usage here.
At a minimum, I would modify your code roughly as follows:
public boolean sendOffer(Sales sell) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = cu.getConnection();
ps = prepareInsertOfferStatement(sell, conn);
ps.executeUpdate();
rs = ps.getGeneratedKeys();
sell.setID(extractKey(rs));
conn.commit();
log.trace("success");
return true;
}
catch(Exception ex) {
log.error(ex); // this is actually probably bad. Consider putting a throws declaration and get rid of this catch
return false;
}
finally {
closeQuietly(rs, ps, conn);
}
}
private void closeQuietly(AutoCloseable... objs) {
for(AutoCloseable obj : objs) {
try {
obj.close();
} catch (SQLException e) {
// this is usually mostly safe to ignore. Maybe log a warning somewhere
}
}
}
private PreparedStatement prepareInsertOfferStatement(Sales sell, Connection conn) throws SQLException {
String sql = "INSERT INTO sales (offer_amount, offer_who, car_id) values(?,?,?)";
String[] keys= {"ID"};
PreparedStatement ps = conn.prepareStatement(sql,keys);
ps.setInt(1, sell.getOfferAmount());
ps.setInt(2, sell.getOwnerID()); //foreign key
ps.setInt(3, sell.getCarID()); // foreign key
return ps;
}
private int extractKey(ResultSet rs) throws SQLException {
if(rs.next()) {
return rs.getInt(1);
}
else {
throw new Exception("The statement did not return any generated key.");
}
}
As you can see it's not shorter, but responsibilities are clearer and all objects are closed accordingly. Furthermore, it gives you nice reusable primitives to close connections and related objects and to extract the key from other inserts you will want to do. Further abstractions would allow you to obtain more primitives, but I think this is sufficient for you to get the gist of it.
I'm trying to drop some objects in Oracle database using jdbc. I want to skip if specific ORA-04043 error occurs. The followings are the code I built.
This array string variable is SqlList.uninstall_OS_COMMAND_SQL.
public static String[] uninstall_OS_COMMAND_SQL = {
"DROP PACKAGE OS_COMMAND",
"DROP PACKAGE LOB_WRITER_PLSQL",
"DROP TYPE OSCOMMAND_VC2_ARRAY",
"DROP TYPE OSCOMMAND_DIR_ARRAY",
"DROP TYPE OSCOMMAND_DIR_ENTRY",
"DROP TYPE FILE_LIST_TYPE",
"DROP TYPE FILE_TYPE",
"DROP PACKAGE FILE_PKG",
"DROP JAVA SOURCE \"OS_HELPER\"",
"DROP JAVA SOURCE \"FILE_TYPE_JAVA\"",
"DROP PACKAGE FILE_SECURITY"
};
and this is the code.
private void uninstallOS_COMMAND_Step1_For_11g() {
Connection targetDBconn = null;
Statement stmt = null;
try {
targetDBconn = globalTargetConn.connect();
logWriter.writeLogs(logTextArea, LogWriter.INFO, "Uninstalling OS_COMMAND package...");
for (int i = 0; i < SqlList.uninstall_OS_COMMAND_SQL.length; i++) {
stmt = targetDBconn.createStatement();
stmt.setEscapeProcessing(false);
logWriter.writeLogs(logTextArea, LogWriter.INFO, "See the query below...");
logWriter.writeLogs(logTextArea, LogWriter.INFO, "\n"+SqlList.uninstall_OS_COMMAND_SQL[i]);
stmt.executeUpdate(SqlList.uninstall_OS_COMMAND_SQL[i]);
}
} catch (SQLException ex) { logWriter.writeLogs(logTextArea, LogWriter.ERROR, ex.getMessage());
} finally {
if (stmt != null ) try {stmt.close();} catch(SQLException ex) {}
if (targetDBconn != null ) try {targetDBconn.close();} catch(SQLException ex) {}
}
}
If I run this code, it executes just one item in the array and stops the entire method. Please help me..
Create one new method and call the new method inloop
Like
execute(Statement stmt, SQL Command ) throws Exception {
try {
stmt.executeUpdate(SqlList.uninstall_OS_COMMAND_SQL[i]);
} catch(SQLException s) {
//LOG error
if (s.getMessage().contains("ORA-04043")) {
} else {
throw s;
}
} catch (Exception ee) {
throw ee;
}
}
you might consider to put your try and catch inside the loop.
I have the following Code that throws a null pointer exeption
public void checkAcc(String sql)
{
System.out.print(sql); // the statement executed is "SELECT AccountID FROM BankAccount"
try {
stmt.executeQuery(sql);
} catch (Exception e) {
System.err.println("Nope that is broken - " + e);
}
}
Have you checked to ensure that stmt isn't null? The way that function is written, it must be a field, and you have to make certain that it has been initialized before checkAcc() is called.