Custom database table design with Java and MS Access - java

While running the following code
public class Temp {
public static void main(String args[]) {
Connection con; // The connection to the database.
// The following code can throw errors, so they must be caught.
try{
// First, tell Java what driver to use and where to find it.
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
// Next, create a connection to your data source.
// Specify that you are using the ODBC-JDBC Bridge.
// And specify the data source from ODBC.
con = DriverManager.getConnection("jdbc:odbc:Temp");
// Create an SQL statement.
Statement stmt = con.createStatement();
// Execute some SQL to create a table in your database.
// If the table already exists, an exception is thrown!
stmt.executeUpdate("CREATE TABLE COFFEES " +
"(COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, " +
"SALES INTEGER, TOTAL INTEGER)");
}
// Catch any exceptions that are thrown.
catch(ClassNotFoundException e){
System.out.println(e.toString());
}
catch(SQLException e){
System.out.println(e.toString());
}
}
}
i got the error as
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] Cannot modify the design of table 'COFFEES'. It is in a read-only database.
please help

Make sure that you have write access to the database/file with your current user.

Check the advanced options in the ODBC DSN and make sure ReadOnly is set to 0.

You need to add "ReadOnly=False;" to your connection string

try deleting the table explicitly and run again.

Related

How to retrieve elements from a database into a JDBC program

I tried a basic program to retrieve data from a database table into a java program. At the end of the compilation, when running the code an exception occurs. No error is shown in the console. It displays the exception message
import java.sql.*;
public class class1 {
public static void main(String args[]){
String url = "jdbc:mysql://localhost:3306//orders";
String username = "root";
String password = "Luxan#22";
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url, username, password);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("SELECT CUST_NAME FROM CUSTOMERS");
System.out.println("List of Registered customers: ");
while(rs.next()){
System.out.println(rs.getString("cust_name"));
}
st.close();
con.close();
}
catch(Exception e){
System.out.println("An Exception error occured while processing JDBC programme");
}
}
}
Below is the output got in my console window
Fri Jan 17 19:34:24 IST 2020 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
An Exception error occured while processing JDBC programme
The problem is with your URL. Replace
"jdbc:mysql://localhost:3306//orders"
with
"jdbc:mysql://localhost:3306/orders"
Note that I have removed one / before orders.
Try to add ?useSSL=false to the end of the connection url.
It is difficult to see what went wrong, without knowing your table structure. But here is another way of writing your program. Maybe it helps you come closer to your goal:
public class Class1 {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver"); // this line is optional since Java 1.6 Normally for MySQL you shouldn't have to do this
// This is called "try-with-resources". It means that inside your "try" declaration you
// tell Java what things you want to open (here you wnat to open a connection)
// and it will automatically close any connection (on failure or success) for you
try (
Connection connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/orders", // before the database name there is only one /
"root", // the database user
"password"); // the password
Statement statement = connection.createStatement() // the same try-with resources can open the statement for your
) {
ResultSet rs = statement.executeQuery("SELECT CUST_NAME FROM CUSTOMERS");
while (rs.next()) {
System.out.println(rs.getString("cust_name"));
}
} catch (SQLException ex) {
Logger.getLogger(Class1.class).log(Level.SEVERE, null, ex); // this will properly log your SQLException. Don't be afraid, SQL error messages are scary and Java Exceptions are impressive. But they will tell you where the problem is
}
} catch (ClassNotFoundException ex) { // if you register your driver you need to catch the exception as well
Logger.getLogger(Class1.class).log(Level.SEVERE, null, ex);
}
}
}
You can read more about this example on MkYong.
I hope it helps you.
One more thing:
Class names start with a capital letter: Class1 instead of class1. Because variable names start with a small letter. Imagine you want to create an instance of a class called car. Then you would say car car = new car(); which is unreadable. Car car = new Car() however is clear :)

Is it possible to create a new PDB from java?

