Creating tables in Oracle database by JDBC - java

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

Related

Batch Insert not Inserting

I have been trying to insert a "batch" of data into a SQLITE db in an Android application. I am getting no errors, but when trying to select from that Table later, no data is returned.
The application uses both SQL server and SQLITE since the device wont always be connected to the network it cannot access SQLServer all the time, so I am running a query to select from SQLServer and then I pass that resultset to the method that is meant to push the data to the SQLITE DB
The process flow I am following is as follows:
Delete everything currently in the sqliteDB
mDb = mDbHelper.getReadableDatabase();
mDb.execSQL("delete from TABLE_1");
Get data from SQLserver
Connection con = connectionClass.CONN();
connect = con;
try {
PreparedStatement statement = connect.prepareStatement("Exec SelectAll '" + Param1+ "'");
rs = statement.executeQuery();
liteAdapter.insertIntoDbLite(rs);
con.close();
} catch (SQLException ex) {
String error = ex.getMessage();
}
Pass resultset from step 2 to the method that should batch insert the data to sqlite
//Insert Records into Bale Table from SQL Server
public void insertIntoDbLite(ResultSet rs)
{
mDb = mDbHelper.getWritableDatabase();
mDb.beginTransaction();
try {
ContentValues values = new ContentValues();
try {
while (rs.next()) {
//put value(Column_Name, record)
values.put("COL1", rs.getString("Col1_Val"));
values.put("COL2", rs.getString("Col2_Val"));
values.put("COL3", rs.getString("Col3_Val"));
values.put("COL4", rs.getString("Col4_Val"));
values.put("COL5", rs.getString("Col5_Val"));
values.put("COL6", rs.getString("Col6_Val"));
values.put("COL7", rs.getString("Col7_Val"));
values.put("COL8", rs.getString("Col8_Val"));
values.put("COl9", rs.getString("Col9_Val"));
}
mDb.insert("TABLE_1", null, values);
}
catch (java.sql.SQLException e)
{
Log.e("Error in SQL",e.toString());
}
mDb.setTransactionSuccessful();
}
catch(Exception ex)
{
Log.e("Error in transaction",ex.toString());
}
finally
{
//End the transaction
mDb.endTransaction();
}
}
so it all seems to run fine, but when I later query the db and to a select, no values are returned from this table,
am I missing something or just doing it wrong?
Thanks
There appears to be nothing glaringly wrong with the given code. The likely scenario is that the update is in not performing the update due to a constraint (a rule such as, but not limited to NOT NULL, UNIQUE). Another, perhaps less likely scenario is that the while loop isn't being entered.
You could distinguish which by changing
mDb.insert("TABLE_1", null, values);
to
Log.d("INSERT","Return from insert is " + Long.toString(mDb.insert("TABLE_1", null, values)));
This will then either write output with :-
(a) no output to the log indicating that the while loop was not entered, so rs is empty.
(b) -1 being the sole value(s) returned, indicating that the update is not being done due to constraints.
(c) with all or some positive (> 0) value(s) returned, this would indicate, that the updates are being performed and that the issue is likely with the method used to checked the data later.
If (b) then changing mDb.insert to mDb.insertOrThrow should result in the first exception being caught which should indicate the issue.

How to inject a SQL command to drop a table in java

My java code for SQL Query is
String sqlSt="INSERT INTO users(id,name,place) values ("+null+",'"+request.getParameter("name")+"','"+request.getParameter("place")+"');";
I have tried out
name= a'); DROP TABLE users; --
as well as
place =a'); DROP TABLE users; --
but it returns an Ecxeption as below
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DROP TABLE users; --','chennai')' at line 1
Note: when i tried the same in mysql command line. It worked!!!! i don't know what happens in jdbc
The real problem is actually JDBC, it only allows one sql if you dont tell it otherwise.
Look at this question for more info:
Multiple queries executed in java in single statement
But also i would try this instead, name =
a',''); DROP TABLE users; --
Since you specificed 3 columns in your insert:
(id,name,place)
You need to provide 3 values for the sql to be valid, not just 2.
Also you can sent the text null, sending a java null value is not necessary and i am not even sure how that works. I think this might be better:
String sqlSt="INSERT INTO users(id,name,place) values (null,'"+request.getParameter("name")+"','"+request.getParameter("place")+"');";
Instead of null, use an empty string ''
String sqlSt = "INSERT INTO users(id, name, place) values ('', '" + request.getParameter("name") + "', '" + request.getParameter("place") + "');";
It's better to use prepared statements to avoid confusion.
String sqlSt = "INSERT INTO users(id, name, place) values ('', ?, ?)";
PreparedStatement ps = null;
try {
ps = connection.prepareStatement(query);
ps.setString(1, request.getParameter("name"));
ps.setString(2, request.getParameter("place"));
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
ps.close();
}
The real problem is with your Query. It is better to use a PreparedStatement for executing a query.
Your Code should be :
String sqlSt="INSERT INTO users(id,name,place) values (?,?,?)";
PreparedStatement pstmt = null;
try{
pstmt = dbConnection.prepareStatement(sqlSt);
pstmt.setString(1,null);
pstmt.setString(2,request.getParameter("name"));
pstmt.setString(3,request.getParameter("place"));
pstmt.executeUpdate();
}catch (Exception e) {
e.printStackTrace();
} finally {
pstmt.close();
}
If you don't want to use a PreparedStatement, just remove last ; from your query.
So your query will be :
String sqlSt="INSERT INTO users(id,name,place) values ("+null+",'"+request.getParameter("name")+"','"+request.getParameter("place")+"')";

MySQL - Object not null?

I am trying to check if a player is already is in the database with this code:
Statement sql = mySql.getConnection().createStatement();
ResultSet check = sql.executeQuery("SELECT * FROM `playerinfo` WHERE Username='" + player.getName() + "';");
System.out.println(check.toString());
if(check != null) {
System.out.println("2");
Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Player already in database");
check.close();
sql.close();
return;
}
I checked but nothing is in the database and it says that the player already contains in the database
Sorry for bad english
Some considerations:
When checking whether the database contains a certain value, it's good practise to do this using a query that returns a single value (and not SELECT * which returns all columns of all rows that match the WHERE condition). You can do this e.g. by selecting a single check flag (SELECT 1) with a row-limiting clause (LIMIT 1):
SELECT 1 FROM playerinfo WHERE Username = ? LIMIT 1
This query is guaranteed to return only one row (with a single column, '1') if a player with the given name exists, or no rows if there are no players with the given name.
As others have pointed out, when you're inputting parameters into the query, you should use a PreparedStatement instead of a simple statement with concatenated inputs. This way, you can avoid SQL injection and the database is also able to reuse/cache the query (or cursor) internally.
Finally, you should close the resources you use, even if an Exception gets thrown during the execution. This is best done in the finally clause, or if you're on Java 7 or later, using the try-with-resources statement.
With these things in mind, a re-write of your code could look like this:
PreparedStatement ps = null;
try {
ps = mySQL.getConnection()
.prepareStatement("SELECT 1 FROM playerinfo WHERE Username = ? LIMIT 1");
ps.setString(1, player.getName());
ResultSet rs = ps.executeQuery();
// the first invocation of rs.next() returns true if
// there are rows in the result set, or false if no rows were found
if (rs.next()) {
System.out.println("2");
Bukkit.getConsoleSender().sendMessage(ChatColor.RED
+ "Player already in database");
}
rs.close();
} finally {
if (ps != null) {
ps.close();
}
}
I think instead of checking if the ResultSet is null or not, you should check if the ResultSet contains any row or not.
Apart from that, use PreparedStatements.

SQLite Database locking up on Delete Command

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

ms access database with java

I am creating a java program, with which I am editing into a Microsoft Access Database. I have a certain case, in which I need to search if a certain record already exists in my table, if it does, I want to update it, and if not, I want to create it from scratch.
I have found this piece of code:
IF EXISTS (SELECT * FROM USERS WHERE USERID=#UID) select 1 else select
This code gives me an error, saying that a SELECT, UPDATE or DELETE statement was expected.
In a code that I have tried my self, I have done the following:
try{
s = con.createStatement();
s.executeQuery("SELECT * FROM table WHERE date='" + today + "'");
rset = s.getResultSet();
if (rset.getString("date") == null){
s = con.createStatement();
s.executeUpdate("INSERT INTO table VALUES ('" + today + "','" + cflow + "','" + vat + "','" + cnn + "')");
}
}
catch (SQLException exp)
{
System.err.println(exp);
}
But with this code, when the record does not exist yet, the user input is not updated inside the database.
Thanks for your time :)
1st: If I can remember right, then is
IF EXISTS (SELECT * FROM USERS WHERE USERID=#UID) select 1 else select
an incomplete transact sql statement -used by the sql engine from a database system.
2nd:
if (rset.getString("date") == null){}
you should avoid this way, because there is a good chance to get a Nullpointer Exception.
In my eyes a better one is a test the size of resultset for zero or the resultset it self for the value of NULL.
In case the UPDATE statement won't also be executed, check your SELECT statement using the database engine -Ms Access, SQL Server, etc.- directly. The advantage is you can exclude a mistake in your SELECT query.
What about this?
SELECT IF EXISTS (SELECT * FROM USERS WHERE USERID=#UID) THEN 1 ELSE 0 END
or
SELECT IF(EXISTS (SELECT * FROM USERS WHERE USERID=#UID), 1, 0)
(I'm not sure about the real syntax here.)
(rset.getString("date") == null)
should be
(!rset.next())
rset is positioned 'before' the first result that gets returned. next() returns true if there was a 'next' result to get.
Also, what datatype is your 'date' variable? There's no guarantee that a date.toString() will format the date correctly for MS-Access version of SQL.
Rather, prepare a statement
PreparedStatement ps = connetion.prepareStatement("SELECT * from table where date=?");
and set the date like
ps.setDate(1, date);
then issue the query using the prepared statement.
That saves any toString() issues. (I haven't compiled this, it almost certainly won't work as-is, but the idea is there).
Here is what i used to find the last ID in a table. IF the table is empty the no ID will be returned. If table is populated then i needed the next ID for new record.
ResultSet mn = stmt.executeQuery("SELECT MAX(ExamID)FROM ExamResults");
if (mn == null){
jTextField1.setText("1");
} else{
while (mn.next()) {
int lastID =Integer.parseInt(""+(mn.getObject(1)));
jTextField1.setText(""+(lastID+1));
}
}
// close the objects
mn.close();
stmt.close();
conn.close();

Categories

Resources