For one of my poc, I would like to create a new PDB from java.
I am able to get cdb connection say,
Connection cdbConnection = DBUtils.getDBConnection(Constants.DB_CDB_NAME, Constants.DB_CDB_USER_NAME, Constants.DB_CDB_PASSWORD);
Now am trying to clone PDB3: CREATE PLUGGABLE DATABASE PDB5 FROM PDB3;
public static void createPluggableDB(Connection cdbConnection) {
try (Statement stmt = cdbConnection.createStatement();) {
stmt.executeUpdate("CREATE PLUGGABLE DATABASE PDB5 FROM PDB3;");
} catch (SQLException exception) {
// exception handling
}
}
When I execute this, am getting,
java.sql.SQLSyntaxErrorException: ORA-00922: missing or invalid option
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:494)
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:446)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1052)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:537)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:255)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:610)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:213)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:37)
at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:887)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1136)
at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1754)
at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1709)
at oracle.jdbc.driver.OracleStatementWrapper.execute(OracleStatementWrapper.java:300)
at com.xit.gtw.db.DBUtils.executeDBScripts(DBUtils.java:43)
at PluggableDBBuilder.createPluggableDB(PluggableDBBuilder.java:51)
at PluggableDBBuilder.main(PluggableDBBuilder.java:35)
Is it possible to create a PDB from java?
Thanks in advance!
You shouldn't have the semicolon in the string you pass to executeUpdate(); it's a statement separator not part of the statement. So remove that:
stmt.executeUpdate("CREATE PLUGGABLE DATABASE PDB5 FROM PDB3");
That applies to any statement you try to execute through JDBC (or, indeed, through many other mechanisms - including execute immediate).

Create database if not exists just once

This is my code, this code should be execute just one time, But when my database already exist, The database created message has been displayed!
I want to see message just when database really created, not every time.
public static boolean createDatabase() throws Exception {
String query = "CREATE DATABASE IF NOT EXISTS LIBRARY3";
Statement st = null;
Connection con = DriverManager.getConnection(dbUrl, "root", "2000");
st = con.createStatement();
if (st.executeUpdate(query) == 1) { // Then database created
JOptionPane.showMessageDialog(null, "Database created");
return true;
}
return false;
}
This code always returns true, Why?
If its MySQL you need to check if database exists to take decision weather the database was really created
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'LIBRARY3'
It returns true because you are asking mysql to create the database only if it exists, so, if it exists there is no error, it just does not create it. What you can do is try to create it and, if it fails, check that the reason is that the database alreyady existed.
try {
statement = connection.createStatement();
String sql = "CREATE DATABASE DBNAME";
//To delete database: sql = "DROP DATABASE DBNAME";
statement.executeUpdate(sql);
System.out.println("Database created!");
} catch (SQLException sqlException) {
if (sqlException.getErrorCode() == 1007) {
// Database already exists error
System.out.println(sqlException.getMessage());
} else {
// Some other problems, e.g. Server down, no permission, etc
sqlException.printStackTrace();
}
} catch (ClassNotFoundException e) {
// No driver class found!
}
The query is successful each time. Do a separate query to check if the table exists and return message based on that result.
Read more about how to check whether a table exists here
Shorter way to do it:
SHOW DATABASES LIKE 'LIBRARY3';
If LIBRARY3 dont exist, you will get an empty string.

H2: Error on all other computers

I'm using the H2 database in my Java project (embedded mode).
On my computer at home everything works, the connection can be established, but on all other computers I always receive the following error:
org.h2.jdbc.JdbcSQLException: Table "CUSTOMERS" not found; SQL
statement: SELECT * FROM CUSTOMERS [42102-162]
I'm sure, that within the DB everything is alright, it should be something with the connection.
But even if I import the h2-1.3.162.jar file, the error still remains.
String dbClass = "org.h2.Driver";
String dbDriver = "jdbc:h2:~/cc";
String user = "user1";
String pass = "test1";
private Connection conn = null;
private Statement stmt = null;
private ResultSet rs = null;
public void connect() {
boolean done = false;
//load driver
try {
Class.forName(dbClass).newInstance();
System.out.println("driver loaded"); // This is shown in the Compiler
} catch (Exception ex) {
System.out.println("error while loading driver");
System.err.println(ex);
}
// Connection
try {
conn = DriverManager.getConnection(dbDriver, user, pass);
System.out.println("connected"); // This is shown in the Compiler
done = true;
} catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
}
public Vector select() {
data = new Vector();
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT * FROM CUSTOMERS");
while (rs.next()) {
Vector row = new Vector();
row.add(rs.getInt("id"));
row.add(rs.getString("fname"));
row.add(rs.getString("lname"));
row.add(rs.getString("street"));
row.add(rs.getString("city"));
row.add(rs.getString("zip"));
row.add(rs.getString("state"));
row.add(rs.getString("phone"));
row.add(rs.getString("birthday"));
row.add(rs.getString("email"));
row.add(rs.getInt("code"));
data.add(row);
}
rs.close();
stmt.close();
} catch (SQLException ex) {
System.out.println("error while selecting"); // I receive this error
System.err.println(ex);
}
return data;
}
The problem isn't with your connection as you'd receive an exception well before then if it was failing to connect to the database. The exception is pretty clear about what the issue is, as well - it can't find the CUSTOMERS table. That could be because the table doesn't exist at all, or the connection is pointing at the wrong database; try putting in the full schema information of the table, rather than just its name, and see if that works.
I'm sure, that within the DB everything is alright, it should be
something with the connection. But even if I import the h2-1.3.162.jar
file, the error still remains.
Check your assumptions. This one is incorrect.
There's nothing in the message to suggest that you couldn't connect. Either you connected to the wrong database OR the one you did connect to didn't CREATE TABLE CUSTOMERS. (Should be named CUSTOMER, not plural.)
You'll fix your error faster if you stop assuming that everything you did is correct. You should be assuming that everything is wrong.
I'd print the stack trace when you catch that exception. It'll give you more information.
Finally I figured it out!
It had nothing to do with my tables, the database couldn't be found. When trying to connect to a database which can't be found with String dbDriver = "jdbc:h2:~/cc";, a new database with the name cc (in my case) will be created (of course an empty one with no tables) and the connection is established. That's why I haven't received any connection errors.
In the next step I tried to retrieve some data from the new created empty database and therefore received the error, that my table doesn't exist.
So I changed this line: String dbDriver = "jdbc:h2:file:lib/cc"; and copied into the lib directory of my application my old database cc.h2.db.
That's all!
PS: Here is a similiar problem: h2 (embedded mode ) database files problem

How to catch constraint violation inside the resultset loop?

I was working on a servlet that will generate a unique code and update that in a mySQL database.
Now, in that, I want to catch any exception thrown in case that unique code already exists in the mySQL table and generate a new code and try updating the database. The problem is I want to do this WITHIN the for loop itself. The code is as follows:
try
{
connection = datasource.getConnection();
SQLUpdate = "INSERT INTO Voucher_dump VALUES( '"+unique_code+"','08-10-2011 04:48:48','0')";
PreparedStatement ps1 = connection.prepareStatement(SQLUpdate);
ps1.executeUpdate();
ResultSet r = ps1.getResultSet(); // this is where I'm checking if it's a duplicate
if(r==null)
out.println("This is a duplicate");
else out.println("Updated");
trial12= "08-10-2011 04:48:480.03999855056924717a";
SQLUpdate = "INSERT INTO Voucher_dump VALUES( '"+trial12+"','08-10-2011 04:48:48','0')";
ps1 = connection.prepareStatement(SQLUpdate);
ps1.executeUpdate();
r = ps1.getResultSet();
if(r==null)
out.println("This is a duplicate");
else out.println("Updated");
}
catch (SQLException sqle)
{
sqle.printStackTrace();
}
I don't want to wait till the end of the entire loop to catch the SQLException (I have already defined this key in mySQL as primary). The moment, the result comes back as a duplicate entry, I want to re-generate this key and attempt the update again.My output for this particular code is coming blank on my output page (all other parameters are showing correctly). Neither is "This is a duplicate" displayed nor is "Updated". Maybe, ResultSet is not the best way to do it. Could you guys give me some advice on what would be the best way forward ?
Some advice in no particular order:
Close the connection in a finally block.
Close statements individually if you'll be creating many of them before closing the connection. ("Many" is defined by your DBAs.)
Format your code.
Don't use stdout and/or stderr from real code. Pick a logging framework.
Consider using some helper classes to simplify (and correct) your database access, like Spring's JdbcTemplate.
Make sure to include relevant context when you post example code.
Due to #6, I don't know what out is, but I suspect the reason you're not seeing anything is that you're inserting a duplicate value with the first statement, which will cause a SQLException from that line, not at getResultSet(), where you seem to expect it. Since the error is written to stdout, it'll show up in your server logs somewhere, but nothing will be written to out. I'm not sure why you think getResultSet() will return null or not null depending on whether there was a constraint violation. Take a look at the javadoc for that method.
Update: 7. As BalusC points out, never, ever concatenate a string directly into a JDBC Statment. Use PreparedStatment's placeholders and set* methods. For info on SQL injection, see Wikipedia and XKCD.
How about this code?
try {
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url + dbName);
System.out.println("Connected to the database");
int i = 1; //get the unique code
boolean isInserted = false;
while (!isInserted) {
try {
PreparedStatement preparedStatement = conn.prepareStatement("INSERT INTO test values (?)");
preparedStatement.setInt(1, i);
preparedStatement.executeUpdate();
isInserted = true;
} catch (com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException e) { //Catch the particular exception which throws error on unique constraint. This may depend on Java/MySQL your version
i++; //get the next unique code
}
}
System.out.println("Disconnected from database");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (Exception e) {
}
}

Categories